diff --git a/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql b/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql index e2c7e032e14..df575dfa398 100755 --- a/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql +++ b/ql/src/experimental/CWE-79/HTMLTemplateEscapingPassthrough.ql @@ -142,6 +142,10 @@ class FlowConfFromUntrustedToTemplateExecutionCall extends TaintTracking::Config override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource } override predicate isSink(DataFlow::Node sink) { isSinkToTemplateExec(sink, _) } + + override predicate isSanitizer(DataFlow::Node sanitizer) { + sanitizer instanceof SharedXss::Sanitizer + } } /** diff --git a/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected b/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected index f81c79f791b..bc920fc54b6 100644 --- a/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected +++ b/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected @@ -92,6 +92,14 @@ edges | HTMLTemplateEscapingPassthrough.go:74:17:74:31 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:75:38:75:44 | escaped | | HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:81:16:81:33 | type conversion | | HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:83:38:83:40 | src | +| HTMLTemplateEscapingPassthrough.go:88:10:88:24 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | nodes | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion : HTML | semmle.label | type conversion : HTML | @@ -270,6 +278,22 @@ nodes | HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent : string | semmle.label | call to UserAgent : string | | HTMLTemplateEscapingPassthrough.go:81:16:81:33 | type conversion | semmle.label | type conversion | | HTMLTemplateEscapingPassthrough.go:83:38:83:40 | src | semmle.label | src | +| HTMLTemplateEscapingPassthrough.go:88:10:88:24 | call to UserAgent : string | semmle.label | call to UserAgent : string | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | +| HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion : HTML | semmle.label | type conversion : HTML | +| HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | +| HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | +| HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | +| HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | +| HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | +| HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | +| HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | #select | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:29:39:29:39 | a | Data from an $@ will not be auto-escaped because it was $@ to template.HTML | HTMLTemplateEscapingPassthrough.go:28:26:28:40 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | converted | | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent : string | HTMLTemplateEscapingPassthrough.go:35:40:35:40 | a | Data from an $@ will not be auto-escaped because it was $@ to template.HTML | HTMLTemplateEscapingPassthrough.go:34:23:34:37 | call to UserAgent | untrusted source | HTMLTemplateEscapingPassthrough.go:34:9:34:38 | type conversion | converted | diff --git a/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.go b/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.go index e0468e4bfb2..f001bc93138 100644 --- a/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.go +++ b/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.go @@ -82,4 +82,12 @@ func good(req *http.Request) { _ = converted checkError(tmpl.Execute(os.Stdout, src)) } + { + // The untrusted input is sanitized before use. + tmpl, _ := template.New("test").Parse(`
Your user agent is {{.}}
`) + src := req.UserAgent() + + converted := template.HTML("" + template.HTMLEscapeString(src) + "") + checkError(tmpl.Execute(os.Stdout, converted)) + } }