Convert cleartext logging tests to inline expectations

This commit is contained in:
Owen Mansel-Chan
2025-03-18 14:35:40 +00:00
parent 59d82b3b62
commit 94c812cbe6
7 changed files with 84 additions and 81 deletions

View File

@@ -1,6 +1,6 @@
#select
| klog.go:22:15:22:20 | header | klog.go:20:30:20:37 | selection of Header | klog.go:22:15:22:20 | header | $@ flows to a logging call. | klog.go:20:30:20:37 | selection of Header | Sensitive data returned by HTTP request headers |
| klog.go:28:13:28:41 | call to Get | klog.go:28:13:28:20 | selection of Header | klog.go:28:13:28:41 | call to Get | $@ flows to a logging call. | klog.go:28:13:28:20 | selection of Header | Sensitive data returned by HTTP request headers |
| klog.go:23:15:23:20 | header | klog.go:21:30:21:37 | selection of Header | klog.go:23:15:23:20 | header | $@ flows to a logging call. | klog.go:21:30:21:37 | selection of Header | Sensitive data returned by HTTP request headers |
| klog.go:29:13:29:41 | call to Get | klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | $@ flows to a logging call. | klog.go:29:13:29:20 | selection of Header | Sensitive data returned by HTTP request headers |
| main.go:15:12:15:19 | password | main.go:15:12:15:19 | password | main.go:15:12:15:19 | password | $@ flows to a logging call. | main.go:15:12:15:19 | password | Sensitive data returned by an access to password |
| main.go:16:17:16:24 | password | main.go:16:17:16:24 | password | main.go:16:17:16:24 | password | $@ flows to a logging call. | main.go:16:17:16:24 | password | Sensitive data returned by an access to password |
| main.go:17:13:17:20 | password | main.go:17:13:17:20 | password | main.go:17:13:17:20 | password | $@ flows to a logging call. | main.go:17:13:17:20 | password | Sensitive data returned by an access to password |
@@ -55,11 +55,11 @@
| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword | passwords.go:127:14:127:21 | selection of y | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword |
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:12:22:12:29 | password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:12:22:12:29 | password | Sensitive data returned by an access to password |
edges
| klog.go:20:3:25:3 | range statement[1] | klog.go:21:27:21:33 | headers | provenance | |
| klog.go:20:30:20:37 | selection of Header | klog.go:20:3:25:3 | range statement[1] | provenance | Src:MaD:1 Config |
| klog.go:21:4:24:4 | range statement[1] | klog.go:22:15:22:20 | header | provenance | |
| klog.go:21:27:21:33 | headers | klog.go:21:4:24:4 | range statement[1] | provenance | Config |
| klog.go:28:13:28:20 | selection of Header | klog.go:28:13:28:41 | call to Get | provenance | Src:MaD:1 Config |
| klog.go:21:3:26:3 | range statement[1] | klog.go:22:27:22:33 | headers | provenance | |
| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | range statement[1] | provenance | Src:MaD:1 Config |
| klog.go:22:4:25:4 | range statement[1] | klog.go:23:15:23:20 | header | provenance | |
| klog.go:22:27:22:33 | headers | klog.go:22:4:25:4 | range statement[1] | provenance | Config |
| klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | provenance | Src:MaD:1 Config |
| overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | provenance | |
| passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | provenance | |
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | |
@@ -101,13 +101,13 @@ edges
models
| 1 | Source: net/http; Request; true; Header; ; ; ; remote; manual |
nodes
| klog.go:20:3:25:3 | range statement[1] | semmle.label | range statement[1] |
| klog.go:20:30:20:37 | selection of Header | semmle.label | selection of Header |
| klog.go:21:4:24:4 | range statement[1] | semmle.label | range statement[1] |
| klog.go:21:27:21:33 | headers | semmle.label | headers |
| klog.go:22:15:22:20 | header | semmle.label | header |
| klog.go:28:13:28:20 | selection of Header | semmle.label | selection of Header |
| klog.go:28:13:28:41 | call to Get | semmle.label | call to Get |
| klog.go:21:3:26:3 | range statement[1] | semmle.label | range statement[1] |
| klog.go:21:30:21:37 | selection of Header | semmle.label | selection of Header |
| klog.go:22:4:25:4 | range statement[1] | semmle.label | range statement[1] |
| klog.go:22:27:22:33 | headers | semmle.label | headers |
| klog.go:23:15:23:20 | header | semmle.label | header |
| klog.go:29:13:29:20 | selection of Header | semmle.label | selection of Header |
| klog.go:29:13:29:41 | call to Get | semmle.label | call to Get |
| main.go:15:12:15:19 | password | semmle.label | password |
| main.go:16:17:16:24 | password | semmle.label | password |
| main.go:17:13:17:20 | password | semmle.label | password |

