Make ClearTextLogging use new API

The extra nodes in .expected files are due to the changes from
https://github.com/github/codeql/pull/13717, which are not applied to
configuration classes extending DataFlow::Configuration or
TaintTracking::Configuration.
This commit is contained in:
Owen Mansel-Chan
2023-07-01 15:00:05 +01:00
parent 653563fcbc
commit a7382e06c2
3 changed files with 88 additions and 19 deletions

View File

@@ -17,6 +17,8 @@ module CleartextLogging {
import CleartextLoggingCustomizations::CleartextLogging
/**
* DEPRECATED: Use `Flow` instead.
*
* A data-flow tracking configuration for clear-text logging of sensitive information.
*
* This configuration identifies flows from `Source`s, which are sources of
@@ -25,7 +27,7 @@ module CleartextLogging {
* added either by extending the relevant class, or by subclassing this configuration itself,
* and amending the sources and sinks.
*/
class Configuration extends DataFlow::Configuration {
deprecated class Configuration extends DataFlow::Configuration {
Configuration() { this = "CleartextLogging" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -56,4 +58,36 @@ module CleartextLogging {
not any(Protobuf::GetMethod gm).taintStep(src, trg)
}
}
private module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof Source }
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) {
node instanceof Barrier
or
exists(DataFlow::CallNode call | node = call.getResult() |
call.getTarget() = Builtin::error().getType().getMethod("Error")
or
call.getTarget().(Method).hasQualifiedName("fmt", "Stringer", "String")
)
}
predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) {
// A taint propagating data-flow edge through structs: a tainted write taints the entire struct.
exists(Write write |
write.writesField(trg.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, src)
)
or
// taint steps that do not include flow through fields. Field reads would produce FPs due to
// the additional taint step above that taints whole structs from individual field writes.
TaintTracking::localTaintStep(src, trg) and
not TaintTracking::fieldReadStep(src, trg) and
// Also exclude protobuf field fetches, since they amount to single field reads.
not any(Protobuf::GetMethod gm).taintStep(src, trg)
}
}
module Flow = DataFlow::Global<Config>;
}

View File

@@ -14,10 +14,10 @@
*/
import go
import semmle.go.security.CleartextLogging::CleartextLogging
import DataFlow::PathGraph
import semmle.go.security.CleartextLogging
import CleartextLogging::Flow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
from CleartextLogging::Flow::PathNode source, CleartextLogging::Flow::PathNode sink
where CleartextLogging::Flow::flowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to a logging call.", source.getNode(),
"Sensitive data returned by " + source.getNode().(Source).describe()
"Sensitive data returned by " + source.getNode().(CleartextLogging::Source).describe()

View File

