From e13c4b75503d77343edff9553e510aa3e4defba9 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Dec 2024 10:41:23 +0000 Subject: [PATCH 1/6] Treat container flow as taint flow in localTaintStep --- .../go/dataflow/internal/DataFlowPrivate.qll | 10 +++++++ .../dataflow/internal/TaintTrackingUtil.qll | 14 ++++++++-- .../FlowSteps/LocalTaintStep.expected | 28 +++++++++++++++++++ .../frameworks/TaintSteps/TaintStep.expected | 12 ++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 2fcbf2d350f2..032196312483 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -458,3 +458,13 @@ class ContentApprox = Unit; /** Gets an approximated value for content `c`. */ pragma[inline] ContentApprox getContentApprox(Content c) { any() } + +/** + * Holds if the the content `c` is a container. + */ +predicate containerContent(ContentSet c) { + c instanceof ArrayContent or + c instanceof CollectionContent or + c instanceof MapKeyContent or + c instanceof MapValueContent +} diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 5365228e2310..80c83c219657 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -27,11 +27,21 @@ predicate localExprTaint(Expr src, Expr sink) { * Holds if taint can flow in one local step from `src` to `sink`. */ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) { - DataFlow::localFlowStep(src, sink) or - localAdditionalTaintStep(src, sink, _) or + DataFlow::localFlowStep(src, sink) + or + localAdditionalTaintStep(src, sink, _) + or // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink, _) + or + // Treat container flow as taint for the local taint flow relation + exists(DataFlow::Content c | DataFlowPrivate::containerContent(c) | + DataFlowPrivate::readStep(src, c, sink) or + DataFlowPrivate::storeStep(src, c, sink) or + FlowSummaryImpl::Private::Steps::summaryGetterStep(src, c, sink, _) or + FlowSummaryImpl::Private::Steps::summarySetterStep(src, c, sink, _) + ) } private Type getElementType(Type containerType) { diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected index 6fadcdaabe63..abe37122ba6b 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected @@ -5,24 +5,36 @@ | main.go:38:19:38:19 | 3 | main.go:38:7:38:20 | slice literal | | main.go:39:8:39:25 | []type{args} | main.go:39:8:39:25 | call to append | | main.go:39:15:39:15 | s | main.go:39:8:39:25 | call to append | +| main.go:39:18:39:18 | 4 | main.go:39:8:39:25 | []type{args} | +| main.go:39:21:39:21 | 5 | main.go:39:8:39:25 | []type{args} | +| main.go:39:24:39:24 | 6 | main.go:39:8:39:25 | []type{args} | | main.go:40:15:40:15 | s | main.go:40:8:40:23 | call to append | | main.go:40:18:40:19 | s1 | main.go:40:8:40:23 | call to append | | main.go:42:10:42:11 | s4 | main.go:38:2:38:2 | definition of s | | main.go:47:20:47:21 | next key-value pair in range | main.go:47:2:50:2 | range statement[0] | | main.go:47:20:47:21 | next key-value pair in range | main.go:47:2:50:2 | range statement[1] | | main.go:47:20:47:21 | xs | main.go:47:2:50:2 | range statement[1] | +| main.go:56:8:56:11 | true | main.go:56:2:56:3 | ch | +| main.go:57:4:57:5 | ch | main.go:57:2:57:5 | <-... | | strings.go:9:24:9:24 | s | strings.go:9:8:9:38 | call to Replace | | strings.go:9:32:9:34 | "_" | strings.go:9:8:9:38 | call to Replace | | strings.go:10:27:10:27 | s | strings.go:10:8:10:42 | call to ReplaceAll | | strings.go:10:35:10:41 | "&" | strings.go:10:8:10:42 | call to ReplaceAll | +| strings.go:11:9:11:26 | []type{args} | strings.go:11:9:11:26 | call to Sprint | | strings.go:11:9:11:26 | call to Sprint | strings.go:11:9:11:50 | ...+... | | strings.go:11:9:11:50 | ...+... | strings.go:11:9:11:69 | ...+... | +| strings.go:11:20:11:21 | s2 | strings.go:11:9:11:26 | []type{args} | | strings.go:11:20:11:21 | s2 | strings.go:11:9:11:26 | call to Sprint | +| strings.go:11:24:11:25 | s3 | strings.go:11:9:11:26 | []type{args} | | strings.go:11:24:11:25 | s3 | strings.go:11:9:11:26 | call to Sprint | +| strings.go:11:30:11:50 | []type{args} | strings.go:11:30:11:50 | call to Sprintf | | strings.go:11:30:11:50 | call to Sprintf | strings.go:11:9:11:50 | ...+... | | strings.go:11:42:11:45 | "%q" | strings.go:11:30:11:50 | call to Sprintf | +| strings.go:11:48:11:49 | s2 | strings.go:11:30:11:50 | []type{args} | | strings.go:11:48:11:49 | s2 | strings.go:11:30:11:50 | call to Sprintf | +| strings.go:11:54:11:69 | []type{args} | strings.go:11:54:11:69 | call to Sprintln | | strings.go:11:54:11:69 | call to Sprintln | strings.go:11:9:11:69 | ...+... | +| strings.go:11:67:11:68 | s3 | strings.go:11:54:11:69 | []type{args} | | strings.go:11:67:11:68 | s3 | strings.go:11:54:11:69 | call to Sprintln | | url.go:12:14:12:48 | call to PathUnescape | url.go:12:3:12:48 | ... = ...[0] | | url.go:12:14:12:48 | call to PathUnescape | url.go:12:3:12:48 | ... = ...[1] | @@ -39,17 +51,25 @@ | url.go:27:9:27:30 | call to ParseRequestURI | url.go:27:2:27:30 | ... = ...[1] | | url.go:27:29:27:29 | s | url.go:27:2:27:30 | ... = ...[0] | | url.go:28:14:28:14 | u | url.go:28:14:28:28 | call to EscapedPath | +| url.go:28:14:28:28 | call to EscapedPath | url.go:28:2:28:29 | []type{args} | | url.go:29:14:29:14 | u | url.go:29:14:29:25 | call to Hostname | +| url.go:29:14:29:25 | call to Hostname | url.go:29:2:29:26 | []type{args} | | url.go:30:11:30:11 | u | url.go:30:2:30:27 | ... := ...[0] | | url.go:30:11:30:27 | call to MarshalBinary | url.go:30:2:30:27 | ... := ...[0] | | url.go:30:11:30:27 | call to MarshalBinary | url.go:30:2:30:27 | ... := ...[1] | +| url.go:31:2:31:16 | []type{args} | url.go:30:2:30:3 | definition of bs | +| url.go:31:14:31:15 | bs | url.go:31:2:31:16 | []type{args} | | url.go:32:9:32:9 | u | url.go:32:2:32:23 | ... = ...[0] | | url.go:32:9:32:23 | call to Parse | url.go:32:2:32:23 | ... = ...[0] | | url.go:32:9:32:23 | call to Parse | url.go:32:2:32:23 | ... = ...[1] | | url.go:32:17:32:22 | "/foo" | url.go:32:2:32:23 | ... = ...[0] | | url.go:33:14:33:14 | u | url.go:33:14:33:21 | call to Port | +| url.go:33:14:33:21 | call to Port | url.go:33:2:33:22 | []type{args} | +| url.go:34:2:34:23 | []type{args} | url.go:34:14:34:22 | call to Query | | url.go:34:14:34:14 | u | url.go:34:14:34:22 | call to Query | +| url.go:34:14:34:22 | call to Query | url.go:34:2:34:23 | []type{args} | | url.go:35:14:35:14 | u | url.go:35:14:35:27 | call to RequestURI | +| url.go:35:14:35:27 | call to RequestURI | url.go:35:2:35:28 | []type{args} | | url.go:36:6:36:6 | u | url.go:36:6:36:26 | call to ResolveReference | | url.go:36:25:36:25 | u | url.go:36:6:36:26 | call to ResolveReference | | url.go:41:17:41:20 | "me" | url.go:41:8:41:21 | call to User | @@ -58,27 +78,35 @@ | url.go:43:11:43:12 | ui | url.go:43:2:43:23 | ... := ...[0] | | url.go:43:11:43:23 | call to Password | url.go:43:2:43:23 | ... := ...[0] | | url.go:43:11:43:23 | call to Password | url.go:43:2:43:23 | ... := ...[1] | +| url.go:44:14:44:15 | pw | url.go:44:2:44:16 | []type{args} | | url.go:45:14:45:15 | ui | url.go:45:14:45:26 | call to Username | +| url.go:45:14:45:26 | call to Username | url.go:45:2:45:27 | []type{args} | | url.go:50:10:50:26 | call to ParseQuery | url.go:50:2:50:26 | ... := ...[0] | | url.go:50:10:50:26 | call to ParseQuery | url.go:50:2:50:26 | ... := ...[1] | | url.go:50:25:50:25 | q | url.go:50:2:50:26 | ... := ...[0] | | url.go:51:14:51:14 | v | url.go:51:14:51:23 | call to Encode | +| url.go:51:14:51:23 | call to Encode | url.go:51:2:51:24 | []type{args} | | url.go:52:14:52:14 | v | url.go:52:14:52:26 | call to Get | +| url.go:52:14:52:26 | call to Get | url.go:52:2:52:27 | []type{args} | | url.go:57:16:57:39 | call to JoinPath | url.go:57:2:57:39 | ... := ...[0] | | url.go:57:16:57:39 | call to JoinPath | url.go:57:2:57:39 | ... := ...[1] | | url.go:57:29:57:29 | q | url.go:57:2:57:39 | ... := ...[0] | | url.go:57:32:57:38 | "clean" | url.go:57:2:57:39 | ... := ...[0] | +| url.go:57:32:57:38 | "clean" | url.go:57:16:57:39 | []type{args} | | url.go:58:16:58:45 | call to JoinPath | url.go:58:2:58:45 | ... := ...[0] | | url.go:58:16:58:45 | call to JoinPath | url.go:58:2:58:45 | ... := ...[1] | | url.go:58:29:58:35 | "clean" | url.go:58:2:58:45 | ... := ...[0] | | url.go:58:38:58:44 | joined1 | url.go:58:2:58:45 | ... := ...[0] | +| url.go:58:38:58:44 | joined1 | url.go:58:16:58:45 | []type{args} | | url.go:59:14:59:31 | call to Parse | url.go:59:2:59:31 | ... := ...[0] | | url.go:59:14:59:31 | call to Parse | url.go:59:2:59:31 | ... := ...[1] | | url.go:59:24:59:30 | joined2 | url.go:59:2:59:31 | ... := ...[0] | | url.go:60:15:60:19 | asUrl | url.go:60:15:60:37 | call to JoinPath | +| url.go:60:30:60:36 | "clean" | url.go:60:15:60:37 | []type{args} | | url.go:60:30:60:36 | "clean" | url.go:60:15:60:37 | call to JoinPath | | url.go:65:17:65:48 | call to Parse | url.go:65:2:65:48 | ... := ...[0] | | url.go:65:17:65:48 | call to Parse | url.go:65:2:65:48 | ... := ...[1] | | url.go:65:27:65:47 | "http://harmless.org" | url.go:65:2:65:48 | ... := ...[0] | | url.go:66:9:66:16 | cleanUrl | url.go:66:9:66:28 | call to JoinPath | +| url.go:66:27:66:27 | q | url.go:66:9:66:28 | []type{args} | | url.go:66:27:66:27 | q | url.go:66:9:66:28 | call to JoinPath | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected b/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected index b7c6f703cf51..1e140bf28b15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected @@ -10,9 +10,13 @@ invalidModelRow | io.go:14:31:14:43 | "some string" | io.go:14:13:14:44 | call to NewReader | | io.go:16:3:16:3 | definition of w | io.go:16:23:16:27 | &... | | io.go:16:3:16:3 | definition of w | io.go:16:30:16:34 | &... | +| io.go:16:8:16:35 | []type{args} | io.go:16:23:16:27 | &... | +| io.go:16:8:16:35 | []type{args} | io.go:16:30:16:34 | &... | | io.go:16:23:16:27 | &... | io.go:15:7:15:10 | definition of buf1 | +| io.go:16:23:16:27 | &... | io.go:16:8:16:35 | []type{args} | | io.go:16:24:16:27 | buf1 | io.go:16:23:16:27 | &... | | io.go:16:30:16:34 | &... | io.go:15:13:15:16 | definition of buf2 | +| io.go:16:30:16:34 | &... | io.go:16:8:16:35 | []type{args} | | io.go:16:31:16:34 | buf2 | io.go:16:30:16:34 | &... | | io.go:18:14:18:19 | reader | io.go:16:3:16:3 | definition of w | | io.go:22:31:22:43 | "some string" | io.go:22:13:22:44 | call to NewReader | @@ -27,8 +31,10 @@ invalidModelRow | io.go:39:11:39:19 | call to Pipe | io.go:39:3:39:19 | ... := ...[0] | | io.go:39:11:39:19 | call to Pipe | io.go:39:3:39:19 | ... := ...[1] | | io.go:40:17:40:31 | "some string\\n" | io.go:39:6:39:6 | definition of w | +| io.go:40:17:40:31 | "some string\\n" | io.go:40:3:40:32 | []type{args} | | io.go:43:16:43:16 | r | io.go:42:3:42:5 | definition of buf | | io.go:44:13:44:15 | buf | io.go:44:13:44:24 | call to String | +| io.go:44:13:44:24 | call to String | io.go:44:3:44:25 | []type{args} | | io.go:48:31:48:43 | "some string" | io.go:48:13:48:44 | call to NewReader | | io.go:50:18:50:23 | reader | io.go:49:3:49:5 | definition of buf | | io.go:54:31:54:43 | "some string" | io.go:54:13:54:44 | call to NewReader | @@ -46,8 +52,14 @@ invalidModelRow | io.go:82:27:82:36 | "reader1 " | io.go:82:9:82:37 | call to NewReader | | io.go:83:27:83:36 | "reader2 " | io.go:83:9:83:37 | call to NewReader | | io.go:84:27:84:35 | "reader3" | io.go:84:9:84:36 | call to NewReader | +| io.go:85:8:85:33 | []type{args} | io.go:82:3:82:4 | definition of r1 | +| io.go:85:8:85:33 | []type{args} | io.go:83:3:83:4 | definition of r2 | +| io.go:85:8:85:33 | []type{args} | io.go:84:3:84:4 | definition of r3 | +| io.go:85:23:85:24 | r1 | io.go:85:8:85:33 | []type{args} | | io.go:85:23:85:24 | r1 | io.go:85:8:85:33 | call to MultiReader | +| io.go:85:27:85:28 | r2 | io.go:85:8:85:33 | []type{args} | | io.go:85:27:85:28 | r2 | io.go:85:8:85:33 | call to MultiReader | +| io.go:85:31:85:32 | r3 | io.go:85:8:85:33 | []type{args} | | io.go:85:31:85:32 | r3 | io.go:85:8:85:33 | call to MultiReader | | io.go:86:22:86:22 | r | io.go:86:11:86:19 | selection of Stdout | | io.go:89:26:89:38 | "some string" | io.go:89:8:89:39 | call to NewReader | From 3f7c37e1edda52588c59523a6365c3fc8801977d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Dec 2024 11:41:32 +0000 Subject: [PATCH 2/6] Treat container flow as taint flow in global taint flow --- .../dataflow/internal/TaintTrackingUtil.qll | 23 ++++++++++++++----- .../CWE-74/DsnInjectionLocal.expected | 7 ++++++ .../dataflow/VarArgsWithExternalFlow/main.go | 8 ++++++- .../CWE-078/CommandInjection.expected | 11 +++++++++ .../CWE-209/StackTraceExposure.expected | 13 +++++++++++ .../CWE-312/CleartextLogging.expected | 18 +++++---------- .../Security/CWE-327/UnsafeTLS.expected | 4 ++++ .../InsecureRandomness.expected | 5 ++++ 8 files changed, 70 insertions(+), 19 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 80c83c219657..c6c9f933707c 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -98,13 +98,24 @@ class AdditionalTaintStep extends Unit { */ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ, string model) { ( - referenceStep(pred, succ) or - elementWriteStep(pred, succ) or - fieldReadStep(pred, succ) or - elementStep(pred, succ) or - tupleStep(pred, succ) or - stringConcatStep(pred, succ) or + referenceStep(pred, succ) + or + elementWriteStep(pred, succ) + or + fieldReadStep(pred, succ) + or + elementStep(pred, succ) + or + tupleStep(pred, succ) + or + stringConcatStep(pred, succ) + or sliceStep(pred, succ) + or + // Treat container flow as taint for the local taint flow relation + exists(DataFlow::Content c | DataFlowPrivate::containerContent(c) | + DataFlowPrivate::readStep(pred, c, succ) + ) ) and model = "" or diff --git a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected index ff83f06ebb28..e18bdf1c8c4f 100644 --- a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected +++ b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected @@ -2,9 +2,13 @@ | Dsn.go:29:29:29:33 | dbDSN | Dsn.go:26:11:26:17 | selection of Args | Dsn.go:29:29:29:33 | dbDSN | This query depends on a $@. | Dsn.go:26:11:26:17 | selection of Args | user-provided value | | Dsn.go:68:29:68:33 | dbDSN | Dsn.go:63:19:63:25 | selection of Args | Dsn.go:68:29:68:33 | dbDSN | This query depends on a $@. | Dsn.go:63:19:63:25 | selection of Args | user-provided value | edges +| Dsn.go:26:11:26:17 | selection of Args | Dsn.go:26:11:26:21 | slice element node | provenance | | | Dsn.go:26:11:26:17 | selection of Args | Dsn.go:28:102:28:109 | index expression | provenance | | +| Dsn.go:26:11:26:21 | slice element node | Dsn.go:26:11:26:21 | slice expression [array] | provenance | | +| Dsn.go:26:11:26:21 | slice expression [array] | Dsn.go:28:102:28:106 | name2 [array] | provenance | | | Dsn.go:28:11:28:110 | []type{args} [array] | Dsn.go:28:11:28:110 | call to Sprintf | provenance | MaD:1 | | Dsn.go:28:11:28:110 | call to Sprintf | Dsn.go:29:29:29:33 | dbDSN | provenance | | +| Dsn.go:28:102:28:106 | name2 [array] | Dsn.go:28:102:28:109 | index expression | provenance | | | Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | []type{args} [array] | provenance | | | Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | call to Sprintf | provenance | FunctionModel | | Dsn.go:62:2:62:4 | definition of cfg [pointer] | Dsn.go:63:9:63:11 | cfg [pointer] | provenance | | @@ -25,8 +29,11 @@ models | 1 | Summary: fmt; ; false; Sprintf; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual | nodes | Dsn.go:26:11:26:17 | selection of Args | semmle.label | selection of Args | +| Dsn.go:26:11:26:21 | slice element node | semmle.label | slice element node | +| Dsn.go:26:11:26:21 | slice expression [array] | semmle.label | slice expression [array] | | Dsn.go:28:11:28:110 | []type{args} [array] | semmle.label | []type{args} [array] | | Dsn.go:28:11:28:110 | call to Sprintf | semmle.label | call to Sprintf | +| Dsn.go:28:102:28:106 | name2 [array] | semmle.label | name2 [array] | | Dsn.go:28:102:28:109 | index expression | semmle.label | index expression | | Dsn.go:29:29:29:33 | dbDSN | semmle.label | dbDSN | | Dsn.go:62:2:62:4 | definition of cfg [pointer] | semmle.label | definition of cfg [pointer] | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go index f90f429b12a4..9d978553d449 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go @@ -44,7 +44,13 @@ func main() { var variadicSource string test.VariadicSource(&variadicSource) - sink(variadicSource) // $ MISSING: hasTaintFlow="variadicSource" + sink(variadicSource) // $ hasTaintFlow="variadicSource" + sink(&variadicSource) // $ hasTaintFlow="&..." + + var variadicSourcePtr *string + test.VariadicSource(variadicSourcePtr) + sink(variadicSourcePtr) // $ hasTaintFlow="variadicSourcePtr" + sink(*variadicSourcePtr) // $ hasTaintFlow="star expression" test.VariadicSink(source()) // $ hasTaintFlow="[]type{args}" diff --git a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index dff32df4e1ff..7642f44856ba 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -50,6 +50,7 @@ edges | GitSubcommands.go:33:13:33:27 | call to Query | GitSubcommands.go:38:32:38:38 | tainted | provenance | | | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:9:13:9:27 | call to Query | provenance | Src:MaD:2 MaD:7 | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:13:25:13:31 | tainted | provenance | | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:14:23:14:33 | slice element node | provenance | | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:39:31:39:37 | tainted | provenance | | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:52:24:52:30 | tainted | provenance | | @@ -70,6 +71,8 @@ edges | SanitizingDoubleDash.go:53:14:53:35 | call to append | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:53:14:53:35 | call to append [array] | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:53:21:53:28 | arrayLit | SanitizingDoubleDash.go:53:14:53:35 | call to append | provenance | MaD:4 | +| SanitizingDoubleDash.go:53:21:53:28 | arrayLit | SanitizingDoubleDash.go:53:14:53:35 | call to append | provenance | MaD:3 | +| SanitizingDoubleDash.go:53:21:53:28 | arrayLit | SanitizingDoubleDash.go:53:14:53:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | SanitizingDoubleDash.go:53:14:53:35 | call to append | provenance | MaD:3 | | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | SanitizingDoubleDash.go:53:14:53:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:68:14:68:38 | []type{args} [array] | SanitizingDoubleDash.go:68:14:68:38 | call to append | provenance | MaD:5 | @@ -80,12 +83,16 @@ edges | SanitizingDoubleDash.go:69:14:69:35 | call to append | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:69:14:69:35 | call to append [array] | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:69:21:69:28 | arrayLit | SanitizingDoubleDash.go:69:14:69:35 | call to append | provenance | MaD:4 | +| SanitizingDoubleDash.go:69:21:69:28 | arrayLit | SanitizingDoubleDash.go:69:14:69:35 | call to append | provenance | MaD:3 | +| SanitizingDoubleDash.go:69:21:69:28 | arrayLit | SanitizingDoubleDash.go:69:14:69:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:69:21:69:28 | arrayLit [array] | SanitizingDoubleDash.go:69:14:69:35 | call to append | provenance | MaD:3 | | SanitizingDoubleDash.go:69:21:69:28 | arrayLit [array] | SanitizingDoubleDash.go:69:14:69:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:92:13:92:27 | call to Query | provenance | Src:MaD:2 MaD:7 | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:95:25:95:31 | tainted | provenance | | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:96:24:96:34 | slice element node | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:96:24:96:34 | slice expression | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:100:31:100:37 | tainted | provenance | | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:101:24:101:34 | slice element node | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:101:24:101:34 | slice expression | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:105:30:105:36 | tainted | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | provenance | | @@ -128,6 +135,8 @@ edges | SanitizingDoubleDash.go:129:14:129:35 | call to append | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:129:14:129:35 | call to append [array] | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:129:21:129:28 | arrayLit | SanitizingDoubleDash.go:129:14:129:35 | call to append | provenance | MaD:4 | +| SanitizingDoubleDash.go:129:21:129:28 | arrayLit | SanitizingDoubleDash.go:129:14:129:35 | call to append | provenance | MaD:3 | +| SanitizingDoubleDash.go:129:21:129:28 | arrayLit | SanitizingDoubleDash.go:129:14:129:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:129:21:129:28 | arrayLit [array] | SanitizingDoubleDash.go:129:14:129:35 | call to append | provenance | MaD:3 | | SanitizingDoubleDash.go:129:21:129:28 | arrayLit [array] | SanitizingDoubleDash.go:129:14:129:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:136:14:136:38 | []type{args} [array] | SanitizingDoubleDash.go:136:14:136:38 | call to append | provenance | MaD:5 | @@ -143,6 +152,8 @@ edges | SanitizingDoubleDash.go:143:14:143:35 | call to append | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:143:14:143:35 | call to append [array] | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:143:21:143:28 | arrayLit | SanitizingDoubleDash.go:143:14:143:35 | call to append | provenance | MaD:4 | +| SanitizingDoubleDash.go:143:21:143:28 | arrayLit | SanitizingDoubleDash.go:143:14:143:35 | call to append | provenance | MaD:3 | +| SanitizingDoubleDash.go:143:21:143:28 | arrayLit | SanitizingDoubleDash.go:143:14:143:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:143:21:143:28 | arrayLit [array] | SanitizingDoubleDash.go:143:14:143:35 | call to append | provenance | MaD:3 | | SanitizingDoubleDash.go:143:21:143:28 | arrayLit [array] | SanitizingDoubleDash.go:143:14:143:35 | call to append [array] | provenance | MaD:3 | models diff --git a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index b3396e7451b5..a43ea9310874 100644 --- a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,16 +1,29 @@ edges +| test.go:14:2:14:4 | definition of buf | test.go:15:8:15:37 | slice element node | provenance | | | test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | provenance | | | test.go:14:2:14:4 | definition of buf | test.go:20:29:20:31 | buf | provenance | | | test.go:15:2:15:4 | definition of buf | test.go:17:10:17:12 | buf | provenance | | | test.go:15:2:15:4 | definition of buf | test.go:20:29:20:31 | buf | provenance | | +| test.go:15:2:15:4 | definition of buf [array] | test.go:17:10:17:12 | buf | provenance | | +| test.go:15:2:15:4 | definition of buf [array] | test.go:20:29:20:31 | buf [array] | provenance | | +| test.go:15:8:15:37 | slice element node | test.go:15:8:15:37 | slice expression [array] | provenance | | +| test.go:15:8:15:37 | slice expression [array] | test.go:17:10:17:12 | buf | provenance | | +| test.go:15:8:15:37 | slice expression [array] | test.go:20:29:20:31 | buf [array] | provenance | | +| test.go:20:2:20:32 | []type{args} [array, array] | test.go:15:2:15:4 | definition of buf [array] | provenance | | | test.go:20:2:20:32 | []type{args} [array] | test.go:15:2:15:4 | definition of buf | provenance | | | test.go:20:29:20:31 | buf | test.go:20:2:20:32 | []type{args} [array] | provenance | | +| test.go:20:29:20:31 | buf [array] | test.go:20:2:20:32 | []type{args} [array, array] | provenance | | nodes | test.go:14:2:14:4 | definition of buf | semmle.label | definition of buf | | test.go:15:2:15:4 | definition of buf | semmle.label | definition of buf | +| test.go:15:2:15:4 | definition of buf [array] | semmle.label | definition of buf [array] | +| test.go:15:8:15:37 | slice element node | semmle.label | slice element node | +| test.go:15:8:15:37 | slice expression [array] | semmle.label | slice expression [array] | | test.go:17:10:17:12 | buf | semmle.label | buf | +| test.go:20:2:20:32 | []type{args} [array, array] | semmle.label | []type{args} [array, array] | | test.go:20:2:20:32 | []type{args} [array] | semmle.label | []type{args} [array] | | test.go:20:29:20:31 | buf | semmle.label | buf | +| test.go:20:29:20:31 | buf [array] | semmle.label | buf [array] | subpaths #select | test.go:17:10:17:12 | buf | test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | HTTP response depends on $@ and may be exposed to an external user. | test.go:14:2:14:4 | definition of buf | stack trace information | diff --git a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 31f709e456f2..98c98dbf331f 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -66,15 +66,13 @@ edges | passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | provenance | Config | | passwords.go:36:2:36:5 | definition of obj1 | passwords.go:39:14:39:17 | obj1 | provenance | | | passwords.go:36:2:36:5 | definition of obj1 | passwords.go:39:14:39:17 | obj1 | provenance | | -| passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | | -| passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | | +| passwords.go:36:10:38:2 | struct literal | passwords.go:36:2:36:5 | definition of obj1 | provenance | | | passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal | provenance | Config | | passwords.go:39:2:39:18 | []type{args} [array] | passwords.go:36:2:36:5 | definition of obj1 | provenance | | | passwords.go:39:14:39:17 | obj1 | passwords.go:39:2:39:18 | []type{args} [array] | provenance | | | passwords.go:41:2:41:5 | definition of obj2 | passwords.go:44:14:44:17 | obj2 | provenance | | | passwords.go:41:2:41:5 | definition of obj2 | passwords.go:44:14:44:17 | obj2 | provenance | | -| passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | | -| passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | | +| passwords.go:41:10:43:2 | struct literal | passwords.go:41:2:41:5 | definition of obj2 | provenance | | | passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal | provenance | Config | | passwords.go:44:2:44:18 | []type{args} [array] | passwords.go:41:2:41:5 | definition of obj2 | provenance | | | passwords.go:44:14:44:17 | obj2 | passwords.go:44:2:44:18 | []type{args} [array] | provenance | | @@ -85,8 +83,7 @@ edges | passwords.go:48:11:48:18 | password | passwords.go:46:6:46:9 | definition of obj3 | provenance | Config | | passwords.go:85:2:85:14 | definition of utilityObject | passwords.go:88:14:88:26 | utilityObject | provenance | | | passwords.go:85:2:85:14 | definition of utilityObject | passwords.go:88:14:88:26 | utilityObject | provenance | | -| passwords.go:85:19:87:2 | struct literal | passwords.go:88:14:88:26 | utilityObject | provenance | | -| passwords.go:85:19:87:2 | struct literal | passwords.go:88:14:88:26 | utilityObject | provenance | | +| passwords.go:85:19:87:2 | struct literal | passwords.go:85:2:85:14 | definition of utilityObject | provenance | | | passwords.go:86:16:86:36 | call to make | passwords.go:85:19:87:2 | struct literal | provenance | Config | | passwords.go:88:2:88:27 | []type{args} [array] | passwords.go:85:2:85:14 | definition of utilityObject | provenance | | | passwords.go:88:14:88:26 | utilityObject | passwords.go:88:2:88:27 | []type{args} [array] | provenance | | @@ -102,12 +99,9 @@ edges | passwords.go:118:2:118:7 | definition of config [x] | passwords.go:126:14:126:19 | config [x] | provenance | | | passwords.go:118:2:118:7 | definition of config [y] | passwords.go:125:14:125:19 | config [y] | provenance | | | passwords.go:118:2:118:7 | definition of config [y] | passwords.go:127:14:127:19 | config [y] | provenance | | -| passwords.go:118:12:123:2 | struct literal | passwords.go:125:14:125:19 | config | provenance | | -| passwords.go:118:12:123:2 | struct literal | passwords.go:125:14:125:19 | config | provenance | | -| passwords.go:118:12:123:2 | struct literal [x] | passwords.go:125:14:125:19 | config [x] | provenance | | -| passwords.go:118:12:123:2 | struct literal [x] | passwords.go:126:14:126:19 | config [x] | provenance | | -| passwords.go:118:12:123:2 | struct literal [y] | passwords.go:125:14:125:19 | config [y] | provenance | | -| passwords.go:118:12:123:2 | struct literal [y] | passwords.go:127:14:127:19 | config [y] | provenance | | +| passwords.go:118:12:123:2 | struct literal | passwords.go:118:2:118:7 | definition of config | provenance | | +| passwords.go:118:12:123:2 | struct literal [x] | passwords.go:118:2:118:7 | definition of config [x] | provenance | | +| passwords.go:118:12:123:2 | struct literal [y] | passwords.go:118:2:118:7 | definition of config [y] | provenance | | | passwords.go:119:13:119:13 | x | passwords.go:118:12:123:2 | struct literal | provenance | Config | | passwords.go:121:13:121:20 | password | passwords.go:118:12:123:2 | struct literal | provenance | Config | | passwords.go:121:13:121:20 | password | passwords.go:118:12:123:2 | struct literal [x] | provenance | | diff --git a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected index 539e1070af88..27629c870e45 100644 --- a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected +++ b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected @@ -60,6 +60,8 @@ edges | UnsafeTLS.go:344:19:344:44 | call to append | UnsafeTLS.go:346:25:346:36 | cipherSuites | provenance | | | UnsafeTLS.go:344:19:344:44 | call to append [array] | UnsafeTLS.go:344:26:344:37 | cipherSuites [array] | provenance | | | UnsafeTLS.go:344:26:344:37 | cipherSuites | UnsafeTLS.go:344:19:344:44 | call to append | provenance | MaD:2 | +| UnsafeTLS.go:344:26:344:37 | cipherSuites | UnsafeTLS.go:344:19:344:44 | call to append | provenance | MaD:1 | +| UnsafeTLS.go:344:26:344:37 | cipherSuites | UnsafeTLS.go:344:19:344:44 | call to append [array] | provenance | MaD:1 | | UnsafeTLS.go:344:26:344:37 | cipherSuites [array] | UnsafeTLS.go:344:19:344:44 | call to append | provenance | MaD:1 | | UnsafeTLS.go:344:26:344:37 | cipherSuites [array] | UnsafeTLS.go:344:19:344:44 | call to append [array] | provenance | MaD:1 | | UnsafeTLS.go:344:40:344:43 | selection of ID | UnsafeTLS.go:344:19:344:44 | []type{args} [array] | provenance | | @@ -70,6 +72,8 @@ edges | UnsafeTLS.go:353:19:353:52 | call to append | UnsafeTLS.go:355:25:355:36 | cipherSuites | provenance | | | UnsafeTLS.go:353:19:353:52 | call to append [array] | UnsafeTLS.go:353:26:353:37 | cipherSuites [array] | provenance | | | UnsafeTLS.go:353:26:353:37 | cipherSuites | UnsafeTLS.go:353:19:353:52 | call to append | provenance | MaD:2 | +| UnsafeTLS.go:353:26:353:37 | cipherSuites | UnsafeTLS.go:353:19:353:52 | call to append | provenance | MaD:1 | +| UnsafeTLS.go:353:26:353:37 | cipherSuites | UnsafeTLS.go:353:19:353:52 | call to append [array] | provenance | MaD:1 | | UnsafeTLS.go:353:26:353:37 | cipherSuites [array] | UnsafeTLS.go:353:19:353:52 | call to append | provenance | MaD:1 | | UnsafeTLS.go:353:26:353:37 | cipherSuites [array] | UnsafeTLS.go:353:19:353:52 | call to append [array] | provenance | MaD:1 | | UnsafeTLS.go:353:40:353:51 | selection of ID | UnsafeTLS.go:353:19:353:52 | []type{args} [array] | provenance | | diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected index b2659fffde78..7ce564fd97fb 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected @@ -6,13 +6,16 @@ | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | sample.go:43:17:43:39 | call to Intn | random number | | sample.go:58:32:58:43 | type conversion | sample.go:55:17:55:42 | call to Intn | sample.go:58:32:58:43 | type conversion | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:55:17:55:42 | call to Intn | random number | edges +| sample.go:15:10:15:64 | call to Sum256 | sample.go:16:9:16:15 | slice element node | provenance | | | sample.go:15:10:15:64 | call to Sum256 | sample.go:16:9:16:15 | slice expression | provenance | | | sample.go:15:24:15:63 | type conversion | sample.go:15:10:15:64 | call to Sum256 | provenance | FunctionModel | | sample.go:15:31:15:62 | []type{args} [array] | sample.go:15:31:15:62 | call to Sprintf | provenance | MaD:1 | | sample.go:15:31:15:62 | call to Sprintf | sample.go:15:24:15:63 | type conversion | provenance | | | sample.go:15:49:15:61 | call to Uint32 | sample.go:15:31:15:62 | []type{args} [array] | provenance | | | sample.go:15:49:15:61 | call to Uint32 | sample.go:15:31:15:62 | call to Sprintf | provenance | FunctionModel | +| sample.go:16:9:16:15 | slice element node | sample.go:16:9:16:15 | slice expression [array] | provenance | | | sample.go:16:9:16:15 | slice expression | sample.go:26:25:26:30 | call to Guid | provenance | | +| sample.go:16:9:16:15 | slice expression [array] | sample.go:26:25:26:30 | call to Guid | provenance | | | sample.go:33:2:33:6 | definition of nonce | sample.go:37:25:37:29 | nonce | provenance | | | sample.go:33:2:33:6 | definition of nonce | sample.go:37:32:37:36 | nonce | provenance | | | sample.go:34:12:34:40 | call to New | sample.go:35:14:35:19 | random | provenance | | @@ -31,7 +34,9 @@ nodes | sample.go:15:31:15:62 | []type{args} [array] | semmle.label | []type{args} [array] | | sample.go:15:31:15:62 | call to Sprintf | semmle.label | call to Sprintf | | sample.go:15:49:15:61 | call to Uint32 | semmle.label | call to Uint32 | +| sample.go:16:9:16:15 | slice element node | semmle.label | slice element node | | sample.go:16:9:16:15 | slice expression | semmle.label | slice expression | +| sample.go:16:9:16:15 | slice expression [array] | semmle.label | slice expression [array] | | sample.go:26:25:26:30 | call to Guid | semmle.label | call to Guid | | sample.go:33:2:33:6 | definition of nonce | semmle.label | definition of nonce | | sample.go:34:12:34:40 | call to New | semmle.label | call to New | From 26b52078c07672ce21bb529d8833b120a21ba70c Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Dec 2024 13:41:35 +0000 Subject: [PATCH 3/6] Add change note --- .../lib/change-notes/2024-12-12-variadic-parameter-sources.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/lib/change-notes/2024-12-12-variadic-parameter-sources.md diff --git a/go/ql/lib/change-notes/2024-12-12-variadic-parameter-sources.md b/go/ql/lib/change-notes/2024-12-12-variadic-parameter-sources.md new file mode 100644 index 000000000000..38d5ad2783f1 --- /dev/null +++ b/go/ql/lib/change-notes/2024-12-12-variadic-parameter-sources.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Source models defined using models-as-data now work for variadic parameters. From b58e6ebade20f51375c6c992a85ba0ec45755ec5 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 12 Dec 2024 21:53:27 +0000 Subject: [PATCH 4/6] Address review comments for localTaintStep --- go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index c6c9f933707c..7cdd4924ac5c 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -37,7 +37,8 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) { or // Treat container flow as taint for the local taint flow relation exists(DataFlow::Content c | DataFlowPrivate::containerContent(c) | - DataFlowPrivate::readStep(src, c, sink) or + // `DataFlowPrivate::readStep` has already been included in + // `localAdditionalTaintStep`. DataFlowPrivate::storeStep(src, c, sink) or FlowSummaryImpl::Private::Steps::summaryGetterStep(src, c, sink, _) or FlowSummaryImpl::Private::Steps::summarySetterStep(src, c, sink, _) @@ -112,7 +113,7 @@ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ, str or sliceStep(pred, succ) or - // Treat container flow as taint for the local taint flow relation + // Treat container read steps as taint for global taint flow. exists(DataFlow::Content c | DataFlowPrivate::containerContent(c) | DataFlowPrivate::readStep(pred, c, succ) ) From 3a3e053f121671b2001487c2f3c8aa6b0524d9ee Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 13 Dec 2024 13:07:31 +0000 Subject: [PATCH 5/6] Only add taint steps for implicit varargs slice post-update nodes --- .../go/dataflow/internal/TaintTrackingUtil.qll | 11 ++++++----- .../experimental/CWE-74/DsnInjectionLocal.expected | 7 ------- .../go/dataflow/FlowSteps/LocalTaintStep.expected | 1 - .../Security/CWE-078/CommandInjection.expected | 11 ----------- .../Security/CWE-209/StackTraceExposure.expected | 13 ------------- .../query-tests/Security/CWE-327/UnsafeTLS.expected | 4 ---- .../InsecureRandomness/InsecureRandomness.expected | 5 ----- 7 files changed, 6 insertions(+), 46 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 7cdd4924ac5c..c20c78d20483 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -112,11 +112,6 @@ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ, str stringConcatStep(pred, succ) or sliceStep(pred, succ) - or - // Treat container read steps as taint for global taint flow. - exists(DataFlow::Content c | DataFlowPrivate::containerContent(c) | - DataFlowPrivate::readStep(pred, c, succ) - ) ) and model = "" or @@ -185,6 +180,12 @@ predicate elementStep(DataFlow::Node pred, DataFlow::Node succ) { // only step into the value, not the index succ.asInstruction() = IR::extractTupleElement(nextEntry, 1) ) + or + exists(DataFlow::ImplicitVarargsSlice ivs | + pred.(DataFlow::PostUpdateNode).getPreUpdateNode() = ivs and + succ.(DataFlow::PostUpdateNode).getPreUpdateNode() = + ivs.getCallNode().getAnImplicitVarargsArgument() + ) } /** Holds if taint flows from `pred` to `succ` via an extract tuple operation. */ diff --git a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected index e18bdf1c8c4f..ff83f06ebb28 100644 --- a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected +++ b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected @@ -2,13 +2,9 @@ | Dsn.go:29:29:29:33 | dbDSN | Dsn.go:26:11:26:17 | selection of Args | Dsn.go:29:29:29:33 | dbDSN | This query depends on a $@. | Dsn.go:26:11:26:17 | selection of Args | user-provided value | | Dsn.go:68:29:68:33 | dbDSN | Dsn.go:63:19:63:25 | selection of Args | Dsn.go:68:29:68:33 | dbDSN | This query depends on a $@. | Dsn.go:63:19:63:25 | selection of Args | user-provided value | edges -| Dsn.go:26:11:26:17 | selection of Args | Dsn.go:26:11:26:21 | slice element node | provenance | | | Dsn.go:26:11:26:17 | selection of Args | Dsn.go:28:102:28:109 | index expression | provenance | | -| Dsn.go:26:11:26:21 | slice element node | Dsn.go:26:11:26:21 | slice expression [array] | provenance | | -| Dsn.go:26:11:26:21 | slice expression [array] | Dsn.go:28:102:28:106 | name2 [array] | provenance | | | Dsn.go:28:11:28:110 | []type{args} [array] | Dsn.go:28:11:28:110 | call to Sprintf | provenance | MaD:1 | | Dsn.go:28:11:28:110 | call to Sprintf | Dsn.go:29:29:29:33 | dbDSN | provenance | | -| Dsn.go:28:102:28:106 | name2 [array] | Dsn.go:28:102:28:109 | index expression | provenance | | | Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | []type{args} [array] | provenance | | | Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | call to Sprintf | provenance | FunctionModel | | Dsn.go:62:2:62:4 | definition of cfg [pointer] | Dsn.go:63:9:63:11 | cfg [pointer] | provenance | | @@ -29,11 +25,8 @@ models | 1 | Summary: fmt; ; false; Sprintf; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual | nodes | Dsn.go:26:11:26:17 | selection of Args | semmle.label | selection of Args | -| Dsn.go:26:11:26:21 | slice element node | semmle.label | slice element node | -| Dsn.go:26:11:26:21 | slice expression [array] | semmle.label | slice expression [array] | | Dsn.go:28:11:28:110 | []type{args} [array] | semmle.label | []type{args} [array] | | Dsn.go:28:11:28:110 | call to Sprintf | semmle.label | call to Sprintf | -| Dsn.go:28:102:28:106 | name2 [array] | semmle.label | name2 [array] | | Dsn.go:28:102:28:109 | index expression | semmle.label | index expression | | Dsn.go:29:29:29:33 | dbDSN | semmle.label | dbDSN | | Dsn.go:62:2:62:4 | definition of cfg [pointer] | semmle.label | definition of cfg [pointer] | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected index abe37122ba6b..8aaf3c4d7f3c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected @@ -15,7 +15,6 @@ | main.go:47:20:47:21 | next key-value pair in range | main.go:47:2:50:2 | range statement[1] | | main.go:47:20:47:21 | xs | main.go:47:2:50:2 | range statement[1] | | main.go:56:8:56:11 | true | main.go:56:2:56:3 | ch | -| main.go:57:4:57:5 | ch | main.go:57:2:57:5 | <-... | | strings.go:9:24:9:24 | s | strings.go:9:8:9:38 | call to Replace | | strings.go:9:32:9:34 | "_" | strings.go:9:8:9:38 | call to Replace | | strings.go:10:27:10:27 | s | strings.go:10:8:10:42 | call to ReplaceAll | diff --git a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index 7642f44856ba..dff32df4e1ff 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -50,7 +50,6 @@ edges | GitSubcommands.go:33:13:33:27 | call to Query | GitSubcommands.go:38:32:38:38 | tainted | provenance | | | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:9:13:9:27 | call to Query | provenance | Src:MaD:2 MaD:7 | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:13:25:13:31 | tainted | provenance | | -| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:14:23:14:33 | slice element node | provenance | | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:39:31:39:37 | tainted | provenance | | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:52:24:52:30 | tainted | provenance | | @@ -71,8 +70,6 @@ edges | SanitizingDoubleDash.go:53:14:53:35 | call to append | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:53:14:53:35 | call to append [array] | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:53:21:53:28 | arrayLit | SanitizingDoubleDash.go:53:14:53:35 | call to append | provenance | MaD:4 | -| SanitizingDoubleDash.go:53:21:53:28 | arrayLit | SanitizingDoubleDash.go:53:14:53:35 | call to append | provenance | MaD:3 | -| SanitizingDoubleDash.go:53:21:53:28 | arrayLit | SanitizingDoubleDash.go:53:14:53:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | SanitizingDoubleDash.go:53:14:53:35 | call to append | provenance | MaD:3 | | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | SanitizingDoubleDash.go:53:14:53:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:68:14:68:38 | []type{args} [array] | SanitizingDoubleDash.go:68:14:68:38 | call to append | provenance | MaD:5 | @@ -83,16 +80,12 @@ edges | SanitizingDoubleDash.go:69:14:69:35 | call to append | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:69:14:69:35 | call to append [array] | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:69:21:69:28 | arrayLit | SanitizingDoubleDash.go:69:14:69:35 | call to append | provenance | MaD:4 | -| SanitizingDoubleDash.go:69:21:69:28 | arrayLit | SanitizingDoubleDash.go:69:14:69:35 | call to append | provenance | MaD:3 | -| SanitizingDoubleDash.go:69:21:69:28 | arrayLit | SanitizingDoubleDash.go:69:14:69:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:69:21:69:28 | arrayLit [array] | SanitizingDoubleDash.go:69:14:69:35 | call to append | provenance | MaD:3 | | SanitizingDoubleDash.go:69:21:69:28 | arrayLit [array] | SanitizingDoubleDash.go:69:14:69:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:92:13:92:27 | call to Query | provenance | Src:MaD:2 MaD:7 | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:95:25:95:31 | tainted | provenance | | -| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:96:24:96:34 | slice element node | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:96:24:96:34 | slice expression | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:100:31:100:37 | tainted | provenance | | -| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:101:24:101:34 | slice element node | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:101:24:101:34 | slice expression | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:105:30:105:36 | tainted | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | provenance | | @@ -135,8 +128,6 @@ edges | SanitizingDoubleDash.go:129:14:129:35 | call to append | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:129:14:129:35 | call to append [array] | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:129:21:129:28 | arrayLit | SanitizingDoubleDash.go:129:14:129:35 | call to append | provenance | MaD:4 | -| SanitizingDoubleDash.go:129:21:129:28 | arrayLit | SanitizingDoubleDash.go:129:14:129:35 | call to append | provenance | MaD:3 | -| SanitizingDoubleDash.go:129:21:129:28 | arrayLit | SanitizingDoubleDash.go:129:14:129:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:129:21:129:28 | arrayLit [array] | SanitizingDoubleDash.go:129:14:129:35 | call to append | provenance | MaD:3 | | SanitizingDoubleDash.go:129:21:129:28 | arrayLit [array] | SanitizingDoubleDash.go:129:14:129:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:136:14:136:38 | []type{args} [array] | SanitizingDoubleDash.go:136:14:136:38 | call to append | provenance | MaD:5 | @@ -152,8 +143,6 @@ edges | SanitizingDoubleDash.go:143:14:143:35 | call to append | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:143:14:143:35 | call to append [array] | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:143:21:143:28 | arrayLit | SanitizingDoubleDash.go:143:14:143:35 | call to append | provenance | MaD:4 | -| SanitizingDoubleDash.go:143:21:143:28 | arrayLit | SanitizingDoubleDash.go:143:14:143:35 | call to append | provenance | MaD:3 | -| SanitizingDoubleDash.go:143:21:143:28 | arrayLit | SanitizingDoubleDash.go:143:14:143:35 | call to append [array] | provenance | MaD:3 | | SanitizingDoubleDash.go:143:21:143:28 | arrayLit [array] | SanitizingDoubleDash.go:143:14:143:35 | call to append | provenance | MaD:3 | | SanitizingDoubleDash.go:143:21:143:28 | arrayLit [array] | SanitizingDoubleDash.go:143:14:143:35 | call to append [array] | provenance | MaD:3 | models diff --git a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index a43ea9310874..b3396e7451b5 100644 --- a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,29 +1,16 @@ edges -| test.go:14:2:14:4 | definition of buf | test.go:15:8:15:37 | slice element node | provenance | | | test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | provenance | | | test.go:14:2:14:4 | definition of buf | test.go:20:29:20:31 | buf | provenance | | | test.go:15:2:15:4 | definition of buf | test.go:17:10:17:12 | buf | provenance | | | test.go:15:2:15:4 | definition of buf | test.go:20:29:20:31 | buf | provenance | | -| test.go:15:2:15:4 | definition of buf [array] | test.go:17:10:17:12 | buf | provenance | | -| test.go:15:2:15:4 | definition of buf [array] | test.go:20:29:20:31 | buf [array] | provenance | | -| test.go:15:8:15:37 | slice element node | test.go:15:8:15:37 | slice expression [array] | provenance | | -| test.go:15:8:15:37 | slice expression [array] | test.go:17:10:17:12 | buf | provenance | | -| test.go:15:8:15:37 | slice expression [array] | test.go:20:29:20:31 | buf [array] | provenance | | -| test.go:20:2:20:32 | []type{args} [array, array] | test.go:15:2:15:4 | definition of buf [array] | provenance | | | test.go:20:2:20:32 | []type{args} [array] | test.go:15:2:15:4 | definition of buf | provenance | | | test.go:20:29:20:31 | buf | test.go:20:2:20:32 | []type{args} [array] | provenance | | -| test.go:20:29:20:31 | buf [array] | test.go:20:2:20:32 | []type{args} [array, array] | provenance | | nodes | test.go:14:2:14:4 | definition of buf | semmle.label | definition of buf | | test.go:15:2:15:4 | definition of buf | semmle.label | definition of buf | -| test.go:15:2:15:4 | definition of buf [array] | semmle.label | definition of buf [array] | -| test.go:15:8:15:37 | slice element node | semmle.label | slice element node | -| test.go:15:8:15:37 | slice expression [array] | semmle.label | slice expression [array] | | test.go:17:10:17:12 | buf | semmle.label | buf | -| test.go:20:2:20:32 | []type{args} [array, array] | semmle.label | []type{args} [array, array] | | test.go:20:2:20:32 | []type{args} [array] | semmle.label | []type{args} [array] | | test.go:20:29:20:31 | buf | semmle.label | buf | -| test.go:20:29:20:31 | buf [array] | semmle.label | buf [array] | subpaths #select | test.go:17:10:17:12 | buf | test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | HTTP response depends on $@ and may be exposed to an external user. | test.go:14:2:14:4 | definition of buf | stack trace information | diff --git a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected index 27629c870e45..539e1070af88 100644 --- a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected +++ b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected @@ -60,8 +60,6 @@ edges | UnsafeTLS.go:344:19:344:44 | call to append | UnsafeTLS.go:346:25:346:36 | cipherSuites | provenance | | | UnsafeTLS.go:344:19:344:44 | call to append [array] | UnsafeTLS.go:344:26:344:37 | cipherSuites [array] | provenance | | | UnsafeTLS.go:344:26:344:37 | cipherSuites | UnsafeTLS.go:344:19:344:44 | call to append | provenance | MaD:2 | -| UnsafeTLS.go:344:26:344:37 | cipherSuites | UnsafeTLS.go:344:19:344:44 | call to append | provenance | MaD:1 | -| UnsafeTLS.go:344:26:344:37 | cipherSuites | UnsafeTLS.go:344:19:344:44 | call to append [array] | provenance | MaD:1 | | UnsafeTLS.go:344:26:344:37 | cipherSuites [array] | UnsafeTLS.go:344:19:344:44 | call to append | provenance | MaD:1 | | UnsafeTLS.go:344:26:344:37 | cipherSuites [array] | UnsafeTLS.go:344:19:344:44 | call to append [array] | provenance | MaD:1 | | UnsafeTLS.go:344:40:344:43 | selection of ID | UnsafeTLS.go:344:19:344:44 | []type{args} [array] | provenance | | @@ -72,8 +70,6 @@ edges | UnsafeTLS.go:353:19:353:52 | call to append | UnsafeTLS.go:355:25:355:36 | cipherSuites | provenance | | | UnsafeTLS.go:353:19:353:52 | call to append [array] | UnsafeTLS.go:353:26:353:37 | cipherSuites [array] | provenance | | | UnsafeTLS.go:353:26:353:37 | cipherSuites | UnsafeTLS.go:353:19:353:52 | call to append | provenance | MaD:2 | -| UnsafeTLS.go:353:26:353:37 | cipherSuites | UnsafeTLS.go:353:19:353:52 | call to append | provenance | MaD:1 | -| UnsafeTLS.go:353:26:353:37 | cipherSuites | UnsafeTLS.go:353:19:353:52 | call to append [array] | provenance | MaD:1 | | UnsafeTLS.go:353:26:353:37 | cipherSuites [array] | UnsafeTLS.go:353:19:353:52 | call to append | provenance | MaD:1 | | UnsafeTLS.go:353:26:353:37 | cipherSuites [array] | UnsafeTLS.go:353:19:353:52 | call to append [array] | provenance | MaD:1 | | UnsafeTLS.go:353:40:353:51 | selection of ID | UnsafeTLS.go:353:19:353:52 | []type{args} [array] | provenance | | diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected index 7ce564fd97fb..b2659fffde78 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected @@ -6,16 +6,13 @@ | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | sample.go:43:17:43:39 | call to Intn | random number | | sample.go:58:32:58:43 | type conversion | sample.go:55:17:55:42 | call to Intn | sample.go:58:32:58:43 | type conversion | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:55:17:55:42 | call to Intn | random number | edges -| sample.go:15:10:15:64 | call to Sum256 | sample.go:16:9:16:15 | slice element node | provenance | | | sample.go:15:10:15:64 | call to Sum256 | sample.go:16:9:16:15 | slice expression | provenance | | | sample.go:15:24:15:63 | type conversion | sample.go:15:10:15:64 | call to Sum256 | provenance | FunctionModel | | sample.go:15:31:15:62 | []type{args} [array] | sample.go:15:31:15:62 | call to Sprintf | provenance | MaD:1 | | sample.go:15:31:15:62 | call to Sprintf | sample.go:15:24:15:63 | type conversion | provenance | | | sample.go:15:49:15:61 | call to Uint32 | sample.go:15:31:15:62 | []type{args} [array] | provenance | | | sample.go:15:49:15:61 | call to Uint32 | sample.go:15:31:15:62 | call to Sprintf | provenance | FunctionModel | -| sample.go:16:9:16:15 | slice element node | sample.go:16:9:16:15 | slice expression [array] | provenance | | | sample.go:16:9:16:15 | slice expression | sample.go:26:25:26:30 | call to Guid | provenance | | -| sample.go:16:9:16:15 | slice expression [array] | sample.go:26:25:26:30 | call to Guid | provenance | | | sample.go:33:2:33:6 | definition of nonce | sample.go:37:25:37:29 | nonce | provenance | | | sample.go:33:2:33:6 | definition of nonce | sample.go:37:32:37:36 | nonce | provenance | | | sample.go:34:12:34:40 | call to New | sample.go:35:14:35:19 | random | provenance | | @@ -34,9 +31,7 @@ nodes | sample.go:15:31:15:62 | []type{args} [array] | semmle.label | []type{args} [array] | | sample.go:15:31:15:62 | call to Sprintf | semmle.label | call to Sprintf | | sample.go:15:49:15:61 | call to Uint32 | semmle.label | call to Uint32 | -| sample.go:16:9:16:15 | slice element node | semmle.label | slice element node | | sample.go:16:9:16:15 | slice expression | semmle.label | slice expression | -| sample.go:16:9:16:15 | slice expression [array] | semmle.label | slice expression [array] | | sample.go:26:25:26:30 | call to Guid | semmle.label | call to Guid | | sample.go:33:2:33:6 | definition of nonce | semmle.label | definition of nonce | | sample.go:34:12:34:40 | call to New | semmle.label | call to New | From e9dcd69cc091ca224dd70b68324d466087e4a2f7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 13 Dec 2024 13:30:18 +0000 Subject: [PATCH 6/6] Add readStep back to local taint flow --- go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll | 3 +-- .../semmle/go/dataflow/FlowSteps/LocalTaintStep.expected | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index c20c78d20483..2605dd326c3c 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -37,8 +37,7 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) { or // Treat container flow as taint for the local taint flow relation exists(DataFlow::Content c | DataFlowPrivate::containerContent(c) | - // `DataFlowPrivate::readStep` has already been included in - // `localAdditionalTaintStep`. + DataFlowPrivate::readStep(src, c, sink) or DataFlowPrivate::storeStep(src, c, sink) or FlowSummaryImpl::Private::Steps::summaryGetterStep(src, c, sink, _) or FlowSummaryImpl::Private::Steps::summarySetterStep(src, c, sink, _) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected index 8aaf3c4d7f3c..abe37122ba6b 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected @@ -15,6 +15,7 @@ | main.go:47:20:47:21 | next key-value pair in range | main.go:47:2:50:2 | range statement[1] | | main.go:47:20:47:21 | xs | main.go:47:2:50:2 | range statement[1] | | main.go:56:8:56:11 | true | main.go:56:2:56:3 | ch | +| main.go:57:4:57:5 | ch | main.go:57:2:57:5 | <-... | | strings.go:9:24:9:24 | s | strings.go:9:8:9:38 | call to Replace | | strings.go:9:32:9:34 | "_" | strings.go:9:8:9:38 | call to Replace | | strings.go:10:27:10:27 | s | strings.go:10:8:10:42 | call to ReplaceAll |