View File

@@ -1,2 +1,4 @@
query: Security/CWE-312/CleartextLogging.ql
postprocess: utils/test/PrettyPrintModels.ql
postprocess:
- utils/test/PrettyPrintModels.ql
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -3,9 +3,10 @@ package main
//go:generate depstubber -vendor k8s.io/klog "" Info
import (
"k8s.io/klog"
"net/http"
"strings"
"k8s.io/klog"
)
func mask(key, value string) string {
@@ -17,15 +18,15 @@ func mask(key, value string) string {
func klogTest() {
http.HandleFunc("/klog", func(w http.ResponseWriter, r *http.Request) {
for name, headers := range r.Header {
for name, headers := range r.Header { // $ Source
for _, header := range headers {
klog.Info(header) // NOT OK
klog.Info(header) // $ Alert
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
klog.Info(r.Header.Get("Authorization")) // $ Alert
})
http.ListenAndServe(":80", nil)
}

View File

@@ -12,43 +12,43 @@ import (
func main() {
password := "P4ssw0rd"
log.Print(password)
log.Printf("", password)
log.Printf(password, "")
log.Println(password)
log.Fatal(password)
log.Fatalf("", password)
log.Fatalf(password, "")
log.Fatalln(password)
log.Panic(password)
log.Panicf("", password)
log.Panicf(password, "")
log.Panicln(password)
log.Output(0, password)
log.Print(password) // $ Alert
log.Printf("", password) // $ Alert
log.Printf(password, "") // $ Alert
log.Println(password) // $ Alert
log.Fatal(password) // $ Alert
log.Fatalf("", password) // $ Alert
log.Fatalf(password, "") // $ Alert
log.Fatalln(password) // $ Alert
log.Panic(password) // $ Alert
log.Panicf("", password) // $ Alert
log.Panicf(password, "") // $ Alert
log.Panicln(password) // $ Alert
log.Output(0, password) // $ Alert
l := log.Default()
l.Print(password)
l.Printf("", password)
l.Printf(password, "")
l.Println(password)
l.Fatal(password)
l.Fatalf("", password)
l.Fatalf(password, "")
l.Fatalln(password)
l.Panic(password)
l.Panicf("", password)
l.Panicf(password, "")
l.Panicln(password)
l.Output(0, password)
l.Print(password) // $ Alert
l.Printf("", password) // $ Alert
l.Printf(password, "") // $ Alert
l.Println(password) // $ Alert
l.Fatal(password) // $ Alert
l.Fatalf("", password) // $ Alert
l.Fatalf(password, "") // $ Alert
l.Fatalln(password) // $ Alert
l.Panic(password) // $ Alert
l.Panicf("", password) // $ Alert
l.Panicf(password, "") // $ Alert
l.Panicln(password) // $ Alert
l.Output(0, password) // $ Alert
glog.Info(password)
logrus.Warning(password)
glog.Info(password) // $ Alert
logrus.Warning(password) // $ Alert
fields := make(logrus.Fields)
fields["pass"] = password
entry := logrus.WithFields(fields)
entry.Errorf("")
entry = logrus.WithField("pass", password)
entry = logrus.WithField("pass", password) // $ Alert
entry.Panic("")
}

View File

@@ -6,10 +6,10 @@ type s struct{}
func (_ s) String() string {
password := "horsebatterystaplecorrect"
return password
return password // $ Source
}
func overrideTest(x s, y fmt.Stringer) {
fmt.Println(x.String()) // NOT OK
fmt.Println(x.String()) // $ Alert
fmt.Println(y.String()) // OK
}

View File

@@ -6,7 +6,7 @@ import (
)
func myLog(x string) {
log.Println(x) // NOT OK
log.Println(x) // $ Alert
}
func redact(kind, value string) string {
@@ -22,33 +22,33 @@ func test() {
x := "horsebatterystapleincorrect"
var o passStruct
log.Println(password) // NOT OK
log.Println(o.password) // NOT OK
log.Println(getPassword()) // NOT OK
log.Println(o.getPassword()) // NOT OK
log.Println(password) // $ Alert
log.Println(o.password) // $ Alert
log.Println(getPassword()) // $ Alert
log.Println(o.getPassword()) // $ Alert
myLog(password)
myLog(password) // $ Source
log.Panic(password) // NOT OK
log.Panic(password) // $ Alert
log.Println(name + ", " + password) // NOT OK
log.Println(name + ", " + password) // $ Alert
obj1 := passStruct{
password: x,
password: x, // $ Source
}
log.Println(obj1) // NOT OK
log.Println(obj1) // $ Alert
obj2 := xStruct{
x: password,
x: password, // $ Source
}
log.Println(obj2) // NOT OK
log.Println(obj2) // $ Alert
var obj3 xStruct
log.Println(obj3) // caught because of the below line
obj3.x = password // NOT OK
log.Println(obj3) // $ SPURIOUS: Alert // caught because of the below line and def-use flow
obj3.x = password // $ Source
fixed_password := "cowbatterystaplecorrect"
log.Println(fixed_password) // Probably OK, but caught
log.Println(fixed_password) // $ Alert // Probably OK
log.Println(IncorrectPasswordError) // OK
@@ -83,12 +83,12 @@ func test() {
log.Println(password_sha) // OK
utilityObject := passSetStruct{
passwordSet: make(map[string]bool),
passwordSet: make(map[string]bool), // $ Source
}
log.Println(utilityObject) // NOT OK
log.Println(utilityObject) // $ Alert
secret := password
log.Printf("pw: %s", secret) // NOT OK
secret := password // $ Source
log.Printf("pw: %s", secret) // $ Alert
log.Println("Password is: " + redact("password", password))
@@ -98,33 +98,33 @@ func test() {
if t.test(y) {
f()
// ...
log.Println("Password is: " + password) // NOT OK
log.Println("Password is: " + password) // $ Alert
// ...
}
if t.test(y) {
if f() {
log.Println("Password is: " + password) // NOT OK
log.Println("Password is: " + password) // $ Alert
}
}
if os.Getenv("APP_ENV") != "production" {
log.Println("Password is: " + password) // OK, but still flagged
log.Println("Password is: " + password) // $ SPURIOUS: Alert
}
var password1 stringable = stringable{"arstneio"}
log.Println(name + ", " + password1.String()) // NOT OK
log.Println(name + ", " + password1.String()) // $ Alert
config := Config{
password: x,
password: x, // $ Source
hostname: "tarski",
x: password,
y: getPassword(),
x: password, // $ Source
y: getPassword(), // $ Source
}
log.Println(config.hostname) // OK
log.Println(config) // NOT OK
log.Println(config.x) // NOT OK
log.Println(config.y) // NOT OK
log.Println(config) // $ Alert
log.Println(config.x) // $ Alert
log.Println(config.y) // $ Alert
obj4 := xStruct{
x: "aaaaa",

View File

@@ -9,8 +9,8 @@ func testProtobuf() {
password := "P@ssw0rd"
query := &query.Query{}
query.Description = password
query.Description = password // $ Source
log.Println(query.GetDescription()) // NOT OK
log.Println(query.GetDescription()) // $ Alert
log.Println(query.GetId()) // OK
}