Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit b9b306a

Browse files
committed
CleartextLogging: sanitize strings.Split(authheader, ":")[0] and similar
These can represent a username, method name or other non-sensitive component of an Authorization header. For greater precision we could split the query into one investigating Authorization headers and one investigating other sources of sensitive data that can't be sanitized by splitting this way.
1 parent cf29f9d commit b9b306a

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

ql/src/semmle/go/security/CleartextLoggingCustomizations.qll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,22 @@ module CleartextLogging {
183183

184184
override string describe() { result = "HTTP request headers" }
185185
}
186+
187+
/**
188+
* The first element of a split by ' ' or ':', often sanitizing a username/password pair
189+
* or the "Method value" syntax used in the HTTP Authorization header.
190+
*/
191+
private class NonSensitiveAuthorizationElement extends Barrier, DataFlow::ElementReadNode {
192+
NonSensitiveAuthorizationElement() {
193+
exists(DataFlow::CallNode splitCall, DataFlow::Node splitAlias |
194+
splitCall
195+
.getTarget()
196+
.hasQualifiedName("strings", ["Split", "SplitN", "SplitAfter", "SplitAfterN"]) and
197+
splitCall.getArgument(1).getStringValue() = [" ", ":"] and
198+
DataFlow::localFlow(splitCall.getResult(), splitAlias) and
199+
this.getBase() = splitAlias
200+
) and
201+
this.getIndex().getIntValue() = 0
202+
}
203+
}
186204
}

ql/test/query-tests/Security/CWE-312/CleartextLoggingGood.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"log"
55
"net/http"
6+
"strings"
67
)
78

89
func serve1() {
@@ -18,3 +19,19 @@ func serve1() {
1819
})
1920
http.ListenAndServe(":80", nil)
2021
}
22+
23+
func serveauth() {
24+
http.HandleFunc("/register", func(w http.ResponseWriter, r *http.Request) {
25+
authhdr := r.Header.Get("authorization")
26+
fields := strings.Split(authhdr, " ")
27+
28+
log.Printf("Auth method is %s.\n", fields[0])
29+
30+
tokenparts := strings.Split(fields[1], ":")
31+
log.Printf("Username is %s.\n", tokenparts[0])
32+
33+
// ...
34+
use(tokenparts[1])
35+
})
36+
http.ListenAndServe(":80", nil)
37+
}

0 commit comments

Comments
 (0)