@@ -1,29 +1,46 @@
edges
| klog.go:20:30:20:37 | selection of Header | klog.go:22:15:22:20 | header |
| klog.go:20:3:25:3 | range statement[1] | klog.go:20:13:20:19 | definition of headers |
| klog.go:20:13:20:19 | definition of headers | klog.go:21:27:21:33 | headers |
| klog.go:20:30:20:37 | selection of Header | klog.go:20:3:25:3 | range statement[1] |
| klog.go:21:4:24:4 | range statement[1] | klog.go:21:11:21:16 | definition of header |
| klog.go:21:11:21:16 | definition of header | klog.go:22:15:22:20 | header |
| klog.go:21:27:21:33 | headers | klog.go:21:4:24:4 | range statement[1] |
| klog.go:28:13:28:20 | selection of Header | klog.go:28:13:28:41 | call to Get |
| main.go:21:19:21:26 | password | main.go:22:29:22:34 | fields |
| main.go:20:2:20:7 | definition of fields | main.go:22:29:22:34 | fields |
| main.go:21:19:21:26 | password | main.go:20:2:20:7 | definition of fields |
| overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String |
| passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x |
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x |
| passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... |
| passwords.go:37:13:37:13 | x | passwords.go:39:14:39:17 | obj1 |
| passwords.go:42:6:42:13 | password | passwords.go:44:14:44:17 | obj2 |
| passwords.go:48:11:48:18 | password | passwords.go:47:14:47:17 | obj3 |
| passwords.go:86:16:86:36 | call to make | passwords.go:88:14:88:26 | utilityObject |
| passwords.go:90:12:90:19 | password | passwords.go:91:23:91:28 | secret |
| passwords.go:36:2:36:5 | definition of obj1 | passwords.go:39:14:39:17 | obj1 |
| passwords.go:36:10:38:2 | struct literal | passwords.go:36:2:36:5 | definition of obj1 |
| passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal |
| passwords.go:41:2:41:5 | definition of obj2 | passwords.go:44:14:44:17 | obj2 |
| passwords.go:41:10:43:2 | struct literal | passwords.go:41:2:41:5 | definition of obj2 |
| passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal |
| passwords.go:46:6:46:9 | definition of obj3 | passwords.go:47:14:47:17 | obj3 |
| passwords.go:48:11:48:18 | password | passwords.go:46:6:46:9 | definition of obj3 |
| passwords.go:85:2:85:14 | definition of utilityObject | passwords.go:88:14:88:26 | utilityObject |
| passwords.go:85:19:87:2 | struct literal | passwords.go:85:2:85:14 | definition of utilityObject |
| passwords.go:86:16:86:36 | call to make | passwords.go:85:19:87:2 | struct literal |
| passwords.go:90:2:90:7 | definition of secret | passwords.go:91:23:91:28 | secret |
| passwords.go:90:12:90:19 | password | passwords.go:90:2:90:7 | definition of secret |
| passwords.go:101:33:101:40 | password | passwords.go:101:15:101:40 | ...+... |
| passwords.go:107:34:107:41 | password | passwords.go:107:16:107:41 | ...+... |
| passwords.go:112:33:112:40 | password | passwords.go:112:15:112:40 | ...+... |
| passwords.go:116:28:116:36 | password1 | passwords.go:116:14:116:45 | ...+... |
| passwords.go:116:28:116:36 | password1 | passwords.go:116:28:116:45 | call to String |
| passwords.go:116:28:116:45 | call to String | passwords.go:116:14:116:45 | ...+... |
| passwords.go:118:12:123:2 | struct literal [x] | passwords.go:126:14:126:19 | config [x] |
| passwords.go:118:12:123:2 | struct literal [y] | passwords.go:127:14:127:19 | config [y] |
| passwords.go:119:13:119:13 | x | passwords.go:125:14:125:19 | config |
| passwords.go:118:2:118:7 | definition of config | passwords.go:125:14:125:19 | config |
| passwords.go:118:2:118:7 | definition of config [x] | passwords.go:126:14:126:19 | config [x] |
| passwords.go:118:2:118:7 | definition of config [y] | passwords.go:127:14:127:19 | config [y] |
| passwords.go:118:12:123:2 | struct literal | passwords.go:118:2:118:7 | definition of config |
| passwords.go:118:12:123:2 | struct literal [x] | passwords.go:118:2:118:7 | definition of config [x] |
| passwords.go:118:12:123:2 | struct literal [y] | passwords.go:118:2:118:7 | definition of config [y] |
| passwords.go:119:13:119:13 | x | passwords.go:118:12:123:2 | struct literal |
| passwords.go:121:13:121:20 | password | passwords.go:118:12:123:2 | struct literal |
| passwords.go:121:13:121:20 | password | passwords.go:118:12:123:2 | struct literal [x] |
| passwords.go:121:13:121:20 | password | passwords.go:125:14:125:19 | config |
| passwords.go:122:13:122:25 | call to getPassword | passwords.go:118:12:123:2 | struct literal |
| passwords.go:122:13:122:25 | call to getPassword | passwords.go:118:12:123:2 | struct literal [y] |
| passwords.go:122:13:122:25 | call to getPassword | passwords.go:125:14:125:19 | config |
| passwords.go:126:14:126:19 | config [x] | passwords.go:126:14:126:21 | selection of x |
| passwords.go:127:14:127:19 | config [y] | passwords.go:127:14:127:21 | selection of y |
| protobuf.go:11:2:11:6 | definition of query [pointer, Description] | protobuf.go:12:2:12:6 | query [pointer, Description] |
@@ -38,13 +55,19 @@ edges
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] |
| util.go:16:9:16:18 | selection of password | passwords.go:28:14:28:28 | call to getPassword |
nodes
| klog.go:20:3:25:3 | range statement[1] | semmle.label | range statement[1] |
| klog.go:20:13:20:19 | definition of headers | semmle.label | definition of headers |
| 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:11:21:16 | definition of header | semmle.label | definition of header |
| 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 |
| main.go:15:14:15:21 | password | semmle.label | password |
| main.go:17:12:17:19 | password | semmle.label | password |
| main.go:18:17:18:24 | password | semmle.label | password |
| main.go:20:2:20:7 | definition of fields | semmle.label | definition of fields |
| main.go:21:19:21:26 | password | semmle.label | password |
| main.go:22:29:22:34 | fields | semmle.label | fields |
| main.go:25:35:25:42 | password | semmle.label | password |
@@ -60,15 +83,23 @@ nodes
| passwords.go:32:12:32:19 | password | semmle.label | password |
| passwords.go:34:14:34:35 | ...+... | semmle.label | ...+... |
| passwords.go:34:28:34:35 | password | semmle.label | password |
| passwords.go:36:2:36:5 | definition of obj1 | semmle.label | definition of obj1 |
| passwords.go:36:10:38:2 | struct literal | semmle.label | struct literal |
| passwords.go:37:13:37:13 | x | semmle.label | x |
| passwords.go:39:14:39:17 | obj1 | semmle.label | obj1 |
| passwords.go:41:2:41:5 | definition of obj2 | semmle.label | definition of obj2 |
| passwords.go:41:10:43:2 | struct literal | semmle.label | struct literal |
| passwords.go:42:6:42:13 | password | semmle.label | password |
| passwords.go:44:14:44:17 | obj2 | semmle.label | obj2 |
| passwords.go:46:6:46:9 | definition of obj3 | semmle.label | definition of obj3 |
| passwords.go:47:14:47:17 | obj3 | semmle.label | obj3 |
| passwords.go:48:11:48:18 | password | semmle.label | password |
| passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password |
| passwords.go:85:2:85:14 | definition of utilityObject | semmle.label | definition of utilityObject |
| passwords.go:85:19:87:2 | struct literal | semmle.label | struct literal |
| passwords.go:86:16:86:36 | call to make | semmle.label | call to make |
| passwords.go:88:14:88:26 | utilityObject | semmle.label | utilityObject |
| passwords.go:90:2:90:7 | definition of secret | semmle.label | definition of secret |
| passwords.go:90:12:90:19 | password | semmle.label | password |
| passwords.go:91:23:91:28 | secret | semmle.label | secret |
| passwords.go:101:15:101:40 | ...+... | semmle.label | ...+... |
@@ -80,6 +111,10 @@ nodes
| passwords.go:116:14:116:45 | ...+... | semmle.label | ...+... |
| passwords.go:116:28:116:36 | password1 | semmle.label | password1 |
| passwords.go:116:28:116:45 | call to String | semmle.label | call to String |
| passwords.go:118:2:118:7 | definition of config | semmle.label | definition of config |
| passwords.go:118:2:118:7 | definition of config [x] | semmle.label | definition of config [x] |
| passwords.go:118:2:118:7 | definition of config [y] | semmle.label | definition of config [y] |
| passwords.go:118:12:123:2 | struct literal | semmle.label | struct literal |
| passwords.go:118:12:123:2 | struct literal [x] | semmle.label | struct literal [x] |
| passwords.go:118:12:123:2 | struct literal [y] | semmle.label | struct literal [y] |
| passwords.go:119:13:119:13 | x | semmle.label | x |