safe yaml templating as a new feature
irsl opened this issue · comments
Many applications use text/template
(or even html/template
!) with the intention to replace simple strings in a template that will be used later on as YAML. This approach is vulnerable to YAML injection attacks, if the replacement string is controlled by an attacker. We have seen many real-world, exploitable vulnerabilities with this root cause.
I propose safe templating feature to be added into this library with an interface compatible with text/template
(so fixing vulnerable integrations would be super-easy).
I've got a prototype ready, it looks like this:
func TestSimple(t *testing.T) {
yamlTemplate := `
name: "{{ .Name }}"
type: "{{ .PDType }}"
`
tmpl, err := template.New("test").Parse(yamlTemplate)
if err != nil {
t.Fatalf("tmpl.Parse() error = %v", err)
}
type PersistentDiskType string
type StorageClassSpec struct {
Name string
PDType PersistentDiskType
}
var buf bytes.Buffer
err = tmpl.Execute(&buf, StorageClassSpec{Name: "ssd", PDType: "pd-ssd"})
if err != nil {
t.Errorf("tmpl.Execute() error = %v", err)
}
expected := "name: ssd\ntype: pd-ssd\n"
if buf.String() != expected {
t.Errorf("tmpl.Execute() = %v, want: %v", buf.String(), expected)
}
buf.Reset()
err = tmpl.Execute(&buf, StorageClassSpec{Name: "ssd\ninjection", PDType: "pd-ssd\ninjection"})
if err != nil {
t.Errorf("tmpl.Execute() error = %v", err)
}
expected = "name: |-\n ssd\n injection\ntype: |-\n pd-ssd\n injection\n"
if buf.String() != expected {
t.Errorf("tmpl.Execute() = %v, want: %v", buf.String(), expected)
}
}
Why do I propose this feature to be part of this library (instead of publishing it as an independent one)?
- For better adoption
- To support templates that are not valid yaml (missing quotation marks), e.g. this one:
type: {{ print .ObjectMeta "" }}
For sake of a PoC, I've modified the parser (decode.go
) to accept this syntax when it is configured in templating mode.
I'm happy to send a PR if you are open for this contribution.