diff --git a/ql/src/semmle/go/security/CleartextLoggingCustomizations.qll b/ql/src/semmle/go/security/CleartextLoggingCustomizations.qll index 31a2a99b36e..d5137dd4116 100644 --- a/ql/src/semmle/go/security/CleartextLoggingCustomizations.qll +++ b/ql/src/semmle/go/security/CleartextLoggingCustomizations.qll @@ -84,6 +84,27 @@ module CleartextLogging { ObfuscatorCall() { this.getCalleeName().regexpMatch(notSensitive()) } } + /** + * Read of a non-sensitive header, considered as a barrier for clear-text logging. + */ + private class NonSensitiveHeaderGet extends Barrier { + NonSensitiveHeaderGet() { + exists(string headerName | + exists(DataFlow::MethodCallNode c | c = this | + c.getTarget().hasQualifiedName("net/http", "Header", "Get") and + headerName = c.getArgument(0).getStringValue() + ) + or + exists(DataFlow::ElementReadNode e | e = this | + e.getBase().getType().hasQualifiedName("net/http", "Header") and + headerName = e.getIndex().getStringValue() + ) + | + not headerName.toLowerCase() in ["authorization", "cookie"] + ) + } + } + /** * A data-flow node that does not contain a clear-text password. */ diff --git a/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 4d797f8be5d..8196110a435 100644 --- a/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -1,5 +1,6 @@ edges | klog.go:20:30:20:37 | selection of Header : Header | klog.go:22:15:22:20 | header | +| klog.go:28:13:28:20 | selection of Header : Header | klog.go:28:13:28:41 | call to Get | | passwords.go:8:12:8:12 | definition of x : string | passwords.go:9:14:9:14 | x | | passwords.go:30:8:30:15 | password : string | passwords.go:8:12:8:12 | definition of x : string | | passwords.go:34:28:34:35 | password : string | passwords.go:34:14:34:35 | ...+... | @@ -25,6 +26,8 @@ edges nodes | klog.go:20:30:20:37 | selection of Header : Header | semmle.label | selection of Header : Header | | klog.go:22:15:22:20 | header | semmle.label | header | +| klog.go:28:13:28:20 | selection of Header : Header | semmle.label | selection of Header : Header | +| klog.go:28:13:28:41 | call to Get | semmle.label | call to Get | | main.go:15:14:15:21 | password | semmle.label | password | | main.go:17:12:17:19 | password | semmle.label | password | | passwords.go:8:12:8:12 | definition of x : string | semmle.label | definition of x : string | @@ -69,6 +72,7 @@ nodes | util.go:16:9:16:18 | selection of password : string | semmle.label | selection of password : string | #select | klog.go:22:15:22:20 | header | klog.go:20:30:20:37 | selection of Header : Header | klog.go:22:15:22:20 | header | Sensitive data returned by $@ is logged here. | klog.go:20:30:20:37 | selection of Header | HTTP request headers | +| klog.go:28:13:28:41 | call to Get | klog.go:28:13:28:20 | selection of Header : Header | klog.go:28:13:28:41 | call to Get | Sensitive data returned by $@ is logged here. | klog.go:28:13:28:20 | selection of Header | HTTP request headers | | main.go:15:14:15:21 | password | main.go:15:14:15:21 | password | main.go:15:14:15:21 | password | Sensitive data returned by $@ is logged here. | main.go:15:14:15:21 | password | an access to password | | main.go:17:12:17:19 | password | main.go:17:12:17:19 | password | main.go:17:12:17:19 | password | Sensitive data returned by $@ is logged here. | main.go:17:12:17:19 | password | an access to password | | passwords.go:9:14:9:14 | x | passwords.go:30:8:30:15 | password : string | passwords.go:9:14:9:14 | x | Sensitive data returned by $@ is logged here. | passwords.go:30:8:30:15 | password | an access to password | diff --git a/ql/test/query-tests/Security/CWE-312/klog.go b/ql/test/query-tests/Security/CWE-312/klog.go index ee0cf9df549..43203ecdd76 100644 --- a/ql/test/query-tests/Security/CWE-312/klog.go +++ b/ql/test/query-tests/Security/CWE-312/klog.go @@ -23,6 +23,9 @@ func klogTest() { klog.Info(mask(name, header)) // OK } } + klog.Info(r.Header.Get("Accept")) // OK + klog.Info(r.Header["Content-Type"]) // OK + klog.Info(r.Header.Get("Authorization")) // NOT OK }) http.ListenAndServe(":80", nil) }