fix(settings): tolerate whitespace in header template delimiters (#148)

validateTemplateSecure matched safe functions with literal strings.Contains
("{{get "), so a space after {{ ("{{ get") failed the whitelist and
Config.Validate() rejected the config, surfacing as Traefik's opaque
"invalid handler type: <nil>". Go's text/template treats {{ get and {{get
identically, so the validator was stricter than the engine.

Normalize inner-delimiter whitespace before matching. This also closes a
security gap where a leading space let dangerous patterns ("{{ range",
"{{ call") evade detection.

Adds unit + regression coverage.
This commit is contained in:
2026-06-26 11:49:31 +01:00
parent 546ceb949c
commit 48a19e04f8
3 changed files with 114 additions and 0 deletions
+42
View File
@@ -750,6 +750,48 @@ func TestValidateTemplateSecure_CoverageBoost(t *testing.T) {
template: "{{.Unknown}}",
shouldError: true,
},
// Issue #148: whitespace after {{ and before }} must be tolerated
{
name: "get with leading space (issue #148)",
template: "{{ get .Claims \"email\" }}",
shouldError: false,
},
{
name: "get with multiple leading spaces",
template: "{{ get .Claims \"email\"}}",
shouldError: false,
},
{
name: "default with spaces",
template: "{{ default \"unknown\" .Claims.email }}",
shouldError: false,
},
{
name: "claims with spaces",
template: "{{ .Claims.email }}",
shouldError: false,
},
{
name: "access token with spaces",
template: "{{ .AccessToken }}",
shouldError: false,
},
// Issue #148: space must NOT let dangerous patterns bypass detection
{
name: "range with leading space stays blocked",
template: "{{ range .Items }}{{.}}{{end}}",
shouldError: true,
},
{
name: "call with leading space stays blocked",
template: "{{ call .Func }}",
shouldError: true,
},
{
name: "disallowed claim with spaces stays blocked",
template: "{{ .Claims.password }}",
shouldError: true,
},
}
for _, tt := range tests {