-
Notifications
You must be signed in to change notification settings - Fork 616
Document YAML injection risks in chart templates #2158
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
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -100,6 +100,53 @@ All inline styles must be on one line. | |
| characters. The only escape sequence is `''`, which is decoded as a single | ||
| `'`. | ||
|
|
||
| ### Strings in Templates | ||
|
|
||
| When string values are inserted from `.Values`, they are parsed as part of the | ||
| final YAML document. If a value can come from a user or another system, | ||
| rendering it as a bare word can allow YAML syntax in the value to change the | ||
| generated structure. | ||
|
|
||
| ```yaml | ||
| data: | ||
| drink: {{ .Values.favorite.drink }} | ||
| ``` | ||
|
|
||
| For example, a string that contains a newline followed by another key could add | ||
| unexpected data to the rendered manifest. Quote string values so YAML treats the | ||
| rendered value as a scalar: | ||
|
|
||
| ```yaml | ||
| data: | ||
| drink: {{ .Values.favorite.drink | quote }} | ||
| ``` | ||
|
|
||
| The same rule applies after constructing a string from multiple values. For | ||
| example, apply `quote` to the final string produced by `printf` or `print`. | ||
|
|
||
| This guidance is for string values. Other scalar types, such as integers and | ||
| booleans, may need to remain unquoted when the Kubernetes field expects that | ||
| type. Define the expected type in the chart values and render it accordingly. | ||
|
|
||
| When a value is intentionally structured data, serialize the complete value and | ||
| indent it for its location in the manifest: | ||
|
|
||
| ```yaml | ||
| metadata: | ||
| annotations: | ||
| {{- .Values.podAnnotations | toYaml | nindent 4 }} | ||
| ``` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're still in a section about strings here. Might be preferable to move this part to somewhere else in this page. |
||
|
|
||
| Using `toYaml` with the correct indentation preserves the intended YAML | ||
| structure, but it does not make arbitrary content safe or validate that the | ||
| result is appropriate for a particular Kubernetes field. For values that may | ||
| come from untrusted sources, chart authors should constrain the accepted values. | ||
| Helm can validate chart values with a | ||
| [`values.schema.json`](/topics/charts.mdx#schema-files) schema, and templates can | ||
| fail rendering with functions such as | ||
| [`required`](/chart_template_guide/function_list.mdx#required) or | ||
| [`fail`](/chart_template_guide/function_list.mdx#fail) for simple checks. | ||
|
Comment on lines
+126
to
+138
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, we're still in a section about strings. The notes on validation don't seem to fit well here. Maybe they should get their own section? |
||
|
|
||
| In addition to the one-line strings, you can declare multi-line strings: | ||
|
|
||
| ```yaml | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trouble is that chart authors generally cannot know what type a value is. So omitting the
quoteis dangerous.Further above, this page already mentions how to "force a particular type inference using YAML node tags". I think this should be the preferred approach for other scalar types. E.g.:
Here, we first generate YAML strings securely. Then we convert them to the expected YAML scalar type. If the string values do not match the specified YAML type, the YAML parser will fail with an error.
Of course, validation could alternatively be done through
values.schema.json. But we only mention that further below.Personally, I'm a big fan of encapsulation. The component (in this case the template) that generates structured data (in this case YAML), should generate secure output under all circumstances. It should not rely on validation happening elsewhere. Otherwise there's a risk that future changes in one place (the JSON schema) might break stuff in some other place (the template).