Skip to content

Commit 52d3e3d

Browse files
authored
Merge pull request github#15268 from atorralba/atorralba/go/cleartext-logging-src-and-sink-improvs
Go: Adds sources and sinks to `go/clear-text-logging`
2 parents 3534bfc + 5e8c63c commit 52d3e3d

File tree

6 files changed

+107
-21
lines changed

6 files changed

+107
-21
lines changed

go/ql/lib/semmle/go/frameworks/stdlib/Log.qll

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,21 @@ import go
77
/** Provides models of commonly used functions in the `log` package. */
88
module Log {
99
private class LogFunction extends Function {
10+
int firstPrintedArg;
11+
1012
LogFunction() {
11-
exists(string fn | fn.matches(["Fatal%", "Panic%", "Print%"]) |
13+
exists(string fn |
14+
fn.matches(["Fatal%", "Panic%", "Print%"]) and firstPrintedArg = 0
15+
or
16+
fn = "Output" and firstPrintedArg = 1
17+
|
1218
this.hasQualifiedName("log", fn)
1319
or
1420
this.(Method).hasQualifiedName("log", "Logger", fn)
1521
)
1622
}
23+
24+
int getFirstPrintedArg() { result = firstPrintedArg }
1725
}
1826

1927
private class LogFormatter extends StringOps::Formatting::Range instanceof LogFunction {
@@ -23,9 +31,13 @@ module Log {
2331
}
2432

2533
private class LogCall extends LoggerCall::Range, DataFlow::CallNode {
26-
LogCall() { this = any(LogFunction f).getACall() }
34+
LogFunction target;
2735

28-
override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() }
36+
LogCall() { this = target.getACall() }
37+
38+
override DataFlow::Node getAMessageComponent() {
39+
result = this.getSyntacticArgument(any(int i | i >= target.getFirstPrintedArg()))
40+
}
2941
}
3042

3143
/** A fatal log function, which calls `os.Exit`. */

go/ql/lib/semmle/go/security/CleartextLogging.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ module CleartextLogging {
7474
)
7575
}
7676

77+
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
78+
7779
predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) {
7880
// A taint propagating data-flow edge through structs: a tainted write taints the entire struct.
7981
exists(Write write |

go/ql/lib/semmle/go/security/SensitiveActions.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ module HeuristicNames {
3535
*/
3636
string maybePassword() {
3737
result = "(?is).*pass(wd|word|code|phrase)(?!.*question).*" or
38-
result = "(?is).*(auth(entication|ori[sz]ation)?|api)key.*"
38+
result = "(?is).*(auth(entication|ori[sz]ation)?|api|secret)key.*"
3939
}
4040

4141
/**
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added more sources and sinks to the query `go/clear-text-logging`.

go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ edges
66
| klog.go:21:11:21:16 | definition of header | klog.go:22:15:22:20 | header |
77
| klog.go:21:27:21:33 | headers | klog.go:21:4:24:4 | range statement[1] |
88
| klog.go:28:13:28:20 | selection of Header | klog.go:28:13:28:41 | call to Get |
9-
| main.go:20:2:20:7 | definition of fields | main.go:22:29:22:34 | fields |
10-
| main.go:21:19:21:26 | password | main.go:20:2:20:7 | definition of fields |
119
| overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String |
1210
| passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x |
1311
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x |
@@ -53,7 +51,6 @@ edges
5351
| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] |
5452
| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description |
5553
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] |
56-
| util.go:16:9:16:18 | selection of password | passwords.go:28:14:28:28 | call to getPassword |
5754
nodes
5855
| klog.go:20:3:25:3 | range statement[1] | semmle.label | range statement[1] |
5956
| klog.go:20:13:20:19 | definition of headers | semmle.label | definition of headers |
@@ -64,13 +61,35 @@ nodes
6461
| klog.go:22:15:22:20 | header | semmle.label | header |
6562
| klog.go:28:13:28:20 | selection of Header | semmle.label | selection of Header |
6663
| klog.go:28:13:28:41 | call to Get | semmle.label | call to Get |
67-
| main.go:15:14:15:21 | password | semmle.label | password |
68-
| main.go:17:12:17:19 | password | semmle.label | password |
69-
| main.go:18:17:18:24 | password | semmle.label | password |
70-
| main.go:20:2:20:7 | definition of fields | semmle.label | definition of fields |
71-
| main.go:21:19:21:26 | password | semmle.label | password |
72-
| main.go:22:29:22:34 | fields | semmle.label | fields |
73-
| main.go:25:35:25:42 | password | semmle.label | password |
64+
| main.go:15:12:15:19 | password | semmle.label | password |
65+
| main.go:16:17:16:24 | password | semmle.label | password |
66+
| main.go:17:13:17:20 | password | semmle.label | password |
67+
| main.go:18:14:18:21 | password | semmle.label | password |
68+
| main.go:19:12:19:19 | password | semmle.label | password |
69+
| main.go:20:17:20:24 | password | semmle.label | password |
70+
| main.go:21:13:21:20 | password | semmle.label | password |
71+
| main.go:22:14:22:21 | password | semmle.label | password |
72+
| main.go:23:12:23:19 | password | semmle.label | password |
73+
| main.go:24:17:24:24 | password | semmle.label | password |
74+
| main.go:25:13:25:20 | password | semmle.label | password |
75+
| main.go:26:14:26:21 | password | semmle.label | password |
76+
| main.go:27:16:27:23 | password | semmle.label | password |
77+
| main.go:30:10:30:17 | password | semmle.label | password |
78+
| main.go:31:15:31:22 | password | semmle.label | password |
79+
| main.go:32:11:32:18 | password | semmle.label | password |
80+
| main.go:33:12:33:19 | password | semmle.label | password |
81+
| main.go:34:10:34:17 | password | semmle.label | password |
82+
| main.go:35:15:35:22 | password | semmle.label | password |
83+
| main.go:36:11:36:18 | password | semmle.label | password |
84+
| main.go:37:12:37:19 | password | semmle.label | password |
85+
| main.go:38:10:38:17 | password | semmle.label | password |
86+
| main.go:39:15:39:22 | password | semmle.label | password |
87+
| main.go:40:11:40:18 | password | semmle.label | password |
88+
| main.go:41:12:41:19 | password | semmle.label | password |
89+
| main.go:42:14:42:21 | password | semmle.label | password |
90+
| main.go:44:12:44:19 | password | semmle.label | password |
91+
| main.go:45:17:45:24 | password | semmle.label | password |
92+
| main.go:52:35:52:42 | password | semmle.label | password |
7493
| overrides.go:9:9:9:16 | password | semmle.label | password |
7594
| overrides.go:13:14:13:23 | call to String | semmle.label | call to String |
7695
| passwords.go:8:12:8:12 | definition of x | semmle.label | definition of x |
@@ -135,24 +154,46 @@ nodes
135154
| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | semmle.label | implicit dereference [Description] |
136155
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | semmle.label | x [pointer, Description] |
137156
| protos/query/query.pb.go:119:10:119:22 | selection of Description | semmle.label | selection of Description |
138-
| util.go:16:9:16:18 | selection of password | semmle.label | selection of password |
139157
subpaths
140158
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | protobuf.go:14:14:14:35 | call to GetDescription |
141159
#select
142160
| 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 |
143161
| 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 |
144-
| main.go:15:14:15:21 | password | main.go:15:14:15:21 | password | main.go:15:14:15:21 | password | $@ flows to a logging call. | main.go:15:14:15:21 | password | Sensitive data returned by an access to password |
145-
| main.go:17:12:17:19 | password | main.go:17:12:17:19 | password | main.go:17:12:17:19 | password | $@ flows to a logging call. | main.go:17:12:17:19 | password | Sensitive data returned by an access to password |
146-
| main.go:18:17:18:24 | password | main.go:18:17:18:24 | password | main.go:18:17:18:24 | password | $@ flows to a logging call. | main.go:18:17:18:24 | password | Sensitive data returned by an access to password |
147-
| main.go:22:29:22:34 | fields | main.go:21:19:21:26 | password | main.go:22:29:22:34 | fields | $@ flows to a logging call. | main.go:21:19:21:26 | password | Sensitive data returned by an access to password |
148-
| main.go:25:35:25:42 | password | main.go:25:35:25:42 | password | main.go:25:35:25:42 | password | $@ flows to a logging call. | main.go:25:35:25:42 | password | Sensitive data returned by an access to password |
162+
| 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 |
163+
| 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 |
164+
| 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 |
165+
| main.go:18:14:18:21 | password | main.go:18:14:18:21 | password | main.go:18:14:18:21 | password | $@ flows to a logging call. | main.go:18:14:18:21 | password | Sensitive data returned by an access to password |
166+
| main.go:19:12:19:19 | password | main.go:19:12:19:19 | password | main.go:19:12:19:19 | password | $@ flows to a logging call. | main.go:19:12:19:19 | password | Sensitive data returned by an access to password |
167+
| main.go:20:17:20:24 | password | main.go:20:17:20:24 | password | main.go:20:17:20:24 | password | $@ flows to a logging call. | main.go:20:17:20:24 | password | Sensitive data returned by an access to password |
168+
| main.go:21:13:21:20 | password | main.go:21:13:21:20 | password | main.go:21:13:21:20 | password | $@ flows to a logging call. | main.go:21:13:21:20 | password | Sensitive data returned by an access to password |
169+
| main.go:22:14:22:21 | password | main.go:22:14:22:21 | password | main.go:22:14:22:21 | password | $@ flows to a logging call. | main.go:22:14:22:21 | password | Sensitive data returned by an access to password |
170+
| main.go:23:12:23:19 | password | main.go:23:12:23:19 | password | main.go:23:12:23:19 | password | $@ flows to a logging call. | main.go:23:12:23:19 | password | Sensitive data returned by an access to password |
171+
| main.go:24:17:24:24 | password | main.go:24:17:24:24 | password | main.go:24:17:24:24 | password | $@ flows to a logging call. | main.go:24:17:24:24 | password | Sensitive data returned by an access to password |
172+
| main.go:25:13:25:20 | password | main.go:25:13:25:20 | password | main.go:25:13:25:20 | password | $@ flows to a logging call. | main.go:25:13:25:20 | password | Sensitive data returned by an access to password |
173+
| main.go:26:14:26:21 | password | main.go:26:14:26:21 | password | main.go:26:14:26:21 | password | $@ flows to a logging call. | main.go:26:14:26:21 | password | Sensitive data returned by an access to password |
174+
| main.go:27:16:27:23 | password | main.go:27:16:27:23 | password | main.go:27:16:27:23 | password | $@ flows to a logging call. | main.go:27:16:27:23 | password | Sensitive data returned by an access to password |
175+
| main.go:30:10:30:17 | password | main.go:30:10:30:17 | password | main.go:30:10:30:17 | password | $@ flows to a logging call. | main.go:30:10:30:17 | password | Sensitive data returned by an access to password |
176+
| main.go:31:15:31:22 | password | main.go:31:15:31:22 | password | main.go:31:15:31:22 | password | $@ flows to a logging call. | main.go:31:15:31:22 | password | Sensitive data returned by an access to password |
177+
| main.go:32:11:32:18 | password | main.go:32:11:32:18 | password | main.go:32:11:32:18 | password | $@ flows to a logging call. | main.go:32:11:32:18 | password | Sensitive data returned by an access to password |
178+
| main.go:33:12:33:19 | password | main.go:33:12:33:19 | password | main.go:33:12:33:19 | password | $@ flows to a logging call. | main.go:33:12:33:19 | password | Sensitive data returned by an access to password |
179+
| main.go:34:10:34:17 | password | main.go:34:10:34:17 | password | main.go:34:10:34:17 | password | $@ flows to a logging call. | main.go:34:10:34:17 | password | Sensitive data returned by an access to password |
180+
| main.go:35:15:35:22 | password | main.go:35:15:35:22 | password | main.go:35:15:35:22 | password | $@ flows to a logging call. | main.go:35:15:35:22 | password | Sensitive data returned by an access to password |
181+
| main.go:36:11:36:18 | password | main.go:36:11:36:18 | password | main.go:36:11:36:18 | password | $@ flows to a logging call. | main.go:36:11:36:18 | password | Sensitive data returned by an access to password |
182+
| main.go:37:12:37:19 | password | main.go:37:12:37:19 | password | main.go:37:12:37:19 | password | $@ flows to a logging call. | main.go:37:12:37:19 | password | Sensitive data returned by an access to password |
183+
| main.go:38:10:38:17 | password | main.go:38:10:38:17 | password | main.go:38:10:38:17 | password | $@ flows to a logging call. | main.go:38:10:38:17 | password | Sensitive data returned by an access to password |
184+
| main.go:39:15:39:22 | password | main.go:39:15:39:22 | password | main.go:39:15:39:22 | password | $@ flows to a logging call. | main.go:39:15:39:22 | password | Sensitive data returned by an access to password |
185+
| main.go:40:11:40:18 | password | main.go:40:11:40:18 | password | main.go:40:11:40:18 | password | $@ flows to a logging call. | main.go:40:11:40:18 | password | Sensitive data returned by an access to password |
186+
| main.go:41:12:41:19 | password | main.go:41:12:41:19 | password | main.go:41:12:41:19 | password | $@ flows to a logging call. | main.go:41:12:41:19 | password | Sensitive data returned by an access to password |
187+
| main.go:42:14:42:21 | password | main.go:42:14:42:21 | password | main.go:42:14:42:21 | password | $@ flows to a logging call. | main.go:42:14:42:21 | password | Sensitive data returned by an access to password |
188+
| main.go:44:12:44:19 | password | main.go:44:12:44:19 | password | main.go:44:12:44:19 | password | $@ flows to a logging call. | main.go:44:12:44:19 | password | Sensitive data returned by an access to password |
189+
| main.go:45:17:45:24 | password | main.go:45:17:45:24 | password | main.go:45:17:45:24 | password | $@ flows to a logging call. | main.go:45:17:45:24 | password | Sensitive data returned by an access to password |
190+
| main.go:52:35:52:42 | password | main.go:52:35:52:42 | password | main.go:52:35:52:42 | password | $@ flows to a logging call. | main.go:52:35:52:42 | password | Sensitive data returned by an access to password |
149191
| overrides.go:13:14:13:23 | call to String | overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:9:9:9:16 | password | Sensitive data returned by an access to password |
150192
| passwords.go:9:14:9:14 | x | passwords.go:30:8:30:15 | password | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:30:8:30:15 | password | Sensitive data returned by an access to password |
151193
| passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password | $@ flows to a logging call. | passwords.go:25:14:25:21 | password | Sensitive data returned by an access to password |
152194
| passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | $@ flows to a logging call. | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by an access to password |
153195
| passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | $@ flows to a logging call. | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by a call to getPassword |
154196
| passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by a call to getPassword |
155-
| passwords.go:28:14:28:28 | call to getPassword | util.go:16:9:16:18 | selection of password | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | util.go:16:9:16:18 | selection of password | Sensitive data returned by an access to password |
156197
| passwords.go:32:12:32:19 | password | passwords.go:32:12:32:19 | password | passwords.go:32:12:32:19 | password | $@ flows to a logging call. | passwords.go:32:12:32:19 | password | Sensitive data returned by an access to password |
157198
| passwords.go:34:14:34:35 | ...+... | passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | $@ flows to a logging call. | passwords.go:34:28:34:35 | password | Sensitive data returned by an access to password |
158199
| passwords.go:39:14:39:17 | obj1 | passwords.go:37:13:37:13 | x | passwords.go:39:14:39:17 | obj1 | $@ flows to a logging call. | passwords.go:37:13:37:13 | x | Sensitive data returned by an access to password |

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,34 @@ import (
1212
func main() {
1313
password := "P4ssw0rd"
1414

15+
log.Print(password)
16+
log.Printf("", password)
17+
log.Printf(password, "")
1518
log.Println(password)
19+
log.Fatal(password)
20+
log.Fatalf("", password)
21+
log.Fatalf(password, "")
22+
log.Fatalln(password)
23+
log.Panic(password)
24+
log.Panicf("", password)
25+
log.Panicf(password, "")
26+
log.Panicln(password)
27+
log.Output(0, password)
28+
29+
l := log.Default()
30+
l.Print(password)
31+
l.Printf("", password)
32+
l.Printf(password, "")
33+
l.Println(password)
34+
l.Fatal(password)
35+
l.Fatalf("", password)
36+
l.Fatalf(password, "")
37+
l.Fatalln(password)
38+
l.Panic(password)
39+
l.Panicf("", password)
40+
l.Panicf(password, "")
41+
l.Panicln(password)
42+
l.Output(0, password)
1643

1744
glog.Info(password)
1845
logrus.Warning(password)

0 commit comments

Comments
 (0)