Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toJSON and toJSONPretty messes up secret from Vault #1430

Closed
nagypeterjob opened this issue Dec 10, 2020 · 6 comments
Closed

toJSON and toJSONPretty messes up secret from Vault #1430

nagypeterjob opened this issue Dec 10, 2020 · 6 comments
Labels
enhancement hashicat-update-complete Completed porting changes to hashicat hashicat-update-required Changes that need to be ported to hashicat
Milestone

Comments

@nagypeterjob
Copy link
Contributor

nagypeterjob commented Dec 10, 2020

Consul Template version

v0.25.1

Configuration

{{` { `}}
   {{ if (eq .Values.vault.secretPath "") }}{{` {{- with secret "secrets/` }}{{ .Values.namespace }}/{{ .Values.serviceName }}{{`" -}}`}}{{ else }}{{` {{- with secret "`}}{{ .Values.vault.secretPath }}{{`" -}}`}}{{ end }}
        {{` "service": {{ .Data.data | toJSONPretty }} `}}
   {{` {{ end }} `}}
   {{` , `}}
    {{` {{- with secret "secrets/`}}{{ .Values.namespace }}{{`/common" }} `}}
        {{` "common": {{ .Data.data | toJSONPretty }} `}}
     {{` {{ end }} `}}
     {{` } `}}
{{- end }}

Sample data

# Include sample data you reference in the template from Consul or Vault here.
{
  "mongo_uri": mongodb://username:password@shard0.maln2.mongodb.net:27017,shard1.maln2.mongodb.net:27017,shard3.maln2.mongodb.net:27017/collection?ssl=true&authSource=user&readPreference=secondaryPreferred&replicaSet=replicaset"
}

Expected behavior

The expected behavior is that the rendered secret (including toJSONPretty call) contains the value for key mongo_url in the exact same format as provided via Vault.

What should have happened?

The mongo connection string should not be HTML escaped.

Actual behavior

Actually the rendered secret messes up the value for mongo_url. Right now, the value for mongo_url key will look like this:

"mongo_uri": mongodb://username:password@shard0.maln2.mongodb.net:27017,shard1.maln2.mongodb.net:27017,shard3.maln2.mongodb.net:27017/collection?ssl=true\u0026authSource=user\u0026readPreference=secondaryPreferred\u0026replicaSet=replicaset"

What actually happened?

toJSON and toJSONPretty generates json by calling the Golang standard library function json.Marshal. It is well known that json.Marshal HTML escapes the produced json string. Though It is still valid json, I wonder if in the context of Vault it is considered to be a "valid" and "desirable" side effect.

As a resolution we could:

  1. use a custom json encoder
  2. use SetEscapeHTML as in link
  3. provide a function parameter through which on can turn on/off HTML escape side effect

Do you think it is a valid problem?

@eikenb
Copy link
Contributor

eikenb commented Dec 11, 2020

Thanks for filing the issue @nagypeterjob.

To quickly restart the issue to be sure... the problem is the toJSON (and Pretty) use json.Marshal and it HTML escapes strings which breaks the URL.

I can see this as an issue, but I'm not sure if just changing toJSON and toJSONPretty would work as it seems like this could break things. Maybe an option can be worked in somehow. I'm going to label this an enhancement for now assuming we'll need to add some way to enable this (vs. changing existing behavior). Feel free to chime in if you have a differing opinion or some ideas on the implementation.

Thanks.

@nagypeterjob
Copy link
Contributor Author

Thanks for acknowledging that this is indeed an issue @eikenb!

I am more than happy to make a PR after we make a decision of the right solution.

  1. As you have said, changing existing behaviour feels weird and might break things.
  2. I would probably create new functions, something like toUnescapedJSON or toUnsafeJSON. It would look like this:
func toUnescapedJSON(t interface{}) (string, error) {
    buf := &bytes.Buffer{}
    encoder := json.NewEncoder(buf)
    encoder.SetEscapeHTML(false)
    err := encoder.Encode(t) // Encode leaves a \n character at the end of the sequence, we might want to trim the result.
    if err != nil {
       return "", errors.Wrap(err, "toUnescapedJSON")
    }
    return buffer.String(), err
}

We could also create a toUnescapedJSONPretty function by extending the code above with encoder.SetIndent.

encoder.SetIndent("", "    ")

What do you think?

@eikenb
Copy link
Contributor

eikenb commented Dec 12, 2020

That sounds reasonable. Please include tests. Thanks.

@nagypeterjob
Copy link
Contributor Author

I have finished the PR as we agreed to @eikenb. Feel free to take a look at it if you have the time. Thanks in advance 🤞

@eikenb
Copy link
Contributor

eikenb commented Jan 5, 2021

Hey @nagypeterjob, I took some time off for the holidays but will take a look at this as soon as I get a chance. Thanks!

@eikenb eikenb added the hashicat-update-required Changes that need to be ported to hashicat label Nov 10, 2021
@eikenb
Copy link
Contributor

eikenb commented Nov 10, 2021

Missed that this didn't get auto-closed with the merge. Closing now.

@eikenb eikenb closed this as completed Nov 10, 2021
@eikenb eikenb added this to the 0.26.0 milestone Nov 10, 2021
@eikenb eikenb added the hashicat-update-complete Completed porting changes to hashicat label Nov 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement hashicat-update-complete Completed porting changes to hashicat hashicat-update-required Changes that need to be ported to hashicat
Projects
None yet
Development

No branches or pull requests

2 participants