From 0728692e93f26b9d43ac05c0bd51a067a17d1163 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 29 Sep 2025 14:23:16 +0200 Subject: [PATCH 01/70] Rust: Add tests for functions as lambdas --- .../dataflow/closures/inline-flow.expected | 50 ------------------- .../dataflow/{closures => lambdas}/Cargo.lock | 0 .../dataflow/lambdas/inline-flow.expected | 50 +++++++++++++++++++ .../{closures => lambdas}/inline-flow.ql | 0 .../dataflow/{closures => lambdas}/main.rs | 50 +++++++++++++++---- 5 files changed, 91 insertions(+), 59 deletions(-) delete mode 100644 rust/ql/test/library-tests/dataflow/closures/inline-flow.expected rename rust/ql/test/library-tests/dataflow/{closures => lambdas}/Cargo.lock (100%) create mode 100644 rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected rename rust/ql/test/library-tests/dataflow/{closures => lambdas}/inline-flow.ql (100%) rename rust/ql/test/library-tests/dataflow/{closures => lambdas}/main.rs (53%) diff --git a/rust/ql/test/library-tests/dataflow/closures/inline-flow.expected b/rust/ql/test/library-tests/dataflow/closures/inline-flow.expected deleted file mode 100644 index a2cee10f246..00000000000 --- a/rust/ql/test/library-tests/dataflow/closures/inline-flow.expected +++ /dev/null @@ -1,50 +0,0 @@ -models -edges -| main.rs:11:20:11:52 | if cond {...} else {...} | main.rs:12:10:12:16 | f(...) | provenance | | -| main.rs:11:30:11:39 | source(...) | main.rs:11:20:11:52 | if cond {...} else {...} | provenance | | -| main.rs:16:20:16:23 | ... | main.rs:18:18:18:21 | data | provenance | | -| main.rs:22:9:22:9 | a | main.rs:23:13:23:13 | a | provenance | | -| main.rs:22:13:22:22 | source(...) | main.rs:22:9:22:9 | a | provenance | | -| main.rs:23:13:23:13 | a | main.rs:16:20:16:23 | ... | provenance | | -| main.rs:27:20:27:23 | ... | main.rs:28:9:32:9 | if cond {...} else {...} | provenance | | -| main.rs:33:9:33:9 | a | main.rs:34:21:34:21 | a | provenance | | -| main.rs:33:13:33:22 | source(...) | main.rs:33:9:33:9 | a | provenance | | -| main.rs:34:9:34:9 | b | main.rs:35:10:35:10 | b | provenance | | -| main.rs:34:13:34:22 | f(...) | main.rs:34:9:34:9 | b | provenance | | -| main.rs:34:21:34:21 | a | main.rs:27:20:27:23 | ... | provenance | | -| main.rs:34:21:34:21 | a | main.rs:34:13:34:22 | f(...) | provenance | | -| main.rs:42:16:42:25 | source(...) | main.rs:44:5:44:5 | [post] f [captured capt] | provenance | | -| main.rs:44:5:44:5 | [post] f [captured capt] | main.rs:45:10:45:13 | capt | provenance | | -| main.rs:44:5:44:5 | [post] f [captured capt] | main.rs:49:5:49:5 | g [captured capt] | provenance | | -| main.rs:49:5:49:5 | g [captured capt] | main.rs:47:14:47:17 | capt | provenance | | -nodes -| main.rs:11:20:11:52 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | -| main.rs:11:30:11:39 | source(...) | semmle.label | source(...) | -| main.rs:12:10:12:16 | f(...) | semmle.label | f(...) | -| main.rs:16:20:16:23 | ... | semmle.label | ... | -| main.rs:18:18:18:21 | data | semmle.label | data | -| main.rs:22:9:22:9 | a | semmle.label | a | -| main.rs:22:13:22:22 | source(...) | semmle.label | source(...) | -| main.rs:23:13:23:13 | a | semmle.label | a | -| main.rs:27:20:27:23 | ... | semmle.label | ... | -| main.rs:28:9:32:9 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | -| main.rs:33:9:33:9 | a | semmle.label | a | -| main.rs:33:13:33:22 | source(...) | semmle.label | source(...) | -| main.rs:34:9:34:9 | b | semmle.label | b | -| main.rs:34:13:34:22 | f(...) | semmle.label | f(...) | -| main.rs:34:21:34:21 | a | semmle.label | a | -| main.rs:35:10:35:10 | b | semmle.label | b | -| main.rs:42:16:42:25 | source(...) | semmle.label | source(...) | -| main.rs:44:5:44:5 | [post] f [captured capt] | semmle.label | [post] f [captured capt] | -| main.rs:45:10:45:13 | capt | semmle.label | capt | -| main.rs:47:14:47:17 | capt | semmle.label | capt | -| main.rs:49:5:49:5 | g [captured capt] | semmle.label | g [captured capt] | -subpaths -| main.rs:34:21:34:21 | a | main.rs:27:20:27:23 | ... | main.rs:28:9:32:9 | if cond {...} else {...} | main.rs:34:13:34:22 | f(...) | -testFailures -#select -| main.rs:12:10:12:16 | f(...) | main.rs:11:30:11:39 | source(...) | main.rs:12:10:12:16 | f(...) | $@ | main.rs:11:30:11:39 | source(...) | source(...) | -| main.rs:18:18:18:21 | data | main.rs:22:13:22:22 | source(...) | main.rs:18:18:18:21 | data | $@ | main.rs:22:13:22:22 | source(...) | source(...) | -| main.rs:35:10:35:10 | b | main.rs:33:13:33:22 | source(...) | main.rs:35:10:35:10 | b | $@ | main.rs:33:13:33:22 | source(...) | source(...) | -| main.rs:45:10:45:13 | capt | main.rs:42:16:42:25 | source(...) | main.rs:45:10:45:13 | capt | $@ | main.rs:42:16:42:25 | source(...) | source(...) | -| main.rs:47:14:47:17 | capt | main.rs:42:16:42:25 | source(...) | main.rs:47:14:47:17 | capt | $@ | main.rs:42:16:42:25 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/closures/Cargo.lock b/rust/ql/test/library-tests/dataflow/lambdas/Cargo.lock similarity index 100% rename from rust/ql/test/library-tests/dataflow/closures/Cargo.lock rename to rust/ql/test/library-tests/dataflow/lambdas/Cargo.lock diff --git a/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected new file mode 100644 index 00000000000..ef9a97677e1 --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected @@ -0,0 +1,50 @@ +models +edges +| main.rs:10:20:10:52 | if cond {...} else {...} | main.rs:11:10:11:16 | f(...) | provenance | | +| main.rs:10:30:10:39 | source(...) | main.rs:10:20:10:52 | if cond {...} else {...} | provenance | | +| main.rs:15:20:15:23 | ... | main.rs:17:18:17:21 | data | provenance | | +| main.rs:22:9:22:9 | a | main.rs:23:13:23:13 | a | provenance | | +| main.rs:22:13:22:22 | source(...) | main.rs:22:9:22:9 | a | provenance | | +| main.rs:23:13:23:13 | a | main.rs:15:20:15:23 | ... | provenance | | +| main.rs:27:20:27:23 | ... | main.rs:27:26:27:52 | if cond {...} else {...} | provenance | | +| main.rs:28:9:28:9 | a | main.rs:29:21:29:21 | a | provenance | | +| main.rs:28:13:28:22 | source(...) | main.rs:28:9:28:9 | a | provenance | | +| main.rs:29:9:29:9 | b | main.rs:30:10:30:10 | b | provenance | | +| main.rs:29:13:29:22 | f(...) | main.rs:29:9:29:9 | b | provenance | | +| main.rs:29:21:29:21 | a | main.rs:27:20:27:23 | ... | provenance | | +| main.rs:29:21:29:21 | a | main.rs:29:13:29:22 | f(...) | provenance | | +| main.rs:37:16:37:25 | source(...) | main.rs:39:5:39:5 | [post] f [captured capt] | provenance | | +| main.rs:39:5:39:5 | [post] f [captured capt] | main.rs:40:10:40:13 | capt | provenance | | +| main.rs:39:5:39:5 | [post] f [captured capt] | main.rs:44:5:44:5 | g [captured capt] | provenance | | +| main.rs:44:5:44:5 | g [captured capt] | main.rs:42:14:42:17 | capt | provenance | | +nodes +| main.rs:10:20:10:52 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | +| main.rs:10:30:10:39 | source(...) | semmle.label | source(...) | +| main.rs:11:10:11:16 | f(...) | semmle.label | f(...) | +| main.rs:15:20:15:23 | ... | semmle.label | ... | +| main.rs:17:18:17:21 | data | semmle.label | data | +| main.rs:22:9:22:9 | a | semmle.label | a | +| main.rs:22:13:22:22 | source(...) | semmle.label | source(...) | +| main.rs:23:13:23:13 | a | semmle.label | a | +| main.rs:27:20:27:23 | ... | semmle.label | ... | +| main.rs:27:26:27:52 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | +| main.rs:28:9:28:9 | a | semmle.label | a | +| main.rs:28:13:28:22 | source(...) | semmle.label | source(...) | +| main.rs:29:9:29:9 | b | semmle.label | b | +| main.rs:29:13:29:22 | f(...) | semmle.label | f(...) | +| main.rs:29:21:29:21 | a | semmle.label | a | +| main.rs:30:10:30:10 | b | semmle.label | b | +| main.rs:37:16:37:25 | source(...) | semmle.label | source(...) | +| main.rs:39:5:39:5 | [post] f [captured capt] | semmle.label | [post] f [captured capt] | +| main.rs:40:10:40:13 | capt | semmle.label | capt | +| main.rs:42:14:42:17 | capt | semmle.label | capt | +| main.rs:44:5:44:5 | g [captured capt] | semmle.label | g [captured capt] | +subpaths +| main.rs:29:21:29:21 | a | main.rs:27:20:27:23 | ... | main.rs:27:26:27:52 | if cond {...} else {...} | main.rs:29:13:29:22 | f(...) | +testFailures +#select +| main.rs:11:10:11:16 | f(...) | main.rs:10:30:10:39 | source(...) | main.rs:11:10:11:16 | f(...) | $@ | main.rs:10:30:10:39 | source(...) | source(...) | +| main.rs:17:18:17:21 | data | main.rs:22:13:22:22 | source(...) | main.rs:17:18:17:21 | data | $@ | main.rs:22:13:22:22 | source(...) | source(...) | +| main.rs:30:10:30:10 | b | main.rs:28:13:28:22 | source(...) | main.rs:30:10:30:10 | b | $@ | main.rs:28:13:28:22 | source(...) | source(...) | +| main.rs:40:10:40:13 | capt | main.rs:37:16:37:25 | source(...) | main.rs:40:10:40:13 | capt | $@ | main.rs:37:16:37:25 | source(...) | source(...) | +| main.rs:42:14:42:17 | capt | main.rs:37:16:37:25 | source(...) | main.rs:42:14:42:17 | capt | $@ | main.rs:37:16:37:25 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/closures/inline-flow.ql b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.ql similarity index 100% rename from rust/ql/test/library-tests/dataflow/closures/inline-flow.ql rename to rust/ql/test/library-tests/dataflow/lambdas/inline-flow.ql diff --git a/rust/ql/test/library-tests/dataflow/closures/main.rs b/rust/ql/test/library-tests/dataflow/lambdas/main.rs similarity index 53% rename from rust/ql/test/library-tests/dataflow/closures/main.rs rename to rust/ql/test/library-tests/dataflow/lambdas/main.rs index 66ce59a3b04..573e93311c5 100644 --- a/rust/ql/test/library-tests/dataflow/closures/main.rs +++ b/rust/ql/test/library-tests/dataflow/lambdas/main.rs @@ -6,30 +6,25 @@ fn sink(s: i64) { println!("{}", s); } - fn closure_flow_out() { let f = |cond| if cond { source(92) } else { 0 }; sink(f(true)); // $ hasValueFlow=92 } fn closure_flow_in() { - let f = |cond, data| + let f = |cond, data| { if cond { sink(data); // $ hasValueFlow=87 } else { sink(0) - }; + } + }; let a = source(87); f(true, a); } fn closure_flow_through() { - let f = |cond, data| - if cond { - data - } else { - 0 - }; + let f = |cond, data| if cond { data } else { 0 }; let a = source(43); let b = f(true, a); sink(b); // $ hasValueFlow=43 @@ -49,9 +44,46 @@ fn closure_captured_variable() { g(); } +fn get_from_source() -> i64 { + source(93) +} + +fn pass_to_sink(data: i64) { + sink(data); // $ MISSING: hasValueFlow=34 +} + +fn function_flow_out() { + let f = get_from_source; + sink(f()); // $ MISSING: hasValueFlow=93 +} + +fn function_flow_in() { + let f = pass_to_sink; + let a = source(34); + f(a); +} + +fn get_arg(cond: bool, data: i64) -> i64 { + if cond { + data + } else { + 0 + } +} + +fn function_flows_through() { + let f = get_arg; + let a = source(56); + let b = f(true, a); + sink(b); // $ MISSING: hasValueFlow=56 +} + fn main() { closure_flow_out(); closure_flow_in(); closure_flow_through(); closure_captured_variable(); + function_flow_in(); + function_flow_out(); + function_flows_through(); } From 37ffe82ac94023148caa6f818bf81b4621b4fea0 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 29 Sep 2025 14:49:04 +0200 Subject: [PATCH 02/70] Rust: Handle functions as lambdas --- .../rust/dataflow/internal/DataFlowImpl.qll | 24 ++++++++------ .../codeql/rust/dataflow/internal/Node.qll | 4 +-- .../dataflow/lambdas/inline-flow.expected | 33 +++++++++++++++++++ .../library-tests/dataflow/lambdas/main.rs | 6 ++-- 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 4c252dfcd0f..9fa0f0a5a83 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -295,13 +295,10 @@ module LocalFlow { class LambdaCallKind = Unit; /** Holds if `creation` is an expression that creates a lambda of kind `kind`. */ -predicate lambdaCreationExpr(Expr creation, LambdaCallKind kind) { - ( - creation instanceof ClosureExpr - or - creation instanceof Scope::AsyncBlockScope - ) and - exists(kind) +predicate lambdaCreationExpr(Expr creation) { + creation instanceof ClosureExpr + or + creation instanceof Scope::AsyncBlockScope } /** @@ -810,8 +807,15 @@ module RustDataFlow implements InputSig { /** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) { - exists(Expr e | - e = creation.asExpr().getExpr() and lambdaCreationExpr(e, kind) and e = c.asCfgScope() + exists(kind) and + exists(Expr e | e = creation.asExpr().getExpr() | + lambdaCreationExpr(e) and e = c.asCfgScope() + or + // A path expression, that resolves to a function, evaluates to a function + // pointer. Except if the path occurs directly in a call, then it's just a + // call to the function and not a function being passed as data. + resolvePath(e.(PathExpr).getPath()) = c.asCfgScope() and + not any(CallExpr call).getFunction() = e ) } @@ -931,7 +935,7 @@ module VariableCapture { } class ClosureExpr extends Expr instanceof ExprCfgNode { - ClosureExpr() { lambdaCreationExpr(super.getExpr(), _) } + ClosureExpr() { lambdaCreationExpr(super.getExpr()) } predicate hasBody(Callable body) { body = super.getExpr() } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll index a1bdc367d0a..e46b4375c04 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll @@ -454,7 +454,7 @@ newtype TNode = or lambdaCallExpr(_, _, e) or - lambdaCreationExpr(e.getExpr(), _) + lambdaCreationExpr(e.getExpr()) or // Whenever `&mut e` has a post-update node we also create one for `e`. // E.g., for `e` in `f(..., &mut e, ...)` or `*(&mut e) = ...`. @@ -478,5 +478,5 @@ newtype TNode = } or TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) or TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or - TClosureSelfReferenceNode(CfgScope c) { lambdaCreationExpr(c, _) } or + TClosureSelfReferenceNode(CfgScope c) { lambdaCreationExpr(c) } or TCaptureNode(VariableCapture::Flow::SynthesizedCaptureNode cn) diff --git a/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected index ef9a97677e1..7c99702aec6 100644 --- a/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected @@ -17,6 +17,19 @@ edges | main.rs:39:5:39:5 | [post] f [captured capt] | main.rs:40:10:40:13 | capt | provenance | | | main.rs:39:5:39:5 | [post] f [captured capt] | main.rs:44:5:44:5 | g [captured capt] | provenance | | | main.rs:44:5:44:5 | g [captured capt] | main.rs:42:14:42:17 | capt | provenance | | +| main.rs:47:29:49:1 | { ... } | main.rs:57:10:57:12 | f(...) | provenance | | +| main.rs:48:5:48:14 | source(...) | main.rs:47:29:49:1 | { ... } | provenance | | +| main.rs:51:17:51:25 | ...: i64 | main.rs:52:10:52:13 | data | provenance | | +| main.rs:62:9:62:9 | a | main.rs:63:7:63:7 | a | provenance | | +| main.rs:62:13:62:22 | source(...) | main.rs:62:9:62:9 | a | provenance | | +| main.rs:63:7:63:7 | a | main.rs:51:17:51:25 | ...: i64 | provenance | | +| main.rs:66:24:66:32 | ...: i64 | main.rs:66:42:72:1 | { ... } | provenance | | +| main.rs:76:9:76:9 | a | main.rs:77:21:77:21 | a | provenance | | +| main.rs:76:13:76:22 | source(...) | main.rs:76:9:76:9 | a | provenance | | +| main.rs:77:9:77:9 | b | main.rs:78:10:78:10 | b | provenance | | +| main.rs:77:13:77:22 | f(...) | main.rs:77:9:77:9 | b | provenance | | +| main.rs:77:21:77:21 | a | main.rs:66:24:66:32 | ...: i64 | provenance | | +| main.rs:77:21:77:21 | a | main.rs:77:13:77:22 | f(...) | provenance | | nodes | main.rs:10:20:10:52 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | | main.rs:10:30:10:39 | source(...) | semmle.label | source(...) | @@ -39,8 +52,25 @@ nodes | main.rs:40:10:40:13 | capt | semmle.label | capt | | main.rs:42:14:42:17 | capt | semmle.label | capt | | main.rs:44:5:44:5 | g [captured capt] | semmle.label | g [captured capt] | +| main.rs:47:29:49:1 | { ... } | semmle.label | { ... } | +| main.rs:48:5:48:14 | source(...) | semmle.label | source(...) | +| main.rs:51:17:51:25 | ...: i64 | semmle.label | ...: i64 | +| main.rs:52:10:52:13 | data | semmle.label | data | +| main.rs:57:10:57:12 | f(...) | semmle.label | f(...) | +| main.rs:62:9:62:9 | a | semmle.label | a | +| main.rs:62:13:62:22 | source(...) | semmle.label | source(...) | +| main.rs:63:7:63:7 | a | semmle.label | a | +| main.rs:66:24:66:32 | ...: i64 | semmle.label | ...: i64 | +| main.rs:66:42:72:1 | { ... } | semmle.label | { ... } | +| main.rs:76:9:76:9 | a | semmle.label | a | +| main.rs:76:13:76:22 | source(...) | semmle.label | source(...) | +| main.rs:77:9:77:9 | b | semmle.label | b | +| main.rs:77:13:77:22 | f(...) | semmle.label | f(...) | +| main.rs:77:21:77:21 | a | semmle.label | a | +| main.rs:78:10:78:10 | b | semmle.label | b | subpaths | main.rs:29:21:29:21 | a | main.rs:27:20:27:23 | ... | main.rs:27:26:27:52 | if cond {...} else {...} | main.rs:29:13:29:22 | f(...) | +| main.rs:77:21:77:21 | a | main.rs:66:24:66:32 | ...: i64 | main.rs:66:42:72:1 | { ... } | main.rs:77:13:77:22 | f(...) | testFailures #select | main.rs:11:10:11:16 | f(...) | main.rs:10:30:10:39 | source(...) | main.rs:11:10:11:16 | f(...) | $@ | main.rs:10:30:10:39 | source(...) | source(...) | @@ -48,3 +78,6 @@ testFailures | main.rs:30:10:30:10 | b | main.rs:28:13:28:22 | source(...) | main.rs:30:10:30:10 | b | $@ | main.rs:28:13:28:22 | source(...) | source(...) | | main.rs:40:10:40:13 | capt | main.rs:37:16:37:25 | source(...) | main.rs:40:10:40:13 | capt | $@ | main.rs:37:16:37:25 | source(...) | source(...) | | main.rs:42:14:42:17 | capt | main.rs:37:16:37:25 | source(...) | main.rs:42:14:42:17 | capt | $@ | main.rs:37:16:37:25 | source(...) | source(...) | +| main.rs:52:10:52:13 | data | main.rs:62:13:62:22 | source(...) | main.rs:52:10:52:13 | data | $@ | main.rs:62:13:62:22 | source(...) | source(...) | +| main.rs:57:10:57:12 | f(...) | main.rs:48:5:48:14 | source(...) | main.rs:57:10:57:12 | f(...) | $@ | main.rs:48:5:48:14 | source(...) | source(...) | +| main.rs:78:10:78:10 | b | main.rs:76:13:76:22 | source(...) | main.rs:78:10:78:10 | b | $@ | main.rs:76:13:76:22 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/lambdas/main.rs b/rust/ql/test/library-tests/dataflow/lambdas/main.rs index 573e93311c5..252b132ec74 100644 --- a/rust/ql/test/library-tests/dataflow/lambdas/main.rs +++ b/rust/ql/test/library-tests/dataflow/lambdas/main.rs @@ -49,12 +49,12 @@ fn get_from_source() -> i64 { } fn pass_to_sink(data: i64) { - sink(data); // $ MISSING: hasValueFlow=34 + sink(data); // $ hasValueFlow=34 } fn function_flow_out() { let f = get_from_source; - sink(f()); // $ MISSING: hasValueFlow=93 + sink(f()); // $ hasValueFlow=93 } fn function_flow_in() { @@ -75,7 +75,7 @@ fn function_flows_through() { let f = get_arg; let a = source(56); let b = f(true, a); - sink(b); // $ MISSING: hasValueFlow=56 + sink(b); // $ hasValueFlow=56 } fn main() { From 98a20f982037f5159a2474a48152b949e8a422dd Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 29 Sep 2025 14:58:34 +0200 Subject: [PATCH 03/70] Rust: Add change note --- .../lib/change-notes/2025-09-29-data-flow-function-pointer.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 rust/ql/lib/change-notes/2025-09-29-data-flow-function-pointer.md diff --git a/rust/ql/lib/change-notes/2025-09-29-data-flow-function-pointer.md b/rust/ql/lib/change-notes/2025-09-29-data-flow-function-pointer.md new file mode 100644 index 00000000000..7d1adb06e74 --- /dev/null +++ b/rust/ql/lib/change-notes/2025-09-29-data-flow-function-pointer.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Improve data flow through functions being passed as function pointers. \ No newline at end of file From 4846cf479125a33ed25f5bf3ae1ed2f4a58889b9 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 30 Sep 2025 10:21:17 +0200 Subject: [PATCH 04/70] Cargo: upgrade dependencies --- Cargo.lock | 140 +++++++++++++----------- ruby/extractor/Cargo.toml | 6 +- rust/ast-generator/Cargo.toml | 6 +- rust/extractor/Cargo.toml | 12 +- rust/extractor/macros/Cargo.toml | 2 +- shared/tree-sitter-extractor/Cargo.toml | 2 +- 6 files changed, 90 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77be7b054ed..b6456c84106 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "argfile" @@ -328,7 +328,7 @@ dependencies = [ "chalk-derive 0.103.0", "chalk-ir 0.103.0", "ena", - "indexmap 2.11.1", + "indexmap 2.11.4", "itertools 0.12.1", "petgraph", "rustc-hash 1.1.0", @@ -351,9 +351,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -361,9 +361,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -472,7 +472,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "toml 0.9.5", + "toml 0.9.7", "tracing", "tracing-flame", "tracing-subscriber", @@ -557,9 +557,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "darling" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ "darling_core", "darling_macro", @@ -567,9 +567,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", @@ -581,9 +581,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", @@ -1059,13 +1059,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.1" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", "hashbrown 0.15.5", "serde", + "serde_core", ] [[package]] @@ -1490,7 +1491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.11.1", + "indexmap 2.11.4", ] [[package]] @@ -1559,9 +1560,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -1666,7 +1667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e876bb2c3e52a8d4e6684526a2d4e81f9d028b939ee4dc5dc775fe10deb44d59" dependencies = [ "dashmap", - "indexmap 2.11.1", + "indexmap 2.11.4", "la-arena", "ra_ap_cfg", "ra_ap_intern", @@ -1708,7 +1709,7 @@ checksum = "ebffdc134eccabc17209d7760cfff7fd12ed18ab6e21188c5e084b97aa38504c" dependencies = [ "arrayvec", "either", - "indexmap 2.11.1", + "indexmap 2.11.4", "itertools 0.14.0", "ra_ap_base_db", "ra_ap_cfg", @@ -1738,7 +1739,7 @@ dependencies = [ "drop_bomb", "either", "fst", - "indexmap 2.11.1", + "indexmap 2.11.4", "itertools 0.14.0", "la-arena", "ra-ap-rustc_abi", @@ -1807,7 +1808,7 @@ dependencies = [ "cov-mark", "either", "ena", - "indexmap 2.11.1", + "indexmap 2.11.4", "itertools 0.14.0", "la-arena", "oorandom", @@ -1845,7 +1846,7 @@ dependencies = [ "crossbeam-channel", "either", "fst", - "indexmap 2.11.1", + "indexmap 2.11.4", "itertools 0.14.0", "line-index", "memchr", @@ -1947,7 +1948,7 @@ version = "0.0.301" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45db9e2df587d56f0738afa89fb2c100ff7c1e9cbe49e07f6a8b62342832211b" dependencies = [ - "indexmap 2.11.1", + "indexmap 2.11.4", "ra_ap_intern", "ra_ap_paths", "ra_ap_span", @@ -2106,7 +2107,7 @@ checksum = "6c174d6b9b7a7f54687df7e00c3e75ed6f082a7943a9afb1d54f33c0c12773de" dependencies = [ "crossbeam-channel", "fst", - "indexmap 2.11.1", + "indexmap 2.11.4", "nohash-hasher", "ra_ap_paths", "ra_ap_stdx", @@ -2211,9 +2212,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.2" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -2223,9 +2224,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -2316,7 +2317,7 @@ dependencies = [ "crossbeam-utils", "hashbrown 0.15.5", "hashlink", - "indexmap 2.11.1", + "indexmap 2.11.4", "intrusive-collections", "papaya", "parking_lot", @@ -2414,10 +2415,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -2443,10 +2445,19 @@ dependencies = [ ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -2455,15 +2466,16 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.11.1", + "indexmap 2.11.4", "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -2477,24 +2489,24 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee" dependencies = [ - "serde", + "serde_core", ] [[package]] name = "serde_with" -version = "3.14.0" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" dependencies = [ "base64", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.11.1", + "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", "serde", @@ -2506,9 +2518,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" dependencies = [ "darling", "proc-macro2", @@ -2522,7 +2534,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.11.1", + "indexmap 2.11.4", "itoa", "ryu", "serde", @@ -2701,14 +2713,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" +checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0" dependencies = [ - "indexmap 2.11.1", - "serde", - "serde_spanned 1.0.0", - "toml_datetime 0.7.0", + "indexmap 2.11.4", + "serde_core", + "serde_spanned 1.0.2", + "toml_datetime 0.7.2", "toml_parser", "toml_writer", "winnow", @@ -2725,11 +2737,11 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -2738,7 +2750,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.1", + "indexmap 2.11.4", "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", @@ -2748,9 +2760,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" dependencies = [ "winnow", ] @@ -2763,9 +2775,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" +checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109" [[package]] name = "tracing" @@ -2855,9 +2867,9 @@ dependencies = [ [[package]] name = "tree-sitter-embedded-template" -version = "0.23.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790063ef14e5b67556abc0b3be0ed863fb41d65ee791cf8c0b20eb42a1fa46af" +checksum = "833d528e8fcb4e49ddb04d4d6450ddb8ac08f282a58fec94ce981c9c5dbf7e3a" dependencies = [ "cc", "tree-sitter-language", diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index f4de37e8512..b6e1ae90119 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -8,15 +8,15 @@ edition = "2024" # When updating these dependencies, run `misc/bazel/3rdparty/update_cargo_deps.sh` [dependencies] tree-sitter = ">= 0.23.0" -tree-sitter-embedded-template = "0.23.2" +tree-sitter-embedded-template = "0.25.0" tree-sitter-ruby = "0.23.1" clap = { version = "4.5", features = ["derive"] } tracing = "0.1" tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } rayon = "1.11.0" -regex = "1.11.2" +regex = "1.11.3" encoding = "0.2" lazy_static = "1.5.0" -serde_json = "1.0.143" +serde_json = "1.0.145" codeql-extractor = { path = "../../shared/tree-sitter-extractor" } diff --git a/rust/ast-generator/Cargo.toml b/rust/ast-generator/Cargo.toml index a5270923722..fcba71b696c 100644 --- a/rust/ast-generator/Cargo.toml +++ b/rust/ast-generator/Cargo.toml @@ -8,10 +8,10 @@ license = "MIT" [dependencies] ungrammar = "1.16.1" proc-macro2 = "1.0.101" -quote = "1.0.40" +quote = "1.0.41" either = "1.15.0" stdx = {package = "ra_ap_stdx", version = "0.0.301"} itertools = "0.14.0" mustache = "0.9.0" -serde = { version = "1.0.219", features = ["derive"] } -anyhow = "1.0.99" +serde = { version = "1.0.228", features = ["derive"] } +anyhow = "1.0.100" diff --git a/rust/extractor/Cargo.toml b/rust/extractor/Cargo.toml index 0f87bc22f9e..223d9dfc68c 100644 --- a/rust/extractor/Cargo.toml +++ b/rust/extractor/Cargo.toml @@ -6,8 +6,8 @@ license = "MIT" # When updating these dependencies, run `rust/update_cargo_deps.sh` [dependencies] -anyhow = "1.0.99" -clap = { version = "4.5.47", features = ["derive"] } +anyhow = "1.0.100" +clap = { version = "4.5.48", features = ["derive"] } figment = { version = "0.10.19", features = ["env", "yaml"] } num-traits = "0.2.19" ra_ap_base_db = "0.0.301" @@ -25,8 +25,8 @@ ra_ap_parser = "0.0.301" ra_ap_span = "0.0.301" ra_ap_cfg = "0.0.301" ra_ap_intern = "0.0.301" -serde = "1.0.219" -serde_with = "3.14.0" +serde = "1.0.228" +serde_with = "3.14.1" triomphe = "0.1.14" argfile = "0.2.1" codeql-extractor = { path = "../../shared/tree-sitter-extractor" } @@ -34,9 +34,9 @@ rust-extractor-macros = { path = "macros" } itertools = "0.14.0" glob = "0.3.3" chrono = { version = "0.4.42", features = ["serde"] } -serde_json = "1.0.143" +serde_json = "1.0.145" dunce = "1.0.5" -toml = "0.9.5" +toml = "0.9.7" tracing = "0.1.41" tracing-flame = "0.2.0" tracing-subscriber = "0.3.20" diff --git a/rust/extractor/macros/Cargo.toml b/rust/extractor/macros/Cargo.toml index 013ebd986b4..e2e51876ee7 100644 --- a/rust/extractor/macros/Cargo.toml +++ b/rust/extractor/macros/Cargo.toml @@ -9,5 +9,5 @@ proc-macro = true # When updating these dependencies, run `rust/update_cargo_deps.sh` [dependencies] -quote = "1.0.40" +quote = "1.0.41" syn = { version = "2.0.106", features = ["full"] } diff --git a/shared/tree-sitter-extractor/Cargo.toml b/shared/tree-sitter-extractor/Cargo.toml index 8e60be7274f..d02f02fd588 100644 --- a/shared/tree-sitter-extractor/Cargo.toml +++ b/shared/tree-sitter-extractor/Cargo.toml @@ -12,7 +12,7 @@ tree-sitter = ">= 0.23.0" tracing = "0.1" tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } rayon = "1.11.0" -regex = "1.11.2" +regex = "1.11.3" encoding = "0.2" lazy_static = "1.5.0" serde = { version = "1.0", features = ["derive"] } From ef80ff416fc3059d408c7aa850c256a7dd01d3d6 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 30 Sep 2025 10:28:42 +0200 Subject: [PATCH 05/70] Bazel: regenerate vendored cargo dependencies --- MODULE.bazel | 18 +- ....0.99.bazel => BUILD.anyhow-1.0.100.bazel} | 6 +- .../tree_sitter_extractors_deps/BUILD.bazel | 54 ++-- .../BUILD.camino-1.1.12.bazel | 2 +- .../BUILD.cargo-platform-0.2.0.bazel | 2 +- .../BUILD.cargo-util-schemas-0.8.2.bazel | 2 +- .../BUILD.cargo_metadata-0.21.0.bazel | 4 +- .../BUILD.chalk-derive-0.103.0.bazel | 2 +- .../BUILD.chalk-derive-0.104.0.bazel | 2 +- .../BUILD.chalk-solve-0.103.0.bazel | 2 +- .../BUILD.chrono-0.4.42.bazel | 2 +- ...p-4.5.47.bazel => BUILD.clap-4.5.48.bazel} | 4 +- ....bazel => BUILD.clap_builder-4.5.48.bazel} | 2 +- .../BUILD.clap_derive-4.5.47.bazel | 2 +- ...20.11.bazel => BUILD.darling-0.21.3.bazel} | 6 +- ....bazel => BUILD.darling_core-0.21.3.bazel} | 4 +- ...bazel => BUILD.darling_macro-0.21.3.bazel} | 6 +- .../BUILD.displaydoc-0.2.5.bazel | 2 +- .../BUILD.erased-serde-0.4.6.bazel | 2 +- .../BUILD.figment-0.10.19.bazel | 2 +- .../BUILD.globset-0.4.16.bazel | 2 +- ...11.1.bazel => BUILD.indexmap-2.11.4.bazel} | 4 +- .../BUILD.matchers-0.2.0.bazel | 2 +- .../BUILD.mustache-0.9.0.bazel | 2 +- .../BUILD.pear_codegen-0.2.9.bazel | 2 +- .../BUILD.petgraph-0.6.5.bazel | 2 +- ...BUILD.proc-macro2-diagnostics-0.10.1.bazel | 2 +- ...-1.0.40.bazel => BUILD.quote-1.0.41.bazel} | 71 ++++- ...ILD.ra-ap-rustc_index_macros-0.123.0.bazel | 2 +- .../BUILD.ra_ap_base_db-0.0.301.bazel | 2 +- .../BUILD.ra_ap_hir-0.0.301.bazel | 2 +- .../BUILD.ra_ap_hir_def-0.0.301.bazel | 2 +- .../BUILD.ra_ap_hir_ty-0.0.301.bazel | 2 +- .../BUILD.ra_ap_ide_db-0.0.301.bazel | 2 +- .../BUILD.ra_ap_load-cargo-0.0.301.bazel | 2 +- .../BUILD.ra_ap_proc_macro_api-0.0.301.bazel | 8 +- .../BUILD.ra_ap_project_model-0.0.301.bazel | 8 +- ...UILD.ra_ap_query-group-macro-0.0.301.bazel | 2 +- .../BUILD.ra_ap_vfs-0.0.301.bazel | 2 +- .../BUILD.ref-cast-impl-1.0.24.bazel | 2 +- ...-1.11.2.bazel => BUILD.regex-1.11.3.bazel} | 4 +- ...azel => BUILD.regex-automata-0.4.11.bazel} | 2 +- .../BUILD.salsa-0.23.0.bazel | 2 +- .../BUILD.salsa-macros-0.23.0.bazel | 2 +- .../BUILD.schemars-0.9.0.bazel | 4 +- .../BUILD.schemars-1.0.4.bazel | 4 +- .../BUILD.semver-1.0.26.bazel | 2 +- ....0.219.bazel => BUILD.serde-1.0.228.bazel} | 13 +- .../BUILD.serde-untagged-0.1.8.bazel | 2 +- .../BUILD.serde-value-0.7.0.bazel | 2 +- .../BUILD.serde_core-1.0.228.bazel | 167 +++++++++++ ...bazel => BUILD.serde_derive-1.0.228.bazel} | 6 +- ...3.bazel => BUILD.serde_json-1.0.145.bazel} | 36 +-- .../BUILD.serde_spanned-0.6.9.bazel | 2 +- ....bazel => BUILD.serde_spanned-1.0.2.bazel} | 4 +- ....0.bazel => BUILD.serde_with-3.14.1.bazel} | 8 +- ...l => BUILD.serde_with_macros-3.14.1.bazel} | 6 +- .../BUILD.serde_yaml-0.9.34+deprecated.bazel | 4 +- .../BUILD.syn-2.0.106.bazel | 2 +- .../BUILD.synstructure-0.13.2.bazel | 2 +- .../BUILD.thiserror-impl-2.0.16.bazel | 2 +- .../BUILD.toml-0.8.23.bazel | 2 +- ...oml-0.9.5.bazel => BUILD.toml-0.9.7.bazel} | 12 +- .../BUILD.toml_datetime-0.6.11.bazel | 2 +- ....bazel => BUILD.toml_datetime-0.7.2.bazel} | 4 +- .../BUILD.toml_edit-0.22.27.bazel | 4 +- ....2.bazel => BUILD.toml_parser-1.0.3.bazel} | 2 +- ....2.bazel => BUILD.toml_writer-1.0.3.bazel} | 2 +- .../BUILD.tracing-attributes-0.1.30.bazel | 2 +- .../BUILD.tracing-subscriber-0.3.20.bazel | 2 +- .../BUILD.tree-sitter-0.25.9.bazel | 4 +- ...ree-sitter-embedded-template-0.25.0.bazel} | 6 +- .../BUILD.triomphe-0.1.14.bazel | 2 +- .../BUILD.url-2.5.7.bazel | 2 +- .../BUILD.wasm-bindgen-backend-0.2.101.bazel | 2 +- .../BUILD.wasm-bindgen-macro-0.2.101.bazel | 2 +- ...D.wasm-bindgen-macro-support-0.2.101.bazel | 2 +- .../BUILD.windows-implement-0.60.0.bazel | 2 +- .../BUILD.windows-interface-0.59.1.bazel | 2 +- .../BUILD.yoke-derive-0.8.0.bazel | 2 +- .../BUILD.zerocopy-derive-0.8.27.bazel | 2 +- .../BUILD.zerofrom-derive-0.1.6.bazel | 2 +- .../BUILD.zerovec-derive-0.11.1.bazel | 2 +- .../tree_sitter_extractors_deps/defs.bzl | 272 +++++++++--------- 84 files changed, 553 insertions(+), 308 deletions(-) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.anyhow-1.0.99.bazel => BUILD.anyhow-1.0.100.bazel} (97%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.clap-4.5.47.bazel => BUILD.clap-4.5.48.bazel} (98%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.clap_builder-4.5.47.bazel => BUILD.clap_builder-4.5.48.bazel} (99%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.darling-0.20.11.bazel => BUILD.darling-0.21.3.bazel} (96%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.darling_core-0.20.11.bazel => BUILD.darling_core-0.21.3.bazel} (98%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.darling_macro-0.20.11.bazel => BUILD.darling_macro-0.21.3.bazel} (96%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.indexmap-2.11.1.bazel => BUILD.indexmap-2.11.4.bazel} (98%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.quote-1.0.40.bazel => BUILD.quote-1.0.41.bazel} (72%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.regex-1.11.2.bazel => BUILD.regex-1.11.3.bazel} (98%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.regex-automata-0.4.10.bazel => BUILD.regex-automata-0.4.11.bazel} (99%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.serde-1.0.219.bazel => BUILD.serde-1.0.228.bazel} (95%) create mode 100644 misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_core-1.0.228.bazel rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.serde_derive-1.0.219.bazel => BUILD.serde_derive-1.0.228.bazel} (97%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.serde_json-1.0.143.bazel => BUILD.serde_json-1.0.145.bazel} (91%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.serde_spanned-1.0.0.bazel => BUILD.serde_spanned-1.0.2.bazel} (98%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.serde_with-3.14.0.bazel => BUILD.serde_with-3.14.1.bazel} (95%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.serde_with_macros-3.14.0.bazel => BUILD.serde_with_macros-3.14.1.bazel} (97%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.toml-0.9.5.bazel => BUILD.toml-0.9.7.bazel} (92%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.toml_datetime-0.7.0.bazel => BUILD.toml_datetime-0.7.2.bazel} (98%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.toml_parser-1.0.2.bazel => BUILD.toml_parser-1.0.3.bazel} (99%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.toml_writer-1.0.2.bazel => BUILD.toml_writer-1.0.3.bazel} (99%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.tree-sitter-embedded-template-0.23.2.bazel => BUILD.tree-sitter-embedded-template-0.25.0.bazel} (97%) diff --git a/MODULE.bazel b/MODULE.bazel index 9d09fc99722..89fdbf86a4d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -98,11 +98,11 @@ use_repo( tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r") use_repo( tree_sitter_extractors_deps, - "vendor_ts__anyhow-1.0.99", + "vendor_ts__anyhow-1.0.100", "vendor_ts__argfile-0.2.1", "vendor_ts__chalk-ir-0.104.0", "vendor_ts__chrono-0.4.42", - "vendor_ts__clap-4.5.47", + "vendor_ts__clap-4.5.48", "vendor_ts__dunce-1.0.5", "vendor_ts__either-1.15.0", "vendor_ts__encoding-0.2.33", @@ -116,7 +116,7 @@ use_repo( "vendor_ts__num-traits-0.2.19", "vendor_ts__num_cpus-1.17.0", "vendor_ts__proc-macro2-1.0.101", - "vendor_ts__quote-1.0.40", + "vendor_ts__quote-1.0.41", "vendor_ts__ra_ap_base_db-0.0.301", "vendor_ts__ra_ap_cfg-0.0.301", "vendor_ts__ra_ap_hir-0.0.301", @@ -135,17 +135,17 @@ use_repo( "vendor_ts__ra_ap_vfs-0.0.301", "vendor_ts__rand-0.9.2", "vendor_ts__rayon-1.11.0", - "vendor_ts__regex-1.11.2", - "vendor_ts__serde-1.0.219", - "vendor_ts__serde_json-1.0.143", - "vendor_ts__serde_with-3.14.0", + "vendor_ts__regex-1.11.3", + "vendor_ts__serde-1.0.228", + "vendor_ts__serde_json-1.0.145", + "vendor_ts__serde_with-3.14.1", "vendor_ts__syn-2.0.106", - "vendor_ts__toml-0.9.5", + "vendor_ts__toml-0.9.7", "vendor_ts__tracing-0.1.41", "vendor_ts__tracing-flame-0.2.0", "vendor_ts__tracing-subscriber-0.3.20", "vendor_ts__tree-sitter-0.25.9", - "vendor_ts__tree-sitter-embedded-template-0.23.2", + "vendor_ts__tree-sitter-embedded-template-0.25.0", "vendor_ts__tree-sitter-json-0.24.8", "vendor_ts__tree-sitter-ql-0.23.1", "vendor_ts__tree-sitter-ruby-0.23.1", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.anyhow-1.0.99.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.anyhow-1.0.100.bazel similarity index 97% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.anyhow-1.0.99.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.anyhow-1.0.100.bazel index cdcb7d554a2..26ed6194b68 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.anyhow-1.0.99.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.anyhow-1.0.100.bazel @@ -96,9 +96,9 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.99", + version = "1.0.100", deps = [ - "@vendor_ts__anyhow-1.0.99//:build_script_build", + "@vendor_ts__anyhow-1.0.100//:build_script_build", ], ) @@ -154,7 +154,7 @@ cargo_build_script( "noclippy", "norustfmt", ], - version = "1.0.99", + version = "1.0.100", visibility = ["//visibility:private"], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel index 720687fcb84..a5cfeccdcea 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel @@ -32,14 +32,14 @@ filegroup( # Workspace Member Dependencies alias( - name = "anyhow-1.0.99", - actual = "@vendor_ts__anyhow-1.0.99//:anyhow", + name = "anyhow-1.0.100", + actual = "@vendor_ts__anyhow-1.0.100//:anyhow", tags = ["manual"], ) alias( name = "anyhow", - actual = "@vendor_ts__anyhow-1.0.99//:anyhow", + actual = "@vendor_ts__anyhow-1.0.100//:anyhow", tags = ["manual"], ) @@ -80,14 +80,14 @@ alias( ) alias( - name = "clap-4.5.47", - actual = "@vendor_ts__clap-4.5.47//:clap", + name = "clap-4.5.48", + actual = "@vendor_ts__clap-4.5.48//:clap", tags = ["manual"], ) alias( name = "clap", - actual = "@vendor_ts__clap-4.5.47//:clap", + actual = "@vendor_ts__clap-4.5.48//:clap", tags = ["manual"], ) @@ -248,14 +248,14 @@ alias( ) alias( - name = "quote-1.0.40", - actual = "@vendor_ts__quote-1.0.40//:quote", + name = "quote-1.0.41", + actual = "@vendor_ts__quote-1.0.41//:quote", tags = ["manual"], ) alias( name = "quote", - actual = "@vendor_ts__quote-1.0.40//:quote", + actual = "@vendor_ts__quote-1.0.41//:quote", tags = ["manual"], ) @@ -482,50 +482,50 @@ alias( ) alias( - name = "regex-1.11.2", - actual = "@vendor_ts__regex-1.11.2//:regex", + name = "regex-1.11.3", + actual = "@vendor_ts__regex-1.11.3//:regex", tags = ["manual"], ) alias( name = "regex", - actual = "@vendor_ts__regex-1.11.2//:regex", + actual = "@vendor_ts__regex-1.11.3//:regex", tags = ["manual"], ) alias( - name = "serde-1.0.219", - actual = "@vendor_ts__serde-1.0.219//:serde", + name = "serde-1.0.228", + actual = "@vendor_ts__serde-1.0.228//:serde", tags = ["manual"], ) alias( name = "serde", - actual = "@vendor_ts__serde-1.0.219//:serde", + actual = "@vendor_ts__serde-1.0.228//:serde", tags = ["manual"], ) alias( - name = "serde_json-1.0.143", - actual = "@vendor_ts__serde_json-1.0.143//:serde_json", + name = "serde_json-1.0.145", + actual = "@vendor_ts__serde_json-1.0.145//:serde_json", tags = ["manual"], ) alias( name = "serde_json", - actual = "@vendor_ts__serde_json-1.0.143//:serde_json", + actual = "@vendor_ts__serde_json-1.0.145//:serde_json", tags = ["manual"], ) alias( - name = "serde_with-3.14.0", - actual = "@vendor_ts__serde_with-3.14.0//:serde_with", + name = "serde_with-3.14.1", + actual = "@vendor_ts__serde_with-3.14.1//:serde_with", tags = ["manual"], ) alias( name = "serde_with", - actual = "@vendor_ts__serde_with-3.14.0//:serde_with", + actual = "@vendor_ts__serde_with-3.14.1//:serde_with", tags = ["manual"], ) @@ -542,14 +542,14 @@ alias( ) alias( - name = "toml-0.9.5", - actual = "@vendor_ts__toml-0.9.5//:toml", + name = "toml-0.9.7", + actual = "@vendor_ts__toml-0.9.7//:toml", tags = ["manual"], ) alias( name = "toml", - actual = "@vendor_ts__toml-0.9.5//:toml", + actual = "@vendor_ts__toml-0.9.7//:toml", tags = ["manual"], ) @@ -602,14 +602,14 @@ alias( ) alias( - name = "tree-sitter-embedded-template-0.23.2", - actual = "@vendor_ts__tree-sitter-embedded-template-0.23.2//:tree_sitter_embedded_template", + name = "tree-sitter-embedded-template-0.25.0", + actual = "@vendor_ts__tree-sitter-embedded-template-0.25.0//:tree_sitter_embedded_template", tags = ["manual"], ) alias( name = "tree-sitter-embedded-template", - actual = "@vendor_ts__tree-sitter-embedded-template-0.23.2//:tree_sitter_embedded_template", + actual = "@vendor_ts__tree-sitter-embedded-template-0.25.0//:tree_sitter_embedded_template", tags = ["manual"], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.camino-1.1.12.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.camino-1.1.12.bazel index 9a90162b227..8f8a62dbdd8 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.camino-1.1.12.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.camino-1.1.12.bazel @@ -99,7 +99,7 @@ rust_library( version = "1.1.12", deps = [ "@vendor_ts__camino-1.1.12//:build_script_build", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo-platform-0.2.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo-platform-0.2.0.bazel index bde1a5698f5..315a77ded82 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo-platform-0.2.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo-platform-0.2.0.bazel @@ -90,6 +90,6 @@ rust_library( }), version = "0.2.0", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo-util-schemas-0.8.2.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo-util-schemas-0.8.2.bazel index d0dfee25c63..f74bdea2fe1 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo-util-schemas-0.8.2.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo-util-schemas-0.8.2.bazel @@ -91,7 +91,7 @@ rust_library( version = "0.8.2", deps = [ "@vendor_ts__semver-1.0.26//:semver", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", "@vendor_ts__serde-untagged-0.1.8//:serde_untagged", "@vendor_ts__serde-value-0.7.0//:serde_value", "@vendor_ts__thiserror-2.0.16//:thiserror", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.21.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.21.0.bazel index c96de37e116..12ce8fc813d 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.21.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.21.0.bazel @@ -97,8 +97,8 @@ rust_library( "@vendor_ts__cargo-platform-0.2.0//:cargo_platform", "@vendor_ts__cargo-util-schemas-0.8.2//:cargo_util_schemas", "@vendor_ts__semver-1.0.26//:semver", - "@vendor_ts__serde-1.0.219//:serde", - "@vendor_ts__serde_json-1.0.143//:serde_json", + "@vendor_ts__serde-1.0.228//:serde", + "@vendor_ts__serde_json-1.0.145//:serde_json", "@vendor_ts__thiserror-2.0.16//:thiserror", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-derive-0.103.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-derive-0.103.0.bazel index 5f533839888..89aadd71e2e 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-derive-0.103.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-derive-0.103.0.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.103.0", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", "@vendor_ts__synstructure-0.13.2//:synstructure", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-derive-0.104.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-derive-0.104.0.bazel index cd0251c5806..c5bea0da844 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-derive-0.104.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-derive-0.104.0.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.104.0", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", "@vendor_ts__synstructure-0.13.2//:synstructure", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-solve-0.103.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-solve-0.103.0.bazel index 9f0abb9530a..834e4c9b205 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-solve-0.103.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chalk-solve-0.103.0.bazel @@ -95,7 +95,7 @@ rust_library( deps = [ "@vendor_ts__chalk-ir-0.103.0//:chalk_ir", "@vendor_ts__ena-0.14.3//:ena", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__itertools-0.12.1//:itertools", "@vendor_ts__petgraph-0.6.5//:petgraph", "@vendor_ts__rustc-hash-1.1.0//:rustc_hash", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chrono-0.4.42.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chrono-0.4.42.bazel index f6c987b4f92..806fa5bd5a5 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chrono-0.4.42.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.chrono-0.4.42.bazel @@ -106,7 +106,7 @@ rust_library( version = "0.4.42", deps = [ "@vendor_ts__num-traits-0.2.19//:num_traits", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ] + select({ "@rules_rust//rust/platform:aarch64-apple-darwin": [ "@vendor_ts__iana-time-zone-0.1.63//:iana_time_zone", # aarch64-apple-darwin diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap-4.5.47.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap-4.5.48.bazel similarity index 98% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap-4.5.47.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap-4.5.48.bazel index 6156a05c6ff..c689eac509f 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap-4.5.47.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap-4.5.48.bazel @@ -101,8 +101,8 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "4.5.47", + version = "4.5.48", deps = [ - "@vendor_ts__clap_builder-4.5.47//:clap_builder", + "@vendor_ts__clap_builder-4.5.48//:clap_builder", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_builder-4.5.47.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_builder-4.5.48.bazel similarity index 99% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_builder-4.5.47.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_builder-4.5.48.bazel index 70d56783478..b1d6e28a676 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_builder-4.5.47.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_builder-4.5.48.bazel @@ -96,7 +96,7 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "4.5.47", + version = "4.5.48", deps = [ "@vendor_ts__anstream-0.6.20//:anstream", "@vendor_ts__anstyle-1.0.11//:anstyle", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_derive-4.5.47.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_derive-4.5.47.bazel index 1f2d042d69d..f4d794c20eb 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_derive-4.5.47.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.clap_derive-4.5.47.bazel @@ -95,7 +95,7 @@ rust_proc_macro( deps = [ "@vendor_ts__heck-0.5.0//:heck", "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling-0.20.11.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling-0.21.3.bazel similarity index 96% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling-0.20.11.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling-0.21.3.bazel index 57a23dfb80e..b40385ef20f 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling-0.20.11.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling-0.21.3.bazel @@ -41,7 +41,7 @@ rust_library( crate_root = "src/lib.rs", edition = "2021", proc_macro_deps = [ - "@vendor_ts__darling_macro-0.20.11//:darling_macro", + "@vendor_ts__darling_macro-0.21.3//:darling_macro", ], rustc_env_files = [ ":cargo_toml_env_vars", @@ -95,8 +95,8 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.20.11", + version = "0.21.3", deps = [ - "@vendor_ts__darling_core-0.20.11//:darling_core", + "@vendor_ts__darling_core-0.21.3//:darling_core", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_core-0.20.11.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_core-0.21.3.bazel similarity index 98% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_core-0.20.11.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_core-0.21.3.bazel index 8fe1dfc0606..79e5b9b385f 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_core-0.20.11.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_core-0.21.3.bazel @@ -92,12 +92,12 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.20.11", + version = "0.21.3", deps = [ "@vendor_ts__fnv-1.0.7//:fnv", "@vendor_ts__ident_case-1.0.1//:ident_case", "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__strsim-0.11.1//:strsim", "@vendor_ts__syn-2.0.106//:syn", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_macro-0.20.11.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_macro-0.21.3.bazel similarity index 96% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_macro-0.20.11.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_macro-0.21.3.bazel index c32d23d3c48..c150f931e32 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_macro-0.20.11.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.darling_macro-0.21.3.bazel @@ -88,10 +88,10 @@ rust_proc_macro( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.20.11", + version = "0.21.3", deps = [ - "@vendor_ts__darling_core-0.20.11//:darling_core", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__darling_core-0.21.3//:darling_core", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.displaydoc-0.2.5.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.displaydoc-0.2.5.bazel index a486cb7c128..87651e8bda3 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.displaydoc-0.2.5.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.displaydoc-0.2.5.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.2.5", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.erased-serde-0.4.6.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.erased-serde-0.4.6.bazel index 100d2f9727c..8e03c63e500 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.erased-serde-0.4.6.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.erased-serde-0.4.6.bazel @@ -93,7 +93,7 @@ rust_library( }), version = "0.4.6", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", "@vendor_ts__typeid-1.0.3//:typeid", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.figment-0.10.19.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.figment-0.10.19.bazel index 8b6d7b8c56c..641e4f01523 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.figment-0.10.19.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.figment-0.10.19.bazel @@ -103,7 +103,7 @@ rust_library( deps = [ "@vendor_ts__figment-0.10.19//:build_script_build", "@vendor_ts__pear-0.2.9//:pear", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", "@vendor_ts__serde_yaml-0.9.34-deprecated//:serde_yaml", "@vendor_ts__uncased-0.9.10//:uncased", ] + select({ diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.globset-0.4.16.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.globset-0.4.16.bazel index 6c5f8cd7929..cdcb709b651 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.globset-0.4.16.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.globset-0.4.16.bazel @@ -97,7 +97,7 @@ rust_library( "@vendor_ts__aho-corasick-1.1.3//:aho_corasick", "@vendor_ts__bstr-1.12.0//:bstr", "@vendor_ts__log-0.4.28//:log", - "@vendor_ts__regex-automata-0.4.10//:regex_automata", + "@vendor_ts__regex-automata-0.4.11//:regex_automata", "@vendor_ts__regex-syntax-0.8.6//:regex_syntax", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.indexmap-2.11.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.indexmap-2.11.4.bazel similarity index 98% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.indexmap-2.11.1.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.indexmap-2.11.4.bazel index c3763099eb8..be7b81b49f1 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.indexmap-2.11.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.indexmap-2.11.4.bazel @@ -93,10 +93,10 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "2.11.1", + version = "2.11.4", deps = [ "@vendor_ts__equivalent-1.0.2//:equivalent", "@vendor_ts__hashbrown-0.15.5//:hashbrown", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde_core-1.0.228//:serde_core", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.matchers-0.2.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.matchers-0.2.0.bazel index 4ba33942822..da67f321d99 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.matchers-0.2.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.matchers-0.2.0.bazel @@ -90,6 +90,6 @@ rust_library( }), version = "0.2.0", deps = [ - "@vendor_ts__regex-automata-0.4.10//:regex_automata", + "@vendor_ts__regex-automata-0.4.11//:regex_automata", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.mustache-0.9.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.mustache-0.9.0.bazel index ae043e0e2a1..cfaa72fda83 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.mustache-0.9.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.mustache-0.9.0.bazel @@ -91,6 +91,6 @@ rust_library( version = "0.9.0", deps = [ "@vendor_ts__log-0.3.9//:log", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.pear_codegen-0.2.9.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.pear_codegen-0.2.9.bazel index ce5597c6f7e..a8e7ad4bf41 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.pear_codegen-0.2.9.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.pear_codegen-0.2.9.bazel @@ -92,7 +92,7 @@ rust_proc_macro( deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", "@vendor_ts__proc-macro2-diagnostics-0.10.1//:proc_macro2_diagnostics", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.petgraph-0.6.5.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.petgraph-0.6.5.bazel index c643aefe2c7..7c88eb60903 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.petgraph-0.6.5.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.petgraph-0.6.5.bazel @@ -97,6 +97,6 @@ rust_library( version = "0.6.5", deps = [ "@vendor_ts__fixedbitset-0.4.2//:fixedbitset", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.proc-macro2-diagnostics-0.10.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.proc-macro2-diagnostics-0.10.1.bazel index 120c4d6c265..84323b7da79 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.proc-macro2-diagnostics-0.10.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.proc-macro2-diagnostics-0.10.1.bazel @@ -101,7 +101,7 @@ rust_library( deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", "@vendor_ts__proc-macro2-diagnostics-0.10.1//:build_script_build", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", "@vendor_ts__yansi-1.0.1//:yansi", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.quote-1.0.40.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.quote-1.0.41.bazel similarity index 72% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.quote-1.0.40.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.quote-1.0.41.bazel index 66b79239e47..de02a99d0de 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.quote-1.0.40.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.quote-1.0.41.bazel @@ -6,7 +6,11 @@ # bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors ############################################################################### -load("@rules_rust//cargo:defs.bzl", "cargo_toml_env_vars") +load( + "@rules_rust//cargo:defs.bzl", + "cargo_build_script", + "cargo_toml_env_vars", +) load("@rules_rust//rust:defs.bzl", "rust_library") package(default_visibility = ["//visibility:public"]) @@ -92,8 +96,71 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.40", + version = "1.0.41", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", + "@vendor_ts__quote-1.0.41//:build_script_build", ], ) + +cargo_build_script( + name = "_bs", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + "**/*.rs", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_features = [ + "default", + "proc-macro", + ], + crate_name = "build_script_build", + crate_root = "build.rs", + data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + edition = "2018", + pkg_name = "quote", + rustc_env_files = [ + ":cargo_toml_env_vars", + ], + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=quote", + "manual", + "noclippy", + "norustfmt", + ], + version = "1.0.41", + visibility = ["//visibility:private"], +) + +alias( + name = "build_script_build", + actual = ":_bs", + tags = ["manual"], +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra-ap-rustc_index_macros-0.123.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra-ap-rustc_index_macros-0.123.0.bazel index b45b48ce2b9..c0dff747844 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra-ap-rustc_index_macros-0.123.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra-ap-rustc_index_macros-0.123.0.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.123.0", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_base_db-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_base_db-0.0.301.bazel index 3931158e4a1..73ba2f1d47f 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_base_db-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_base_db-0.0.301.bazel @@ -103,7 +103,7 @@ rust_library( version = "0.0.301", deps = [ "@vendor_ts__dashmap-6.1.0//:dashmap", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__la-arena-0.3.1//:la_arena", "@vendor_ts__ra_ap_cfg-0.0.301//:ra_ap_cfg", "@vendor_ts__ra_ap_intern-0.0.301//:ra_ap_intern", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir-0.0.301.bazel index 3134859b4d2..668aa255fbe 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir-0.0.301.bazel @@ -104,7 +104,7 @@ rust_library( deps = [ "@vendor_ts__arrayvec-0.7.6//:arrayvec", "@vendor_ts__either-1.15.0//:either", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__itertools-0.14.0//:itertools", "@vendor_ts__ra_ap_base_db-0.0.301//:ra_ap_base_db", "@vendor_ts__ra_ap_cfg-0.0.301//:ra_ap_cfg", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir_def-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir_def-0.0.301.bazel index e97671e1b1b..77782b1df3c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir_def-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir_def-0.0.301.bazel @@ -112,7 +112,7 @@ rust_library( "@vendor_ts__drop_bomb-0.1.5//:drop_bomb", "@vendor_ts__either-1.15.0//:either", "@vendor_ts__fst-0.4.7//:fst", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__itertools-0.14.0//:itertools", "@vendor_ts__la-arena-0.3.1//:la_arena", "@vendor_ts__ra-ap-rustc_abi-0.123.0//:ra_ap_rustc_abi", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir_ty-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir_ty-0.0.301.bazel index 7190559d3d8..74b8972eda0 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir_ty-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_hir_ty-0.0.301.bazel @@ -113,7 +113,7 @@ rust_library( "@vendor_ts__cov-mark-2.1.0//:cov_mark", "@vendor_ts__either-1.15.0//:either", "@vendor_ts__ena-0.14.3//:ena", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__itertools-0.14.0//:itertools", "@vendor_ts__la-arena-0.3.1//:la_arena", "@vendor_ts__oorandom-11.1.5//:oorandom", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_ide_db-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_ide_db-0.0.301.bazel index 9df94ba4165..da23d55cdd2 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_ide_db-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_ide_db-0.0.301.bazel @@ -111,7 +111,7 @@ rust_library( "@vendor_ts__crossbeam-channel-0.5.15//:crossbeam_channel", "@vendor_ts__either-1.15.0//:either", "@vendor_ts__fst-0.4.7//:fst", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__itertools-0.14.0//:itertools", "@vendor_ts__line-index-0.1.2//:line_index", "@vendor_ts__memchr-2.7.5//:memchr", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_load-cargo-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_load-cargo-0.0.301.bazel index 81cbfdd3eaf..51fdf30d0bb 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_load-cargo-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_load-cargo-0.0.301.bazel @@ -101,7 +101,7 @@ rust_library( }), version = "0.0.301", deps = [ - "@vendor_ts__anyhow-1.0.99//:anyhow", + "@vendor_ts__anyhow-1.0.100//:anyhow", "@vendor_ts__crossbeam-channel-0.5.15//:crossbeam_channel", "@vendor_ts__itertools-0.14.0//:itertools", "@vendor_ts__ra_ap_hir_expand-0.0.301//:ra_ap_hir_expand", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.301.bazel index b2367547415..37f3378bd62 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.301.bazel @@ -44,7 +44,7 @@ rust_library( crate_root = "src/lib.rs", edition = "2024", proc_macro_deps = [ - "@vendor_ts__serde_derive-1.0.219//:serde_derive", + "@vendor_ts__serde_derive-1.0.228//:serde_derive", ], rustc_env_files = [ ":cargo_toml_env_vars", @@ -100,15 +100,15 @@ rust_library( }), version = "0.0.301", deps = [ - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__ra_ap_intern-0.0.301//:ra_ap_intern", "@vendor_ts__ra_ap_paths-0.0.301//:ra_ap_paths", "@vendor_ts__ra_ap_span-0.0.301//:ra_ap_span", "@vendor_ts__ra_ap_stdx-0.0.301//:ra_ap_stdx", "@vendor_ts__ra_ap_tt-0.0.301//:ra_ap_tt", "@vendor_ts__rustc-hash-2.1.1//:rustc_hash", - "@vendor_ts__serde-1.0.219//:serde", - "@vendor_ts__serde_json-1.0.143//:serde_json", + "@vendor_ts__serde-1.0.228//:serde", + "@vendor_ts__serde_json-1.0.145//:serde_json", "@vendor_ts__tracing-0.1.41//:tracing", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.301.bazel index 4332ecda1a7..29b6d793366 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.301.bazel @@ -46,7 +46,7 @@ rust_library( crate_root = "src/lib.rs", edition = "2024", proc_macro_deps = [ - "@vendor_ts__serde_derive-1.0.219//:serde_derive", + "@vendor_ts__serde_derive-1.0.228//:serde_derive", ], rustc_env_files = [ ":cargo_toml_env_vars", @@ -102,7 +102,7 @@ rust_library( }), version = "0.0.301", deps = [ - "@vendor_ts__anyhow-1.0.99//:anyhow", + "@vendor_ts__anyhow-1.0.100//:anyhow", "@vendor_ts__cargo_metadata-0.21.0//:cargo_metadata", "@vendor_ts__itertools-0.14.0//:itertools", "@vendor_ts__la-arena-0.3.1//:la_arena", @@ -115,8 +115,8 @@ rust_library( "@vendor_ts__ra_ap_toolchain-0.0.301//:ra_ap_toolchain", "@vendor_ts__rustc-hash-2.1.1//:rustc_hash", "@vendor_ts__semver-1.0.26//:semver", - "@vendor_ts__serde-1.0.219//:serde", - "@vendor_ts__serde_json-1.0.143//:serde_json", + "@vendor_ts__serde-1.0.228//:serde", + "@vendor_ts__serde_json-1.0.145//:serde_json", "@vendor_ts__temp-dir-0.1.16//:temp_dir", "@vendor_ts__tracing-0.1.41//:tracing", "@vendor_ts__triomphe-0.1.14//:triomphe", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_query-group-macro-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_query-group-macro-0.0.301.bazel index a4099d462ee..ae0f619a3ba 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_query-group-macro-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_query-group-macro-0.0.301.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.0.301", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_vfs-0.0.301.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_vfs-0.0.301.bazel index 33b4db4d356..868107cddc5 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_vfs-0.0.301.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_vfs-0.0.301.bazel @@ -96,7 +96,7 @@ rust_library( deps = [ "@vendor_ts__crossbeam-channel-0.5.15//:crossbeam_channel", "@vendor_ts__fst-0.4.7//:fst", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__nohash-hasher-0.2.0//:nohash_hasher", "@vendor_ts__ra_ap_paths-0.0.301//:ra_ap_paths", "@vendor_ts__ra_ap_stdx-0.0.301//:ra_ap_stdx", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ref-cast-impl-1.0.24.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ref-cast-impl-1.0.24.bazel index ba548e9113a..70bc6acb116 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ref-cast-impl-1.0.24.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ref-cast-impl-1.0.24.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "1.0.24", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-1.11.2.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-1.11.3.bazel similarity index 98% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-1.11.2.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-1.11.3.bazel index 1c4f925a111..2e26723c478 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-1.11.2.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-1.11.3.bazel @@ -107,11 +107,11 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.11.2", + version = "1.11.3", deps = [ "@vendor_ts__aho-corasick-1.1.3//:aho_corasick", "@vendor_ts__memchr-2.7.5//:memchr", - "@vendor_ts__regex-automata-0.4.10//:regex_automata", + "@vendor_ts__regex-automata-0.4.11//:regex_automata", "@vendor_ts__regex-syntax-0.8.6//:regex_syntax", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-automata-0.4.10.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-automata-0.4.11.bazel similarity index 99% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-automata-0.4.10.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-automata-0.4.11.bazel index 4b17c645f34..3f008ea863c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-automata-0.4.10.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.regex-automata-0.4.11.bazel @@ -116,7 +116,7 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.4.10", + version = "0.4.11", deps = [ "@vendor_ts__aho-corasick-1.1.3//:aho_corasick", "@vendor_ts__memchr-2.7.5//:memchr", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.salsa-0.23.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.salsa-0.23.0.bazel index a7a2366514f..5ba01a304a8 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.salsa-0.23.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.salsa-0.23.0.bazel @@ -104,7 +104,7 @@ rust_library( "@vendor_ts__crossbeam-utils-0.8.21//:crossbeam_utils", "@vendor_ts__hashbrown-0.15.5//:hashbrown", "@vendor_ts__hashlink-0.10.0//:hashlink", - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__intrusive-collections-0.9.7//:intrusive_collections", "@vendor_ts__papaya-0.2.3//:papaya", "@vendor_ts__parking_lot-0.12.4//:parking_lot", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.salsa-macros-0.23.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.salsa-macros-0.23.0.bazel index 03a3ef58912..8d763b3ef95 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.salsa-macros-0.23.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.salsa-macros-0.23.0.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.23.0", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", "@vendor_ts__synstructure-0.13.2//:synstructure", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.schemars-0.9.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.schemars-0.9.0.bazel index 639b6c71a0d..6f1dd98fa17 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.schemars-0.9.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.schemars-0.9.0.bazel @@ -92,7 +92,7 @@ rust_library( deps = [ "@vendor_ts__dyn-clone-1.0.20//:dyn_clone", "@vendor_ts__ref-cast-1.0.24//:ref_cast", - "@vendor_ts__serde-1.0.219//:serde", - "@vendor_ts__serde_json-1.0.143//:serde_json", + "@vendor_ts__serde-1.0.228//:serde", + "@vendor_ts__serde_json-1.0.145//:serde_json", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.schemars-1.0.4.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.schemars-1.0.4.bazel index dce895551c8..81d7aa89ab5 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.schemars-1.0.4.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.schemars-1.0.4.bazel @@ -92,7 +92,7 @@ rust_library( deps = [ "@vendor_ts__dyn-clone-1.0.20//:dyn_clone", "@vendor_ts__ref-cast-1.0.24//:ref_cast", - "@vendor_ts__serde-1.0.219//:serde", - "@vendor_ts__serde_json-1.0.143//:serde_json", + "@vendor_ts__serde-1.0.228//:serde", + "@vendor_ts__serde_json-1.0.145//:serde_json", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.semver-1.0.26.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.semver-1.0.26.bazel index 1b139d7a87e..b0460d053ae 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.semver-1.0.26.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.semver-1.0.26.bazel @@ -100,7 +100,7 @@ rust_library( version = "1.0.26", deps = [ "@vendor_ts__semver-1.0.26//:build_script_build", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-1.0.219.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-1.0.228.bazel similarity index 95% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-1.0.219.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-1.0.228.bazel index 86cb23175ba..e58b661dec8 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-1.0.219.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-1.0.228.bazel @@ -46,9 +46,9 @@ rust_library( "std", ], crate_root = "src/lib.rs", - edition = "2018", + edition = "2021", proc_macro_deps = [ - "@vendor_ts__serde_derive-1.0.219//:serde_derive", + "@vendor_ts__serde_derive-1.0.228//:serde_derive", ], rustc_env_files = [ ":cargo_toml_env_vars", @@ -102,9 +102,10 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.219", + version = "1.0.228", deps = [ - "@vendor_ts__serde-1.0.219//:build_script_build", + "@vendor_ts__serde-1.0.228//:build_script_build", + "@vendor_ts__serde_core-1.0.228//:serde_core", ], ) @@ -148,7 +149,7 @@ cargo_build_script( "WORKSPACE.bazel", ], ), - edition = "2018", + edition = "2021", pkg_name = "serde", rustc_env_files = [ ":cargo_toml_env_vars", @@ -163,7 +164,7 @@ cargo_build_script( "noclippy", "norustfmt", ], - version = "1.0.219", + version = "1.0.228", visibility = ["//visibility:private"], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-untagged-0.1.8.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-untagged-0.1.8.bazel index 0191982b73a..f04da9de1ad 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-untagged-0.1.8.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-untagged-0.1.8.bazel @@ -91,7 +91,7 @@ rust_library( version = "0.1.8", deps = [ "@vendor_ts__erased-serde-0.4.6//:erased_serde", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", "@vendor_ts__typeid-1.0.3//:typeid", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-value-0.7.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-value-0.7.0.bazel index f6b8e9a212a..c897b79e5c7 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-value-0.7.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde-value-0.7.0.bazel @@ -91,6 +91,6 @@ rust_library( version = "0.7.0", deps = [ "@vendor_ts__ordered-float-2.10.1//:ordered_float", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_core-1.0.228.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_core-1.0.228.bazel new file mode 100644 index 00000000000..cfca5c545ab --- /dev/null +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_core-1.0.228.bazel @@ -0,0 +1,167 @@ +############################################################################### +# @generated +# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To +# regenerate this file, run the following: +# +# bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors +############################################################################### + +load( + "@rules_rust//cargo:defs.bzl", + "cargo_build_script", + "cargo_toml_env_vars", +) +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +cargo_toml_env_vars( + name = "cargo_toml_env_vars", + src = "Cargo.toml", +) + +rust_library( + name = "serde_core", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_features = [ + "alloc", + "result", + "std", + ], + crate_root = "src/lib.rs", + edition = "2021", + rustc_env_files = [ + ":cargo_toml_env_vars", + ], + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=serde_core", + "manual", + "noclippy", + "norustfmt", + ], + target_compatible_with = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [], + "@rules_rust//rust/platform:aarch64-apple-ios": [], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [], + "@rules_rust//rust/platform:aarch64-linux-android": [], + "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [], + "@rules_rust//rust/platform:aarch64-unknown-uefi": [], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:armv7-linux-androideabi": [], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:i686-apple-darwin": [], + "@rules_rust//rust/platform:i686-linux-android": [], + "@rules_rust//rust/platform:i686-pc-windows-msvc": [], + "@rules_rust//rust/platform:i686-unknown-freebsd": [], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [], + "@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [], + "@rules_rust//rust/platform:thumbv7em-none-eabi": [], + "@rules_rust//rust/platform:thumbv8m.main-none-eabi": [], + "@rules_rust//rust/platform:wasm32-unknown-unknown": [], + "@rules_rust//rust/platform:wasm32-wasip1": [], + "@rules_rust//rust/platform:x86_64-apple-darwin": [], + "@rules_rust//rust/platform:x86_64-apple-ios": [], + "@rules_rust//rust/platform:x86_64-linux-android": [], + "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-none": [], + "@rules_rust//rust/platform:x86_64-unknown-uefi": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + version = "1.0.228", + deps = [ + "@vendor_ts__serde_core-1.0.228//:build_script_build", + ], +) + +cargo_build_script( + name = "_bs", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + "**/*.rs", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_features = [ + "alloc", + "result", + "std", + ], + crate_name = "build_script_build", + crate_root = "build.rs", + data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + edition = "2021", + pkg_name = "serde_core", + rustc_env_files = [ + ":cargo_toml_env_vars", + ], + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=serde_core", + "manual", + "noclippy", + "norustfmt", + ], + version = "1.0.228", + visibility = ["//visibility:private"], +) + +alias( + name = "build_script_build", + actual = ":_bs", + tags = ["manual"], +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_derive-1.0.219.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_derive-1.0.228.bazel similarity index 97% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_derive-1.0.219.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_derive-1.0.228.bazel index f11ee965dba..e3b6733407b 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_derive-1.0.219.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_derive-1.0.228.bazel @@ -38,7 +38,7 @@ rust_proc_macro( "default", ], crate_root = "src/lib.rs", - edition = "2015", + edition = "2021", rustc_env_files = [ ":cargo_toml_env_vars", ], @@ -91,10 +91,10 @@ rust_proc_macro( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.219", + version = "1.0.228", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.143.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.145.bazel similarity index 91% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.143.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.145.bazel index 1a4cca70a4f..5d6298313e4 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.143.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.145.bazel @@ -155,55 +155,55 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.143", + version = "1.0.145", deps = [ "@vendor_ts__itoa-1.0.15//:itoa", "@vendor_ts__memchr-2.7.5//:memchr", "@vendor_ts__ryu-1.0.20//:ryu", - "@vendor_ts__serde-1.0.219//:serde", - "@vendor_ts__serde_json-1.0.143//:build_script_build", + "@vendor_ts__serde_core-1.0.228//:serde_core", + "@vendor_ts__serde_json-1.0.145//:build_script_build", ] + select({ "@rules_rust//rust/platform:aarch64-apple-darwin": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # aarch64-apple-darwin + "@vendor_ts__indexmap-2.11.4//:indexmap", # aarch64-apple-darwin ], "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # aarch64-pc-windows-msvc + "@vendor_ts__indexmap-2.11.4//:indexmap", # aarch64-pc-windows-msvc ], "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # aarch64-unknown-linux-gnu + "@vendor_ts__indexmap-2.11.4//:indexmap", # aarch64-unknown-linux-gnu ], "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # aarch64-unknown-linux-gnu, aarch64-unknown-nixos-gnu + "@vendor_ts__indexmap-2.11.4//:indexmap", # aarch64-unknown-linux-gnu, aarch64-unknown-nixos-gnu ], "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # arm-unknown-linux-gnueabi + "@vendor_ts__indexmap-2.11.4//:indexmap", # arm-unknown-linux-gnueabi ], "@rules_rust//rust/platform:i686-pc-windows-msvc": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # i686-pc-windows-msvc + "@vendor_ts__indexmap-2.11.4//:indexmap", # i686-pc-windows-msvc ], "@rules_rust//rust/platform:i686-unknown-linux-gnu": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # i686-unknown-linux-gnu + "@vendor_ts__indexmap-2.11.4//:indexmap", # i686-unknown-linux-gnu ], "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # powerpc-unknown-linux-gnu + "@vendor_ts__indexmap-2.11.4//:indexmap", # powerpc-unknown-linux-gnu ], "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # s390x-unknown-linux-gnu + "@vendor_ts__indexmap-2.11.4//:indexmap", # s390x-unknown-linux-gnu ], "@rules_rust//rust/platform:x86_64-apple-darwin": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # x86_64-apple-darwin + "@vendor_ts__indexmap-2.11.4//:indexmap", # x86_64-apple-darwin ], "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # x86_64-pc-windows-msvc + "@vendor_ts__indexmap-2.11.4//:indexmap", # x86_64-pc-windows-msvc ], "@rules_rust//rust/platform:x86_64-unknown-freebsd": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # x86_64-unknown-freebsd + "@vendor_ts__indexmap-2.11.4//:indexmap", # x86_64-unknown-freebsd ], "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # x86_64-unknown-linux-gnu + "@vendor_ts__indexmap-2.11.4//:indexmap", # x86_64-unknown-linux-gnu ], "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [ - "@vendor_ts__indexmap-2.11.1//:indexmap", # x86_64-unknown-linux-gnu, x86_64-unknown-nixos-gnu + "@vendor_ts__indexmap-2.11.4//:indexmap", # x86_64-unknown-linux-gnu, x86_64-unknown-nixos-gnu ], "//conditions:default": [], }), @@ -320,7 +320,7 @@ cargo_build_script( "noclippy", "norustfmt", ], - version = "1.0.143", + version = "1.0.145", visibility = ["//visibility:private"], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-0.6.9.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-0.6.9.bazel index ffb3bcf7240..c596adf490c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-0.6.9.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-0.6.9.bazel @@ -93,6 +93,6 @@ rust_library( }), version = "0.6.9", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-1.0.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-1.0.2.bazel similarity index 98% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-1.0.0.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-1.0.2.bazel index e0c6242de6f..e51f544db4f 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-1.0.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_spanned-1.0.2.bazel @@ -93,8 +93,8 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.0", + version = "1.0.2", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde_core-1.0.228//:serde_core", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with-3.14.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with-3.14.1.bazel similarity index 95% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with-3.14.0.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with-3.14.1.bazel index 08f8fdf3880..39a38f4f337 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with-3.14.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with-3.14.1.bazel @@ -43,8 +43,8 @@ rust_library( crate_root = "src/lib.rs", edition = "2021", proc_macro_deps = [ - "@vendor_ts__serde_derive-1.0.219//:serde_derive", - "@vendor_ts__serde_with_macros-3.14.0//:serde_with_macros", + "@vendor_ts__serde_derive-1.0.228//:serde_derive", + "@vendor_ts__serde_with_macros-3.14.1//:serde_with_macros", ], rustc_env_files = [ ":cargo_toml_env_vars", @@ -98,8 +98,8 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "3.14.0", + version = "3.14.1", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with_macros-3.14.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with_macros-3.14.1.bazel similarity index 97% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with_macros-3.14.0.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with_macros-3.14.1.bazel index 5ce2041aa7f..e6c0864d9f0 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with_macros-3.14.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_with_macros-3.14.1.bazel @@ -88,11 +88,11 @@ rust_proc_macro( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "3.14.0", + version = "3.14.1", deps = [ - "@vendor_ts__darling-0.20.11//:darling", + "@vendor_ts__darling-0.21.3//:darling", "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_yaml-0.9.34+deprecated.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_yaml-0.9.34+deprecated.bazel index 46287f3ed28..63410f30d1c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_yaml-0.9.34+deprecated.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_yaml-0.9.34+deprecated.bazel @@ -90,10 +90,10 @@ rust_library( }), version = "0.9.34+deprecated", deps = [ - "@vendor_ts__indexmap-2.11.1//:indexmap", + "@vendor_ts__indexmap-2.11.4//:indexmap", "@vendor_ts__itoa-1.0.15//:itoa", "@vendor_ts__ryu-1.0.20//:ryu", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", "@vendor_ts__unsafe-libyaml-0.2.11//:unsafe_libyaml", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.syn-2.0.106.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.syn-2.0.106.bazel index a4bd833e8e5..234b5299969 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.syn-2.0.106.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.syn-2.0.106.bazel @@ -104,7 +104,7 @@ rust_library( version = "2.0.106", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__unicode-ident-1.0.19//:unicode_ident", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.synstructure-0.13.2.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.synstructure-0.13.2.bazel index ed7ebbca401..1043ced1384 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.synstructure-0.13.2.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.synstructure-0.13.2.bazel @@ -95,7 +95,7 @@ rust_library( version = "0.13.2", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.thiserror-impl-2.0.16.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.thiserror-impl-2.0.16.bazel index 4f363e2e5ca..c8a6f5c3aca 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.thiserror-impl-2.0.16.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.thiserror-impl-2.0.16.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "2.0.16", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.8.23.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.8.23.bazel index bca02cb3cec..ba176cda49d 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.8.23.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.8.23.bazel @@ -95,7 +95,7 @@ rust_library( }), version = "0.8.23", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", "@vendor_ts__serde_spanned-0.6.9//:serde_spanned", "@vendor_ts__toml_datetime-0.6.11//:toml_datetime", "@vendor_ts__toml_edit-0.22.27//:toml_edit", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.9.5.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.9.7.bazel similarity index 92% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.9.5.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.9.7.bazel index 50e11857e38..ca4f62b9c48 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.9.5.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml-0.9.7.bazel @@ -95,13 +95,13 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.9.5", + version = "0.9.7", deps = [ - "@vendor_ts__serde-1.0.219//:serde", - "@vendor_ts__serde_spanned-1.0.0//:serde_spanned", - "@vendor_ts__toml_datetime-0.7.0//:toml_datetime", - "@vendor_ts__toml_parser-1.0.2//:toml_parser", - "@vendor_ts__toml_writer-1.0.2//:toml_writer", + "@vendor_ts__serde_core-1.0.228//:serde_core", + "@vendor_ts__serde_spanned-1.0.2//:serde_spanned", + "@vendor_ts__toml_datetime-0.7.2//:toml_datetime", + "@vendor_ts__toml_parser-1.0.3//:toml_parser", + "@vendor_ts__toml_writer-1.0.3//:toml_writer", "@vendor_ts__winnow-0.7.13//:winnow", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.6.11.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.6.11.bazel index d0a8d2086cc..8a9d6b7342b 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.6.11.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.6.11.bazel @@ -93,6 +93,6 @@ rust_library( }), version = "0.6.11", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.7.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.7.2.bazel similarity index 98% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.7.0.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.7.2.bazel index 6d3a99fb0f6..a94b3a87066 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.7.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_datetime-0.7.2.bazel @@ -93,8 +93,8 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.7.0", + version = "0.7.2", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde_core-1.0.228//:serde_core", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_edit-0.22.27.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_edit-0.22.27.bazel index dad3750bcfe..ab36adb8f30 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_edit-0.22.27.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_edit-0.22.27.bazel @@ -95,8 +95,8 @@ rust_library( }), version = "0.22.27", deps = [ - "@vendor_ts__indexmap-2.11.1//:indexmap", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__indexmap-2.11.4//:indexmap", + "@vendor_ts__serde-1.0.228//:serde", "@vendor_ts__serde_spanned-0.6.9//:serde_spanned", "@vendor_ts__toml_datetime-0.6.11//:toml_datetime", "@vendor_ts__toml_write-0.1.2//:toml_write", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_parser-1.0.2.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_parser-1.0.3.bazel similarity index 99% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_parser-1.0.2.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_parser-1.0.3.bazel index 424946c20a6..8b4c4668aa5 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_parser-1.0.2.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_parser-1.0.3.bazel @@ -92,7 +92,7 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.2", + version = "1.0.3", deps = [ "@vendor_ts__winnow-0.7.13//:winnow", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_writer-1.0.2.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_writer-1.0.3.bazel similarity index 99% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_writer-1.0.2.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_writer-1.0.3.bazel index 4193266e6d0..e90c3a61d87 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_writer-1.0.2.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.toml_writer-1.0.3.bazel @@ -92,5 +92,5 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.2", + version = "1.0.3", ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tracing-attributes-0.1.30.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tracing-attributes-0.1.30.bazel index f426539a31c..ec9f805d2d3 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tracing-attributes-0.1.30.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tracing-attributes-0.1.30.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.1.30", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tracing-subscriber-0.3.20.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tracing-subscriber-0.3.20.bazel index 13b54631970..cef88b5639b 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tracing-subscriber-0.3.20.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tracing-subscriber-0.3.20.bazel @@ -110,7 +110,7 @@ rust_library( "@vendor_ts__matchers-0.2.0//:matchers", "@vendor_ts__nu-ansi-term-0.50.1//:nu_ansi_term", "@vendor_ts__once_cell-1.21.3//:once_cell", - "@vendor_ts__regex-automata-0.4.10//:regex_automata", + "@vendor_ts__regex-automata-0.4.11//:regex_automata", "@vendor_ts__sharded-slab-0.1.7//:sharded_slab", "@vendor_ts__smallvec-1.15.1//:smallvec", "@vendor_ts__thread_local-1.1.9//:thread_local", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.25.9.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.25.9.bazel index 0cb981e4755..46d6255099c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.25.9.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.25.9.bazel @@ -98,7 +98,7 @@ rust_library( }), version = "0.25.9", deps = [ - "@vendor_ts__regex-1.11.2//:regex", + "@vendor_ts__regex-1.11.3//:regex", "@vendor_ts__regex-syntax-0.8.6//:regex_syntax", "@vendor_ts__streaming-iterator-0.1.9//:streaming_iterator", "@vendor_ts__tree-sitter-0.25.9//:build_script_build", @@ -163,7 +163,7 @@ cargo_build_script( visibility = ["//visibility:private"], deps = [ "@vendor_ts__cc-1.2.37//:cc", - "@vendor_ts__serde_json-1.0.143//:serde_json", + "@vendor_ts__serde_json-1.0.145//:serde_json", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.23.2.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.25.0.bazel similarity index 97% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.23.2.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.25.0.bazel index a2cac2bd450..2b40d8a34d6 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.23.2.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.25.0.bazel @@ -92,9 +92,9 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.23.2", + version = "0.25.0", deps = [ - "@vendor_ts__tree-sitter-embedded-template-0.23.2//:build_script_build", + "@vendor_ts__tree-sitter-embedded-template-0.25.0//:build_script_build", "@vendor_ts__tree-sitter-language-0.1.5//:tree_sitter_language", ], ) @@ -147,7 +147,7 @@ cargo_build_script( "noclippy", "norustfmt", ], - version = "0.23.2", + version = "0.25.0", visibility = ["//visibility:private"], deps = [ "@vendor_ts__cc-1.2.37//:cc", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.triomphe-0.1.14.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.triomphe-0.1.14.bazel index 1ea48d5a72d..95d24ae522c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.triomphe-0.1.14.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.triomphe-0.1.14.bazel @@ -96,7 +96,7 @@ rust_library( }), version = "0.1.14", deps = [ - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", "@vendor_ts__stable_deref_trait-1.2.0//:stable_deref_trait", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.url-2.5.7.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.url-2.5.7.bazel index 4ac8b9941e5..6b0e6fcb669 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.url-2.5.7.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.url-2.5.7.bazel @@ -98,6 +98,6 @@ rust_library( "@vendor_ts__form_urlencoded-1.2.2//:form_urlencoded", "@vendor_ts__idna-1.1.0//:idna", "@vendor_ts__percent-encoding-2.3.2//:percent_encoding", - "@vendor_ts__serde-1.0.219//:serde", + "@vendor_ts__serde-1.0.228//:serde", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-backend-0.2.101.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-backend-0.2.101.bazel index 5a85b0e104d..f859ddcd68b 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-backend-0.2.101.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-backend-0.2.101.bazel @@ -93,7 +93,7 @@ rust_library( "@vendor_ts__bumpalo-3.19.0//:bumpalo", "@vendor_ts__log-0.4.28//:log", "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", "@vendor_ts__wasm-bindgen-shared-0.2.101//:wasm_bindgen_shared", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-macro-0.2.101.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-macro-0.2.101.bazel index 4b1549c57dd..b6d6862a2bc 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-macro-0.2.101.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-macro-0.2.101.bazel @@ -90,7 +90,7 @@ rust_proc_macro( }), version = "0.2.101", deps = [ - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__wasm-bindgen-macro-support-0.2.101//:wasm_bindgen_macro_support", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-macro-support-0.2.101.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-macro-support-0.2.101.bazel index c42233e4e24..cfee619986a 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-macro-support-0.2.101.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.wasm-bindgen-macro-support-0.2.101.bazel @@ -91,7 +91,7 @@ rust_library( version = "0.2.101", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", "@vendor_ts__wasm-bindgen-backend-0.2.101//:wasm_bindgen_backend", "@vendor_ts__wasm-bindgen-shared-0.2.101//:wasm_bindgen_shared", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.windows-implement-0.60.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.windows-implement-0.60.0.bazel index b851ac18725..39e7c75ba65 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.windows-implement-0.60.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.windows-implement-0.60.0.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.60.0", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.windows-interface-0.59.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.windows-interface-0.59.1.bazel index 0d2150974e0..c91b2cb3347 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.windows-interface-0.59.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.windows-interface-0.59.1.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.59.1", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.yoke-derive-0.8.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.yoke-derive-0.8.0.bazel index 88b72641dcb..98706c66018 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.yoke-derive-0.8.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.yoke-derive-0.8.0.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.8.0", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", "@vendor_ts__synstructure-0.13.2//:synstructure", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerocopy-derive-0.8.27.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerocopy-derive-0.8.27.bazel index b3cddbaed90..7342159d255 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerocopy-derive-0.8.27.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerocopy-derive-0.8.27.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.8.27", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerofrom-derive-0.1.6.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerofrom-derive-0.1.6.bazel index facba68b2c7..b1ccbb6a85d 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerofrom-derive-0.1.6.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerofrom-derive-0.1.6.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.1.6", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", "@vendor_ts__synstructure-0.13.2//:synstructure", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerovec-derive-0.11.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerovec-derive-0.11.1.bazel index 06b27ed643f..29b50b11ae3 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerovec-derive-0.11.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zerovec-derive-0.11.1.bazel @@ -91,7 +91,7 @@ rust_proc_macro( version = "0.11.1", deps = [ "@vendor_ts__proc-macro2-1.0.101//:proc_macro2", - "@vendor_ts__quote-1.0.40//:quote", + "@vendor_ts__quote-1.0.41//:quote", "@vendor_ts__syn-2.0.106//:syn", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl index 6f5c2f2a7b2..4d7205ad951 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl @@ -295,28 +295,28 @@ def aliases( _NORMAL_DEPENDENCIES = { "ruby/extractor": { _COMMON_CONDITION: { - "clap": Label("@vendor_ts__clap-4.5.47//:clap"), + "clap": Label("@vendor_ts__clap-4.5.48//:clap"), "encoding": Label("@vendor_ts__encoding-0.2.33//:encoding"), "lazy_static": Label("@vendor_ts__lazy_static-1.5.0//:lazy_static"), "rayon": Label("@vendor_ts__rayon-1.11.0//:rayon"), - "regex": Label("@vendor_ts__regex-1.11.2//:regex"), - "serde_json": Label("@vendor_ts__serde_json-1.0.143//:serde_json"), + "regex": Label("@vendor_ts__regex-1.11.3//:regex"), + "serde_json": Label("@vendor_ts__serde_json-1.0.145//:serde_json"), "tracing": Label("@vendor_ts__tracing-0.1.41//:tracing"), "tracing-subscriber": Label("@vendor_ts__tracing-subscriber-0.3.20//:tracing_subscriber"), "tree-sitter": Label("@vendor_ts__tree-sitter-0.25.9//:tree_sitter"), - "tree-sitter-embedded-template": Label("@vendor_ts__tree-sitter-embedded-template-0.23.2//:tree_sitter_embedded_template"), + "tree-sitter-embedded-template": Label("@vendor_ts__tree-sitter-embedded-template-0.25.0//:tree_sitter_embedded_template"), "tree-sitter-ruby": Label("@vendor_ts__tree-sitter-ruby-0.23.1//:tree_sitter_ruby"), }, }, "rust/ast-generator": { _COMMON_CONDITION: { - "anyhow": Label("@vendor_ts__anyhow-1.0.99//:anyhow"), + "anyhow": Label("@vendor_ts__anyhow-1.0.100//:anyhow"), "either": Label("@vendor_ts__either-1.15.0//:either"), "itertools": Label("@vendor_ts__itertools-0.14.0//:itertools"), "mustache": Label("@vendor_ts__mustache-0.9.0//:mustache"), "proc-macro2": Label("@vendor_ts__proc-macro2-1.0.101//:proc_macro2"), - "quote": Label("@vendor_ts__quote-1.0.40//:quote"), - "serde": Label("@vendor_ts__serde-1.0.219//:serde"), + "quote": Label("@vendor_ts__quote-1.0.41//:quote"), + "serde": Label("@vendor_ts__serde-1.0.228//:serde"), "stdx": Label("@vendor_ts__ra_ap_stdx-0.0.301//:ra_ap_stdx"), "ungrammar": Label("@vendor_ts__ungrammar-1.16.1//:ungrammar"), }, @@ -325,11 +325,11 @@ _NORMAL_DEPENDENCIES = { }, "rust/extractor": { _COMMON_CONDITION: { - "anyhow": Label("@vendor_ts__anyhow-1.0.99//:anyhow"), + "anyhow": Label("@vendor_ts__anyhow-1.0.100//:anyhow"), "argfile": Label("@vendor_ts__argfile-0.2.1//:argfile"), "chalk-ir": Label("@vendor_ts__chalk-ir-0.104.0//:chalk_ir"), "chrono": Label("@vendor_ts__chrono-0.4.42//:chrono"), - "clap": Label("@vendor_ts__clap-4.5.47//:clap"), + "clap": Label("@vendor_ts__clap-4.5.48//:clap"), "dunce": Label("@vendor_ts__dunce-1.0.5//:dunce"), "figment": Label("@vendor_ts__figment-0.10.19//:figment"), "glob": Label("@vendor_ts__glob-0.3.3//:glob"), @@ -351,10 +351,10 @@ _NORMAL_DEPENDENCIES = { "ra_ap_span": Label("@vendor_ts__ra_ap_span-0.0.301//:ra_ap_span"), "ra_ap_syntax": Label("@vendor_ts__ra_ap_syntax-0.0.301//:ra_ap_syntax"), "ra_ap_vfs": Label("@vendor_ts__ra_ap_vfs-0.0.301//:ra_ap_vfs"), - "serde": Label("@vendor_ts__serde-1.0.219//:serde"), - "serde_json": Label("@vendor_ts__serde_json-1.0.143//:serde_json"), - "serde_with": Label("@vendor_ts__serde_with-3.14.0//:serde_with"), - "toml": Label("@vendor_ts__toml-0.9.5//:toml"), + "serde": Label("@vendor_ts__serde-1.0.228//:serde"), + "serde_json": Label("@vendor_ts__serde_json-1.0.145//:serde_json"), + "serde_with": Label("@vendor_ts__serde_with-3.14.1//:serde_with"), + "toml": Label("@vendor_ts__toml-0.9.7//:toml"), "tracing": Label("@vendor_ts__tracing-0.1.41//:tracing"), "tracing-flame": Label("@vendor_ts__tracing-flame-0.2.0//:tracing_flame"), "tracing-subscriber": Label("@vendor_ts__tracing-subscriber-0.3.20//:tracing_subscriber"), @@ -363,7 +363,7 @@ _NORMAL_DEPENDENCIES = { }, "rust/extractor/macros": { _COMMON_CONDITION: { - "quote": Label("@vendor_ts__quote-1.0.40//:quote"), + "quote": Label("@vendor_ts__quote-1.0.41//:quote"), "syn": Label("@vendor_ts__syn-2.0.106//:syn"), }, }, @@ -376,9 +376,9 @@ _NORMAL_DEPENDENCIES = { "lazy_static": Label("@vendor_ts__lazy_static-1.5.0//:lazy_static"), "num_cpus": Label("@vendor_ts__num_cpus-1.17.0//:num_cpus"), "rayon": Label("@vendor_ts__rayon-1.11.0//:rayon"), - "regex": Label("@vendor_ts__regex-1.11.2//:regex"), - "serde": Label("@vendor_ts__serde-1.0.219//:serde"), - "serde_json": Label("@vendor_ts__serde_json-1.0.143//:serde_json"), + "regex": Label("@vendor_ts__regex-1.11.3//:regex"), + "serde": Label("@vendor_ts__serde-1.0.228//:serde"), + "serde_json": Label("@vendor_ts__serde_json-1.0.145//:serde_json"), "tracing": Label("@vendor_ts__tracing-0.1.41//:tracing"), "tracing-subscriber": Label("@vendor_ts__tracing-subscriber-0.3.20//:tracing_subscriber"), "tree-sitter": Label("@vendor_ts__tree-sitter-0.25.9//:tree_sitter"), @@ -748,12 +748,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__anyhow-1.0.99", - sha256 = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100", + name = "vendor_ts__anyhow-1.0.100", + sha256 = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61", type = "tar.gz", - urls = ["https://static.crates.io/crates/anyhow/1.0.99/download"], - strip_prefix = "anyhow-1.0.99", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.anyhow-1.0.99.bazel"), + urls = ["https://static.crates.io/crates/anyhow/1.0.100/download"], + strip_prefix = "anyhow-1.0.100", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.anyhow-1.0.100.bazel"), ) maybe( @@ -1018,22 +1018,22 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__clap-4.5.47", - sha256 = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931", + name = "vendor_ts__clap-4.5.48", + sha256 = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae", type = "tar.gz", - urls = ["https://static.crates.io/crates/clap/4.5.47/download"], - strip_prefix = "clap-4.5.47", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.clap-4.5.47.bazel"), + urls = ["https://static.crates.io/crates/clap/4.5.48/download"], + strip_prefix = "clap-4.5.48", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.clap-4.5.48.bazel"), ) maybe( http_archive, - name = "vendor_ts__clap_builder-4.5.47", - sha256 = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6", + name = "vendor_ts__clap_builder-4.5.48", + sha256 = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9", type = "tar.gz", - urls = ["https://static.crates.io/crates/clap_builder/4.5.47/download"], - strip_prefix = "clap_builder-4.5.47", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.clap_builder-4.5.47.bazel"), + urls = ["https://static.crates.io/crates/clap_builder/4.5.48/download"], + strip_prefix = "clap_builder-4.5.48", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.clap_builder-4.5.48.bazel"), ) maybe( @@ -1158,32 +1158,32 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__darling-0.20.11", - sha256 = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee", + name = "vendor_ts__darling-0.21.3", + sha256 = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0", type = "tar.gz", - urls = ["https://static.crates.io/crates/darling/0.20.11/download"], - strip_prefix = "darling-0.20.11", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.darling-0.20.11.bazel"), + urls = ["https://static.crates.io/crates/darling/0.21.3/download"], + strip_prefix = "darling-0.21.3", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.darling-0.21.3.bazel"), ) maybe( http_archive, - name = "vendor_ts__darling_core-0.20.11", - sha256 = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e", + name = "vendor_ts__darling_core-0.21.3", + sha256 = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4", type = "tar.gz", - urls = ["https://static.crates.io/crates/darling_core/0.20.11/download"], - strip_prefix = "darling_core-0.20.11", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.darling_core-0.20.11.bazel"), + urls = ["https://static.crates.io/crates/darling_core/0.21.3/download"], + strip_prefix = "darling_core-0.21.3", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.darling_core-0.21.3.bazel"), ) maybe( http_archive, - name = "vendor_ts__darling_macro-0.20.11", - sha256 = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead", + name = "vendor_ts__darling_macro-0.21.3", + sha256 = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81", type = "tar.gz", - urls = ["https://static.crates.io/crates/darling_macro/0.20.11/download"], - strip_prefix = "darling_macro-0.20.11", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.darling_macro-0.20.11.bazel"), + urls = ["https://static.crates.io/crates/darling_macro/0.21.3/download"], + strip_prefix = "darling_macro-0.21.3", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.darling_macro-0.21.3.bazel"), ) maybe( @@ -1698,12 +1698,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__indexmap-2.11.1", - sha256 = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921", + name = "vendor_ts__indexmap-2.11.4", + sha256 = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5", type = "tar.gz", - urls = ["https://static.crates.io/crates/indexmap/2.11.1/download"], - strip_prefix = "indexmap-2.11.1", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.indexmap-2.11.1.bazel"), + urls = ["https://static.crates.io/crates/indexmap/2.11.4/download"], + strip_prefix = "indexmap-2.11.4", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.indexmap-2.11.4.bazel"), ) maybe( @@ -2278,12 +2278,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__quote-1.0.40", - sha256 = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d", + name = "vendor_ts__quote-1.0.41", + sha256 = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1", type = "tar.gz", - urls = ["https://static.crates.io/crates/quote/1.0.40/download"], - strip_prefix = "quote-1.0.40", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.quote-1.0.40.bazel"), + urls = ["https://static.crates.io/crates/quote/1.0.41/download"], + strip_prefix = "quote-1.0.41", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.quote-1.0.41.bazel"), ) maybe( @@ -2708,22 +2708,22 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__regex-1.11.2", - sha256 = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912", + name = "vendor_ts__regex-1.11.3", + sha256 = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c", type = "tar.gz", - urls = ["https://static.crates.io/crates/regex/1.11.2/download"], - strip_prefix = "regex-1.11.2", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.regex-1.11.2.bazel"), + urls = ["https://static.crates.io/crates/regex/1.11.3/download"], + strip_prefix = "regex-1.11.3", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.regex-1.11.3.bazel"), ) maybe( http_archive, - name = "vendor_ts__regex-automata-0.4.10", - sha256 = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6", + name = "vendor_ts__regex-automata-0.4.11", + sha256 = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad", type = "tar.gz", - urls = ["https://static.crates.io/crates/regex-automata/0.4.10/download"], - strip_prefix = "regex-automata-0.4.10", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.regex-automata-0.4.10.bazel"), + urls = ["https://static.crates.io/crates/regex-automata/0.4.11/download"], + strip_prefix = "regex-automata-0.4.11", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.regex-automata-0.4.11.bazel"), ) maybe( @@ -2918,12 +2918,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__serde-1.0.219", - sha256 = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6", + name = "vendor_ts__serde-1.0.228", + sha256 = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e", type = "tar.gz", - urls = ["https://static.crates.io/crates/serde/1.0.219/download"], - strip_prefix = "serde-1.0.219", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde-1.0.219.bazel"), + urls = ["https://static.crates.io/crates/serde/1.0.228/download"], + strip_prefix = "serde-1.0.228", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde-1.0.228.bazel"), ) maybe( @@ -2948,22 +2948,32 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__serde_derive-1.0.219", - sha256 = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00", + name = "vendor_ts__serde_core-1.0.228", + sha256 = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad", type = "tar.gz", - urls = ["https://static.crates.io/crates/serde_derive/1.0.219/download"], - strip_prefix = "serde_derive-1.0.219", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_derive-1.0.219.bazel"), + urls = ["https://static.crates.io/crates/serde_core/1.0.228/download"], + strip_prefix = "serde_core-1.0.228", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_core-1.0.228.bazel"), ) maybe( http_archive, - name = "vendor_ts__serde_json-1.0.143", - sha256 = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a", + name = "vendor_ts__serde_derive-1.0.228", + sha256 = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79", type = "tar.gz", - urls = ["https://static.crates.io/crates/serde_json/1.0.143/download"], - strip_prefix = "serde_json-1.0.143", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_json-1.0.143.bazel"), + urls = ["https://static.crates.io/crates/serde_derive/1.0.228/download"], + strip_prefix = "serde_derive-1.0.228", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_derive-1.0.228.bazel"), + ) + + maybe( + http_archive, + name = "vendor_ts__serde_json-1.0.145", + sha256 = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c", + type = "tar.gz", + urls = ["https://static.crates.io/crates/serde_json/1.0.145/download"], + strip_prefix = "serde_json-1.0.145", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_json-1.0.145.bazel"), ) maybe( @@ -2978,32 +2988,32 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__serde_spanned-1.0.0", - sha256 = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83", + name = "vendor_ts__serde_spanned-1.0.2", + sha256 = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee", type = "tar.gz", - urls = ["https://static.crates.io/crates/serde_spanned/1.0.0/download"], - strip_prefix = "serde_spanned-1.0.0", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_spanned-1.0.0.bazel"), + urls = ["https://static.crates.io/crates/serde_spanned/1.0.2/download"], + strip_prefix = "serde_spanned-1.0.2", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_spanned-1.0.2.bazel"), ) maybe( http_archive, - name = "vendor_ts__serde_with-3.14.0", - sha256 = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5", + name = "vendor_ts__serde_with-3.14.1", + sha256 = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e", type = "tar.gz", - urls = ["https://static.crates.io/crates/serde_with/3.14.0/download"], - strip_prefix = "serde_with-3.14.0", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_with-3.14.0.bazel"), + urls = ["https://static.crates.io/crates/serde_with/3.14.1/download"], + strip_prefix = "serde_with-3.14.1", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_with-3.14.1.bazel"), ) maybe( http_archive, - name = "vendor_ts__serde_with_macros-3.14.0", - sha256 = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f", + name = "vendor_ts__serde_with_macros-3.14.1", + sha256 = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e", type = "tar.gz", - urls = ["https://static.crates.io/crates/serde_with_macros/3.14.0/download"], - strip_prefix = "serde_with_macros-3.14.0", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_with_macros-3.14.0.bazel"), + urls = ["https://static.crates.io/crates/serde_with_macros/3.14.1/download"], + strip_prefix = "serde_with_macros-3.14.1", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_with_macros-3.14.1.bazel"), ) maybe( @@ -3218,12 +3228,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__toml-0.9.5", - sha256 = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8", + name = "vendor_ts__toml-0.9.7", + sha256 = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0", type = "tar.gz", - urls = ["https://static.crates.io/crates/toml/0.9.5/download"], - strip_prefix = "toml-0.9.5", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.toml-0.9.5.bazel"), + urls = ["https://static.crates.io/crates/toml/0.9.7/download"], + strip_prefix = "toml-0.9.7", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.toml-0.9.7.bazel"), ) maybe( @@ -3238,12 +3248,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__toml_datetime-0.7.0", - sha256 = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3", + name = "vendor_ts__toml_datetime-0.7.2", + sha256 = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1", type = "tar.gz", - urls = ["https://static.crates.io/crates/toml_datetime/0.7.0/download"], - strip_prefix = "toml_datetime-0.7.0", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.toml_datetime-0.7.0.bazel"), + urls = ["https://static.crates.io/crates/toml_datetime/0.7.2/download"], + strip_prefix = "toml_datetime-0.7.2", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.toml_datetime-0.7.2.bazel"), ) maybe( @@ -3258,12 +3268,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__toml_parser-1.0.2", - sha256 = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10", + name = "vendor_ts__toml_parser-1.0.3", + sha256 = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627", type = "tar.gz", - urls = ["https://static.crates.io/crates/toml_parser/1.0.2/download"], - strip_prefix = "toml_parser-1.0.2", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.toml_parser-1.0.2.bazel"), + urls = ["https://static.crates.io/crates/toml_parser/1.0.3/download"], + strip_prefix = "toml_parser-1.0.3", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.toml_parser-1.0.3.bazel"), ) maybe( @@ -3278,12 +3288,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__toml_writer-1.0.2", - sha256 = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64", + name = "vendor_ts__toml_writer-1.0.3", + sha256 = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109", type = "tar.gz", - urls = ["https://static.crates.io/crates/toml_writer/1.0.2/download"], - strip_prefix = "toml_writer-1.0.2", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.toml_writer-1.0.2.bazel"), + urls = ["https://static.crates.io/crates/toml_writer/1.0.3/download"], + strip_prefix = "toml_writer-1.0.3", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.toml_writer-1.0.3.bazel"), ) maybe( @@ -3358,12 +3368,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__tree-sitter-embedded-template-0.23.2", - sha256 = "790063ef14e5b67556abc0b3be0ed863fb41d65ee791cf8c0b20eb42a1fa46af", + name = "vendor_ts__tree-sitter-embedded-template-0.25.0", + sha256 = "833d528e8fcb4e49ddb04d4d6450ddb8ac08f282a58fec94ce981c9c5dbf7e3a", type = "tar.gz", - urls = ["https://static.crates.io/crates/tree-sitter-embedded-template/0.23.2/download"], - strip_prefix = "tree-sitter-embedded-template-0.23.2", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.tree-sitter-embedded-template-0.23.2.bazel"), + urls = ["https://static.crates.io/crates/tree-sitter-embedded-template/0.25.0/download"], + strip_prefix = "tree-sitter-embedded-template-0.25.0", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.tree-sitter-embedded-template-0.25.0.bazel"), ) maybe( @@ -4097,11 +4107,11 @@ def crate_repositories(): ) return [ - struct(repo = "vendor_ts__anyhow-1.0.99", is_dev_dep = False), + struct(repo = "vendor_ts__anyhow-1.0.100", is_dev_dep = False), struct(repo = "vendor_ts__argfile-0.2.1", is_dev_dep = False), struct(repo = "vendor_ts__chalk-ir-0.104.0", is_dev_dep = False), struct(repo = "vendor_ts__chrono-0.4.42", is_dev_dep = False), - struct(repo = "vendor_ts__clap-4.5.47", is_dev_dep = False), + struct(repo = "vendor_ts__clap-4.5.48", is_dev_dep = False), struct(repo = "vendor_ts__dunce-1.0.5", is_dev_dep = False), struct(repo = "vendor_ts__either-1.15.0", is_dev_dep = False), struct(repo = "vendor_ts__encoding-0.2.33", is_dev_dep = False), @@ -4115,7 +4125,7 @@ def crate_repositories(): struct(repo = "vendor_ts__num-traits-0.2.19", is_dev_dep = False), struct(repo = "vendor_ts__num_cpus-1.17.0", is_dev_dep = False), struct(repo = "vendor_ts__proc-macro2-1.0.101", is_dev_dep = False), - struct(repo = "vendor_ts__quote-1.0.40", is_dev_dep = False), + struct(repo = "vendor_ts__quote-1.0.41", is_dev_dep = False), struct(repo = "vendor_ts__ra_ap_base_db-0.0.301", is_dev_dep = False), struct(repo = "vendor_ts__ra_ap_cfg-0.0.301", is_dev_dep = False), struct(repo = "vendor_ts__ra_ap_hir-0.0.301", is_dev_dep = False), @@ -4133,17 +4143,17 @@ def crate_repositories(): struct(repo = "vendor_ts__ra_ap_syntax-0.0.301", is_dev_dep = False), struct(repo = "vendor_ts__ra_ap_vfs-0.0.301", is_dev_dep = False), struct(repo = "vendor_ts__rayon-1.11.0", is_dev_dep = False), - struct(repo = "vendor_ts__regex-1.11.2", is_dev_dep = False), - struct(repo = "vendor_ts__serde-1.0.219", is_dev_dep = False), - struct(repo = "vendor_ts__serde_json-1.0.143", is_dev_dep = False), - struct(repo = "vendor_ts__serde_with-3.14.0", is_dev_dep = False), + struct(repo = "vendor_ts__regex-1.11.3", is_dev_dep = False), + struct(repo = "vendor_ts__serde-1.0.228", is_dev_dep = False), + struct(repo = "vendor_ts__serde_json-1.0.145", is_dev_dep = False), + struct(repo = "vendor_ts__serde_with-3.14.1", is_dev_dep = False), struct(repo = "vendor_ts__syn-2.0.106", is_dev_dep = False), - struct(repo = "vendor_ts__toml-0.9.5", is_dev_dep = False), + struct(repo = "vendor_ts__toml-0.9.7", is_dev_dep = False), struct(repo = "vendor_ts__tracing-0.1.41", is_dev_dep = False), struct(repo = "vendor_ts__tracing-flame-0.2.0", is_dev_dep = False), struct(repo = "vendor_ts__tracing-subscriber-0.3.20", is_dev_dep = False), struct(repo = "vendor_ts__tree-sitter-0.25.9", is_dev_dep = False), - struct(repo = "vendor_ts__tree-sitter-embedded-template-0.23.2", is_dev_dep = False), + struct(repo = "vendor_ts__tree-sitter-embedded-template-0.25.0", is_dev_dep = False), struct(repo = "vendor_ts__tree-sitter-ruby-0.23.1", is_dev_dep = False), struct(repo = "vendor_ts__triomphe-0.1.14", is_dev_dep = False), struct(repo = "vendor_ts__ungrammar-1.16.1", is_dev_dep = False), From 16a11b48ad0e5c742e5a55c77bdf1810a4519662 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 10 Nov 2023 14:48:04 +0000 Subject: [PATCH 06/70] Switch to use-use dataflow. This will make post-update nodes easy to implement. Queries / tests that required changes: * The CleartextLogging and MissingErrorCheck queries are updated because they assumed def-use flow * The CommandInjection query works around the shortcomings of use-use flow by essentially reintroducing def-use flow when it applies a sanitizer * The OpenUrlRedirect query currently just accepts its fate; the tests are updated to avoid excess sanitization while the query comments on the problem. We should choose this approach or the CommandInjection one. --- go/ql/lib/semmle/go/dataflow/SSA.qll | 4 + go/ql/lib/semmle/go/dataflow/SsaImpl.qll | 141 ++++++ .../go/dataflow/internal/DataFlowPrivate.qll | 22 +- .../CleartextLoggingCustomizations.qll | 4 +- .../semmle/go/security/CommandInjection.qll | 22 + .../src/InconsistentCode/MissingErrorCheck.ql | 12 +- .../dataflow/FlowSteps/LocalFlowStep.expected | 87 ++-- .../go/frameworks/Echo/OpenRedirect.expected | 26 +- .../semmle/go/frameworks/Echo/test.go | 7 +- .../CWE-312/CleartextLogging.expected | 434 +++++++++++++----- .../test/query-tests/Security/CWE-312/main.go | 71 ++- .../query-tests/Security/CWE-312/passwords.go | 6 +- .../OpenUrlRedirect/OpenUrlRedirect.expected | 218 ++++----- .../CWE-601/OpenUrlRedirect/stdlib.go | 8 +- .../Security/CWE-918/RequestForgery.expected | 109 +++-- .../test/query-tests/Security/CWE-918/tst.go | 6 +- 16 files changed, 800 insertions(+), 377 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/SSA.qll b/go/ql/lib/semmle/go/dataflow/SSA.qll index d13bbe2de63..5891c0ed800 100644 --- a/go/ql/lib/semmle/go/dataflow/SSA.qll +++ b/go/ql/lib/semmle/go/dataflow/SSA.qll @@ -197,6 +197,8 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef { override string prettyPrintDef() { result = "definition of " + this.getSourceVariable() } override Location getLocation() { result = this.getInstruction().getLocation() } + + IR::Instruction getAFirstUse() { firstUse(this, result) } } /** Provides a helper predicate for working with explicit SSA definitions. */ @@ -410,3 +412,5 @@ DataFlow::Node getASimilarReadNode(DataFlow::Node node) { result = readFields.similar().getAUse() ) } + +IR::Instruction getAnAdjacentUse(IR::Instruction pred) { adjacentUseUse(pred, result) } diff --git a/go/ql/lib/semmle/go/dataflow/SsaImpl.qll b/go/ql/lib/semmle/go/dataflow/SsaImpl.qll index 0db37ac03ce..7380aaf60eb 100644 --- a/go/ql/lib/semmle/go/dataflow/SsaImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/SsaImpl.qll @@ -199,6 +199,8 @@ private module Internal { /** * Holds if the `i`th node of `bb` is a use or an SSA definition of variable `v`, with * `k` indicating whether it is the former or the latter. + * + * Note this includes phi nodes, whereas `ref` above only includes explicit writes and captures. */ private predicate ssaRef(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind k) { useAt(bb, i, v) and k = ReadRef() @@ -290,6 +292,145 @@ private module Internal { or rewindReads(bb, i, v) = 1 and result = getDefReachingEndOf(bb.getImmediateDominator(), v) } + + private module AdjacentUsesImpl { + /** Holds if `v` is defined or used in `b`. */ + private predicate varOccursInBlock(SsaSourceVariable v, ReachableBasicBlock b) { + ssaRef(b, _, v, _) + } + + /** Holds if `v` occurs in `b` or one of `b`'s transitive successors. */ + private predicate blockPrecedesVar(SsaSourceVariable v, ReachableBasicBlock b) { + varOccursInBlock(v, b) + or + exists(getDefReachingEndOf(b, v)) + } + + /** + * Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and + * in `b2` or one of its transitive successors but not in any block on the path + * between `b1` and `b2`. + */ + private predicate varBlockReaches( + SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2 + ) { + varOccursInBlock(v, b1) and + b2 = b1.getASuccessor() and + blockPrecedesVar(v, b2) + or + exists(ReachableBasicBlock mid | + varBlockReaches(v, b1, mid) and + b2 = mid.getASuccessor() and + not varOccursInBlock(v, mid) and + blockPrecedesVar(v, b2) + ) + } + + /** + * Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and + * `b2` but not in any block on the path between `b1` and `b2`. + */ + private predicate varBlockStep( + SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2 + ) { + varBlockReaches(v, b1, b2) and + varOccursInBlock(v, b2) + } + + /** + * Gets the maximum rank among all SSA references to `v` in basic block `bb`. + */ + private int maxSsaRefRank(ReachableBasicBlock bb, SsaSourceVariable v) { + result = max(ssaRefRank(bb, _, v, _)) + } + + /** + * Holds if `v` occurs at index `i1` in `b1` and at index `i2` in `b2` and + * there is a path between them without any occurrence of `v`. + */ + pragma[nomagic] + predicate adjacentVarRefs( + SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2 + ) { + exists(int rankix | + b1 = b2 and + ssaRefRank(b1, i1, v, _) = rankix and + ssaRefRank(b2, i2, v, _) = rankix + 1 + ) + or + maxSsaRefRank(b1, v) = ssaRefRank(b1, i1, v, _) and + varBlockStep(v, b1, b2) and + ssaRefRank(b2, i2, v, _) = 1 + } + + predicate variableUse(SsaSourceVariable v, IR::Instruction use, ReachableBasicBlock bb, int i) { + bb.getNode(i) = use and + exists(SsaVariable sv | + sv.getSourceVariable() = v and + use = sv.getAUse() + ) + } + } + + private import AdjacentUsesImpl + + /** + * Holds if the value defined at `def` can reach `use` without passing through + * any other uses, but possibly through phi nodes. + */ + cached + predicate firstUse(SsaDefinition def, IR::Instruction use) { + exists(SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2 | + adjacentVarRefs(v, b1, i1, b2, i2) and + def.definesAt(b1, i1, v) and + variableUse(v, use, b2, i2) + ) + or + exists( + SsaSourceVariable v, SsaPhiNode redef, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, + int i2 + | + adjacentVarRefs(v, b1, i1, b2, i2) and + def.definesAt(b1, i1, v) and + redef.definesAt(b2, i2, v) and + firstUse(redef, use) + ) + } + + /** + * Holds if `use1` and `use2` form an adjacent use-use-pair of the same SSA + * variable, that is, the value read in `use1` can reach `use2` without passing + * through any other use or any SSA definition of the variable. + */ + cached + predicate adjacentUseUseSameVar(IR::Instruction use1, IR::Instruction use2) { + exists(SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2 | + adjacentVarRefs(v, b1, i1, b2, i2) and + variableUse(v, use1, b1, i1) and + variableUse(v, use2, b2, i2) + ) + } + + /** + * Holds if `use1` and `use2` form an adjacent use-use-pair of the same + * `SsaSourceVariable`, that is, the value read in `use1` can reach `use2` + * without passing through any other use or any SSA definition of the variable + * except for phi nodes and uncertain implicit updates. + */ + cached + predicate adjacentUseUse(IR::Instruction use1, IR::Instruction use2) { + adjacentUseUseSameVar(use1, use2) + or + exists( + SsaSourceVariable v, SsaPhiNode def, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, + int i2 + | + adjacentVarRefs(v, b1, i1, b2, i2) and + variableUse(v, use1, b1, i1) and + def.definesAt(b2, i2, v) and + firstUse(def, use2) + ) + } } import Internal diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 2d05b211a57..15f8a8462a1 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -65,26 +65,36 @@ predicate basicLocalFlowStep(Node nodeFrom, Node nodeTo) { else nodeTo.asInstruction() = evalAssert ) or - // Instruction -> SSA + // Instruction -> SSA defn exists(IR::Instruction pred, SsaExplicitDefinition succ | succ.getRhs() = pred and nodeFrom = instructionNode(pred) and nodeTo = ssaNode(succ) ) or - // SSA -> SSA - exists(SsaDefinition pred, SsaPseudoDefinition succ | succ.getAnInput() = pred | + // SSA defn -> SSA capture + exists(SsaExplicitDefinition pred, SsaVariableCapture succ | + // Check: should these flow from PHIs as well? Perhaps they should be included + // in the use-use graph? + succ.(SsaVariableCapture).getSourceVariable() = pred.(SsaExplicitDefinition).getSourceVariable() + | nodeFrom = ssaNode(pred) and nodeTo = ssaNode(succ) ) or - // SSA -> Instruction - exists(SsaDefinition pred, IR::Instruction succ | - succ = pred.getVariable().getAUse() and + // SSA defn -> first SSA use + exists(SsaExplicitDefinition pred, IR::Instruction succ | succ = pred.getAFirstUse() | nodeFrom = ssaNode(pred) and nodeTo = instructionNode(succ) ) or + // SSA use -> successive SSA use + // Note this case includes Phi node traversal + exists(IR::Instruction pred, IR::Instruction succ | succ = getAnAdjacentUse(pred) | + nodeFrom = instructionNode(pred) and + nodeTo = instructionNode(succ) + ) + or // GlobalFunctionNode -> use nodeFrom = any(GlobalFunctionNode fn | fn.getFunction() = nodeTo.asExpr().(FunctionName).getTarget()) diff --git a/go/ql/lib/semmle/go/security/CleartextLoggingCustomizations.qll b/go/ql/lib/semmle/go/security/CleartextLoggingCustomizations.qll index 6c95686cb8c..4abc9021268 100644 --- a/go/ql/lib/semmle/go/security/CleartextLoggingCustomizations.qll +++ b/go/ql/lib/semmle/go/security/CleartextLoggingCustomizations.qll @@ -55,6 +55,8 @@ module CleartextLogging { | this.asExpr().(Ident).getName() = name or + this.(DataFlow::SsaNode).getSourceVariable().getName() = name + or this.(DataFlow::FieldReadNode).getFieldName() = name or this.(DataFlow::CallNode).getCalleeName() = name @@ -143,7 +145,7 @@ module CleartextLogging { not this instanceof NonCleartextPassword and name.regexpMatch(maybePassword()) and ( - this.asExpr().(Ident).getName() = name + this.(DataFlow::SsaNode).getSourceVariable().getName() = name or exists(DataFlow::FieldReadNode fn | fn = this and diff --git a/go/ql/lib/semmle/go/security/CommandInjection.qll b/go/ql/lib/semmle/go/security/CommandInjection.qll index 1774d77af54..face45358a9 100644 --- a/go/ql/lib/semmle/go/security/CommandInjection.qll +++ b/go/ql/lib/semmle/go/security/CommandInjection.qll @@ -84,6 +84,28 @@ module CommandInjection { } predicate observeDiffInformedIncrementalMode() { any() } + + // Hack: with use-use flow, we might have x (use at line 1) -> x (use at line 2), + // x (use at line 1) -> array at line 1 and x (use at line 2) -> array at line 2, + // in the context + // + // array1 := {"--", x} + // array2 := {x, "--"} + // + // We want to taint array2 but not array1, which suggests excluding the edge x (use 1) -> array1 + // However isSanitizer only allows us to remove nodes (isSanitizerIn/Out permit removing all outgoing + // or incoming edges); we can't remove an individual edge, so instead we supply extra edges connecting + // the definition with the next use. + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + exists( + ArgumentArrayWithDoubleDash array, DataFlow::InstructionNode sanitized, + DataFlow::SsaNode defn + | + sanitized = array.getASanitizedElement() and sanitized = defn.getAUse() + | + pred = defn and succ = sanitized.getASuccessor() + ) + } } /** diff --git a/go/ql/src/InconsistentCode/MissingErrorCheck.ql b/go/ql/src/InconsistentCode/MissingErrorCheck.ql index 6a68904427d..e16b8641a97 100644 --- a/go/ql/src/InconsistentCode/MissingErrorCheck.ql +++ b/go/ql/src/InconsistentCode/MissingErrorCheck.ql @@ -73,6 +73,16 @@ predicate checksValue(IR::Instruction instruction, DataFlow::SsaNode value) { ) } +// Now that we have use-use flow, phi nodes aren't directly involved in the flow graph. TODO: change this? +DataFlow::SsaNode phiDefinedFrom(DataFlow::SsaNode node) { + result.getDefinition().(SsaPseudoDefinition).getAnInput() = node.getDefinition().getVariable() +} + +DataFlow::SsaNode definedFrom(DataFlow::SsaNode node) { + DataFlow::localFlow(node, result) or + result = phiDefinedFrom*(node) +} + /** * Matches if `call` is a function returning (`ptr`, `err`) where `ptr` may be nil, and neither * `ptr` not `err` has been checked for validity as of `node`. @@ -99,7 +109,7 @@ predicate returnUncheckedAtNode( // localFlow is used to permit checks via either an SSA phi node or ordinary assignment. returnUncheckedAtNode(call, node.getAPredecessor(), ptr, err) and not exists(DataFlow::SsaNode checked | - DataFlow::localFlow(ptr, checked) or DataFlow::localFlow(err, checked) + checked = definedFrom(ptr) or checked = definedFrom(err) | checksValue(node, checked) ) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected index c6bfdfdc1d5..b48b6fec1a7 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected @@ -49,27 +49,28 @@ | main.go:3:6:3:10 | function test1 | main.go:34:2:34:6 | test1 | | main.go:3:12:3:12 | argument corresponding to x | main.go:3:12:3:12 | definition of x | | main.go:3:12:3:12 | definition of x | main.go:5:5:5:5 | x | -| main.go:3:12:3:12 | definition of x | main.go:6:7:6:7 | x | -| main.go:3:12:3:12 | definition of x | main.go:8:8:8:8 | x | -| main.go:3:12:3:12 | definition of x | main.go:10:7:10:7 | x | -| main.go:3:12:3:12 | definition of x | main.go:10:22:10:22 | x | | main.go:3:19:3:20 | argument corresponding to fn | main.go:3:19:3:20 | definition of fn | | main.go:3:19:3:20 | definition of fn | main.go:10:24:10:25 | fn | -| main.go:6:3:6:3 | definition of y | main.go:10:2:10:2 | y = phi(def@6:3, def@8:3) | +| main.go:5:5:5:5 | x | main.go:6:7:6:7 | x | +| main.go:5:5:5:5 | x | main.go:8:8:8:8 | x | +| main.go:6:3:6:3 | definition of y | main.go:10:12:10:12 | y | | main.go:6:7:6:7 | x | main.go:6:3:6:3 | definition of y | -| main.go:8:3:8:3 | definition of y | main.go:10:2:10:2 | y = phi(def@6:3, def@8:3) | +| main.go:6:7:6:7 | x | main.go:10:7:10:7 | x | +| main.go:8:3:8:3 | definition of y | main.go:10:12:10:12 | y | | main.go:8:7:8:8 | -... | main.go:8:3:8:3 | definition of y | +| main.go:8:8:8:8 | x | main.go:10:7:10:7 | x | | main.go:10:2:10:2 | definition of z | main.go:11:14:11:14 | z | -| main.go:10:2:10:2 | y = phi(def@6:3, def@8:3) | main.go:10:12:10:12 | y | -| main.go:10:2:10:2 | y = phi(def@6:3, def@8:3) | main.go:10:17:10:17 | y | +| main.go:10:7:10:7 | x | main.go:10:22:10:22 | x | | main.go:10:7:10:12 | ...<=... | main.go:10:7:10:27 | ...&&... | | main.go:10:7:10:27 | ...&&... | main.go:10:2:10:2 | definition of z | +| main.go:10:12:10:12 | y | main.go:10:17:10:17 | y | | main.go:10:17:10:27 | ...>=... | main.go:10:7:10:27 | ...&&... | | main.go:11:14:11:14 | z | main.go:11:9:11:15 | type conversion | | main.go:14:6:14:10 | function test2 | main.go:34:8:34:12 | test2 | | main.go:14:6:14:10 | function test2 | main.go:34:19:34:23 | test2 | +| main.go:15:2:15:4 | definition of acc | main.go:16:9:19:2 | capture variable acc | | main.go:15:9:15:9 | 0 | main.go:15:2:15:4 | definition of acc | -| main.go:16:9:19:2 | capture variable acc | main.go:17:3:17:5 | acc | +| main.go:17:3:17:7 | definition of acc | main.go:16:9:19:2 | capture variable acc | | main.go:17:3:17:7 | definition of acc | main.go:18:10:18:12 | acc | | main.go:17:3:17:7 | rhs of increment statement | main.go:17:3:17:7 | definition of acc | | main.go:22:12:22:12 | argument corresponding to b | main.go:22:12:22:12 | definition of b | @@ -84,50 +85,50 @@ | main.go:26:5:26:6 | definition of ok | main.go:27:5:27:6 | ok | | main.go:26:11:26:11 | x | main.go:26:2:26:17 | ... := ...[0] | | main.go:38:2:38:2 | definition of s | main.go:39:15:39:15 | s | -| main.go:38:2:38:2 | definition of s | main.go:40:15:40:15 | s | -| main.go:38:2:38:2 | definition of s | main.go:42:7:42:7 | s | | main.go:38:7:38:20 | slice literal | main.go:38:2:38:2 | definition of s | | main.go:39:2:39:3 | definition of s1 | main.go:40:18:40:19 | s1 | | main.go:39:8:39:25 | call to append | main.go:39:2:39:3 | definition of s1 | +| main.go:39:15:39:15 | s | main.go:40:15:40:15 | s | | main.go:40:2:40:3 | definition of s2 | main.go:43:9:43:10 | s2 | | main.go:40:8:40:23 | call to append | main.go:40:2:40:3 | definition of s2 | +| main.go:40:15:40:15 | s | main.go:42:7:42:7 | s | | main.go:41:2:41:3 | definition of s4 | main.go:42:10:42:11 | s4 | | main.go:41:8:41:21 | call to make | main.go:41:2:41:3 | definition of s4 | | main.go:46:13:46:14 | argument corresponding to xs | main.go:46:13:46:14 | definition of xs | | main.go:46:13:46:14 | definition of xs | main.go:47:20:47:21 | xs | -| main.go:46:24:46:27 | definition of keys | main.go:47:20:47:21 | keys = phi(def@46:24, def@49:3) | +| main.go:46:24:46:27 | definition of keys | main.go:46:24:46:27 | implicit read of keys | +| main.go:46:24:46:27 | definition of keys | main.go:49:3:49:6 | keys | | main.go:46:24:46:27 | zero value for keys | main.go:46:24:46:27 | definition of keys | -| main.go:46:34:46:37 | definition of vals | main.go:47:20:47:21 | vals = phi(def@46:34, def@48:3) | +| main.go:46:34:46:37 | definition of vals | main.go:46:34:46:37 | implicit read of vals | +| main.go:46:34:46:37 | definition of vals | main.go:48:3:48:6 | vals | | main.go:46:34:46:37 | zero value for vals | main.go:46:34:46:37 | definition of vals | | main.go:47:2:50:2 | range statement[0] | main.go:47:6:47:6 | definition of k | | main.go:47:2:50:2 | range statement[1] | main.go:47:9:47:9 | definition of v | | main.go:47:6:47:6 | definition of k | main.go:49:11:49:11 | k | | main.go:47:9:47:9 | definition of v | main.go:48:11:48:11 | v | -| main.go:47:20:47:21 | keys = phi(def@46:24, def@49:3) | main.go:46:24:46:27 | implicit read of keys | -| main.go:47:20:47:21 | keys = phi(def@46:24, def@49:3) | main.go:49:3:49:6 | keys | -| main.go:47:20:47:21 | vals = phi(def@46:34, def@48:3) | main.go:46:34:46:37 | implicit read of vals | -| main.go:47:20:47:21 | vals = phi(def@46:34, def@48:3) | main.go:48:3:48:6 | vals | -| main.go:48:3:48:6 | definition of vals | main.go:47:20:47:21 | vals = phi(def@46:34, def@48:3) | +| main.go:48:3:48:6 | definition of vals | main.go:46:34:46:37 | implicit read of vals | +| main.go:48:3:48:6 | definition of vals | main.go:48:3:48:6 | vals | | main.go:48:3:48:11 | ... += ... | main.go:48:3:48:6 | definition of vals | -| main.go:49:3:49:6 | definition of keys | main.go:47:20:47:21 | keys = phi(def@46:24, def@49:3) | +| main.go:49:3:49:6 | definition of keys | main.go:46:24:46:27 | implicit read of keys | +| main.go:49:3:49:6 | definition of keys | main.go:49:3:49:6 | keys | | main.go:49:3:49:11 | ... += ... | main.go:49:3:49:6 | definition of keys | | main.go:55:6:55:7 | definition of ch | main.go:56:2:56:3 | ch | -| main.go:55:6:55:7 | definition of ch | main.go:57:4:57:5 | ch | | main.go:55:6:55:7 | zero value for ch | main.go:55:6:55:7 | definition of ch | +| main.go:56:2:56:3 | ch | main.go:57:4:57:5 | ch | | main.go:61:2:61:2 | definition of x | main.go:64:11:64:11 | x | -| main.go:61:2:61:2 | definition of x | main.go:65:11:65:11 | x | | main.go:61:7:61:7 | 1 | main.go:61:2:61:2 | definition of x | | main.go:62:2:62:2 | definition of y | main.go:64:14:64:14 | y | -| main.go:62:2:62:2 | definition of y | main.go:65:14:65:14 | y | | main.go:62:7:62:7 | 2 | main.go:62:2:62:2 | definition of y | | main.go:63:2:63:2 | definition of z | main.go:64:17:64:17 | z | -| main.go:63:2:63:2 | definition of z | main.go:65:17:65:17 | z | | main.go:63:7:63:7 | 3 | main.go:63:2:63:2 | definition of z | | main.go:64:2:64:2 | definition of a | main.go:66:9:66:9 | a | | main.go:64:7:64:18 | call to min | main.go:64:2:64:2 | definition of a | | main.go:64:11:64:11 | x | main.go:64:7:64:18 | call to min | +| main.go:64:11:64:11 | x | main.go:65:11:65:11 | x | | main.go:64:14:64:14 | y | main.go:64:7:64:18 | call to min | +| main.go:64:14:64:14 | y | main.go:65:14:65:14 | y | | main.go:64:17:64:17 | z | main.go:64:7:64:18 | call to min | +| main.go:64:17:64:17 | z | main.go:65:17:65:17 | z | | main.go:65:2:65:2 | definition of b | main.go:66:12:66:12 | b | | main.go:65:7:65:18 | call to max | main.go:65:2:65:2 | definition of b | | main.go:65:11:65:11 | x | main.go:65:7:65:18 | call to max | @@ -135,62 +136,60 @@ | main.go:65:17:65:17 | z | main.go:65:7:65:18 | call to max | | strings.go:8:12:8:12 | argument corresponding to s | strings.go:8:12:8:12 | definition of s | | strings.go:8:12:8:12 | definition of s | strings.go:9:24:9:24 | s | -| strings.go:8:12:8:12 | definition of s | strings.go:10:27:10:27 | s | | strings.go:9:2:9:3 | definition of s2 | strings.go:11:20:11:21 | s2 | -| strings.go:9:2:9:3 | definition of s2 | strings.go:11:48:11:49 | s2 | | strings.go:9:8:9:38 | call to Replace | strings.go:9:2:9:3 | definition of s2 | +| strings.go:9:24:9:24 | s | strings.go:10:27:10:27 | s | | strings.go:10:2:10:3 | definition of s3 | strings.go:11:24:11:25 | s3 | -| strings.go:10:2:10:3 | definition of s3 | strings.go:11:67:11:68 | s3 | | strings.go:10:8:10:42 | call to ReplaceAll | strings.go:10:2:10:3 | definition of s3 | +| strings.go:11:20:11:21 | s2 | strings.go:11:48:11:49 | s2 | +| strings.go:11:24:11:25 | s3 | strings.go:11:67:11:68 | s3 | | url.go:8:12:8:12 | argument corresponding to b | url.go:8:12:8:12 | definition of b | | url.go:8:12:8:12 | definition of b | url.go:11:5:11:5 | b | | url.go:8:20:8:20 | argument corresponding to s | url.go:8:20:8:20 | definition of s | | url.go:8:20:8:20 | definition of s | url.go:12:46:12:46 | s | | url.go:8:20:8:20 | definition of s | url.go:14:48:14:48 | s | -| url.go:12:3:12:5 | definition of res | url.go:16:5:16:7 | res = phi(def@12:3, def@14:3) | +| url.go:12:3:12:5 | definition of res | url.go:19:9:19:11 | res | | url.go:12:3:12:48 | ... = ...[0] | url.go:12:3:12:5 | definition of res | | url.go:12:3:12:48 | ... = ...[1] | url.go:12:8:12:10 | definition of err | -| url.go:12:8:12:10 | definition of err | url.go:16:5:16:7 | err = phi(def@12:8, def@14:8) | -| url.go:14:3:14:5 | definition of res | url.go:16:5:16:7 | res = phi(def@12:3, def@14:3) | +| url.go:12:8:12:10 | definition of err | url.go:16:5:16:7 | err | +| url.go:14:3:14:5 | definition of res | url.go:19:9:19:11 | res | | url.go:14:3:14:50 | ... = ...[0] | url.go:14:3:14:5 | definition of res | | url.go:14:3:14:50 | ... = ...[1] | url.go:14:8:14:10 | definition of err | -| url.go:14:8:14:10 | definition of err | url.go:16:5:16:7 | err = phi(def@12:8, def@14:8) | -| url.go:16:5:16:7 | err = phi(def@12:8, def@14:8) | url.go:16:5:16:7 | err | -| url.go:16:5:16:7 | res = phi(def@12:3, def@14:3) | url.go:19:9:19:11 | res | +| url.go:14:8:14:10 | definition of err | url.go:16:5:16:7 | err | | url.go:22:12:22:12 | argument corresponding to i | url.go:22:12:22:12 | definition of i | | url.go:22:12:22:12 | definition of i | url.go:24:5:24:5 | i | | url.go:22:19:22:19 | argument corresponding to s | url.go:22:19:22:19 | definition of s | | url.go:22:19:22:19 | definition of s | url.go:23:20:23:20 | s | -| url.go:22:19:22:19 | definition of s | url.go:27:29:27:29 | s | | url.go:23:2:23:2 | definition of u | url.go:25:10:25:10 | u | | url.go:23:2:23:21 | ... := ...[0] | url.go:23:2:23:2 | definition of u | +| url.go:23:20:23:20 | s | url.go:27:29:27:29 | s | | url.go:27:2:27:2 | definition of u | url.go:28:14:28:14 | u | -| url.go:27:2:27:2 | definition of u | url.go:29:14:29:14 | u | -| url.go:27:2:27:2 | definition of u | url.go:30:11:30:11 | u | -| url.go:27:2:27:2 | definition of u | url.go:32:9:32:9 | u | | url.go:27:2:27:30 | ... = ...[0] | url.go:27:2:27:2 | definition of u | +| url.go:28:14:28:14 | u | url.go:29:14:29:14 | u | +| url.go:29:14:29:14 | u | url.go:30:11:30:11 | u | | url.go:30:2:30:3 | definition of bs | url.go:31:14:31:15 | bs | | url.go:30:2:30:27 | ... := ...[0] | url.go:30:2:30:3 | definition of bs | +| url.go:30:11:30:11 | u | url.go:32:9:32:9 | u | | url.go:32:2:32:2 | definition of u | url.go:33:14:33:14 | u | -| url.go:32:2:32:2 | definition of u | url.go:34:14:34:14 | u | -| url.go:32:2:32:2 | definition of u | url.go:35:14:35:14 | u | -| url.go:32:2:32:2 | definition of u | url.go:36:6:36:6 | u | -| url.go:32:2:32:2 | definition of u | url.go:36:25:36:25 | u | | url.go:32:2:32:23 | ... = ...[0] | url.go:32:2:32:2 | definition of u | +| url.go:33:14:33:14 | u | url.go:34:14:34:14 | u | +| url.go:34:14:34:14 | u | url.go:35:14:35:14 | u | +| url.go:35:14:35:14 | u | url.go:36:6:36:6 | u | | url.go:36:2:36:2 | definition of u | url.go:37:9:37:9 | u | +| url.go:36:6:36:6 | u | url.go:36:25:36:25 | u | | url.go:36:6:36:26 | call to ResolveReference | url.go:36:2:36:2 | definition of u | | url.go:42:2:42:3 | definition of ui | url.go:43:11:43:12 | ui | -| url.go:42:2:42:3 | definition of ui | url.go:45:14:45:15 | ui | -| url.go:42:2:42:3 | definition of ui | url.go:46:9:46:10 | ui | | url.go:42:7:42:38 | call to UserPassword | url.go:42:2:42:3 | definition of ui | | url.go:43:2:43:3 | definition of pw | url.go:44:14:44:15 | pw | | url.go:43:2:43:23 | ... := ...[0] | url.go:43:2:43:3 | definition of pw | +| url.go:43:11:43:12 | ui | url.go:45:14:45:15 | ui | +| url.go:45:14:45:15 | ui | url.go:46:9:46:10 | ui | | url.go:49:12:49:12 | argument corresponding to q | url.go:49:12:49:12 | definition of q | | url.go:49:12:49:12 | definition of q | url.go:50:25:50:25 | q | | url.go:50:2:50:2 | definition of v | url.go:51:14:51:14 | v | -| url.go:50:2:50:2 | definition of v | url.go:52:14:52:14 | v | -| url.go:50:2:50:2 | definition of v | url.go:53:9:53:9 | v | | url.go:50:2:50:26 | ... := ...[0] | url.go:50:2:50:2 | definition of v | +| url.go:51:14:51:14 | v | url.go:52:14:52:14 | v | +| url.go:52:14:52:14 | v | url.go:53:9:53:9 | v | | url.go:56:12:56:12 | argument corresponding to q | url.go:56:12:56:12 | definition of q | | url.go:56:12:56:12 | definition of q | url.go:57:29:57:29 | q | | url.go:57:2:57:8 | definition of joined1 | url.go:58:38:58:44 | joined1 | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected index 4b38e6e8c47..bebd53c1ac5 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected @@ -1,14 +1,14 @@ #select | test.go:173:20:173:24 | param | test.go:172:11:172:32 | call to Param | test.go:173:20:173:24 | param | This path to an untrusted URL redirection depends on a $@. | test.go:172:11:172:32 | call to Param | user-provided value | -| test.go:182:20:182:28 | ...+... | test.go:178:11:178:32 | call to Param | test.go:182:20:182:28 | ...+... | This path to an untrusted URL redirection depends on a $@. | test.go:178:11:178:32 | call to Param | user-provided value | +| test.go:185:20:185:29 | ...+... | test.go:178:11:178:32 | call to Param | test.go:185:20:185:29 | ...+... | This path to an untrusted URL redirection depends on a $@. | test.go:178:11:178:32 | call to Param | user-provided value | edges | test.go:172:11:172:32 | call to Param | test.go:173:20:173:24 | param | provenance | Src:MaD:2 Sink:MaD:1 | -| test.go:178:11:178:32 | call to Param | test.go:182:24:182:28 | param | provenance | Src:MaD:2 | -| test.go:182:24:182:28 | param | test.go:182:20:182:28 | ...+... | provenance | Config Sink:MaD:1 | -| test.go:190:9:190:26 | star expression | test.go:190:10:190:26 | selection of URL | provenance | Config | -| test.go:190:9:190:26 | star expression | test.go:193:21:193:23 | url | provenance | | -| test.go:190:10:190:26 | selection of URL | test.go:190:9:190:26 | star expression | provenance | Src:MaD:3 Config | -| test.go:193:21:193:23 | url | test.go:193:21:193:32 | call to String | provenance | Config Sink:MaD:1 | +| test.go:178:11:178:32 | call to Param | test.go:185:24:185:29 | param2 | provenance | Src:MaD:2 | +| test.go:185:24:185:29 | param2 | test.go:185:20:185:29 | ...+... | provenance | Config Sink:MaD:1 | +| test.go:193:9:193:26 | star expression | test.go:193:10:193:26 | selection of URL | provenance | Config | +| test.go:193:9:193:26 | star expression | test.go:196:21:196:23 | url | provenance | | +| test.go:193:10:193:26 | selection of URL | test.go:193:9:193:26 | star expression | provenance | Src:MaD:3 Config | +| test.go:196:21:196:23 | url | test.go:196:21:196:32 | call to String | provenance | Config Sink:MaD:1 | models | 1 | Sink: github.com/labstack/echo; Context; true; Redirect; ; ; Argument[1]; url-redirection; manual | | 2 | Source: github.com/labstack/echo; Context; true; Param; ; ; ReturnValue[0]; remote; manual | @@ -17,10 +17,10 @@ nodes | test.go:172:11:172:32 | call to Param | semmle.label | call to Param | | test.go:173:20:173:24 | param | semmle.label | param | | test.go:178:11:178:32 | call to Param | semmle.label | call to Param | -| test.go:182:20:182:28 | ...+... | semmle.label | ...+... | -| test.go:182:24:182:28 | param | semmle.label | param | -| test.go:190:9:190:26 | star expression | semmle.label | star expression | -| test.go:190:10:190:26 | selection of URL | semmle.label | selection of URL | -| test.go:193:21:193:23 | url | semmle.label | url | -| test.go:193:21:193:32 | call to String | semmle.label | call to String | +| test.go:185:20:185:29 | ...+... | semmle.label | ...+... | +| test.go:185:24:185:29 | param2 | semmle.label | param2 | +| test.go:193:9:193:26 | star expression | semmle.label | star expression | +| test.go:193:10:193:26 | selection of URL | semmle.label | selection of URL | +| test.go:196:21:196:23 | url | semmle.label | url | +| test.go:196:21:196:32 | call to String | semmle.label | call to String | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go b/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go index 45f92cd19cb..a15fb819ccc 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go @@ -176,12 +176,15 @@ func testRedirect(ctx echo.Context) error { func testLocalRedirects(ctx echo.Context) error { param := ctx.Param("someParam") + param2 := param + param3 := param + // Gratuitious copy because sanitization of uses propagates to subsequent uses // GOOD: local redirects are unproblematic ctx.Redirect(301, "/local"+param) // BAD: this could be a non-local redirect - ctx.Redirect(301, "/"+param) + ctx.Redirect(301, "/"+param2) // GOOD: localhost redirects are unproblematic - ctx.Redirect(301, "//localhost/"+param) + ctx.Redirect(301, "//localhost/"+param3) return nil } 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 a7f7f83a9ff..90d182b144b 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -1,97 +1,235 @@ #select | klog.go:23:15:23:20 | header | klog.go:21:30:21:37 | selection of Header | klog.go:23:15:23:20 | header | $@ flows to a logging call. | klog.go:21:30:21:37 | selection of Header | Sensitive data returned by HTTP request headers | | klog.go:29:13:29:41 | call to Get | klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | $@ flows to a logging call. | klog.go:29:13:29:20 | selection of Header | Sensitive data returned by HTTP request headers | -| main.go:16:12:16:19 | password | main.go:16:12:16:19 | password | main.go:16:12:16:19 | password | $@ flows to a logging call. | main.go:16:12:16:19 | password | Sensitive data returned by an access to password | -| main.go:17:19:17:26 | password | main.go:17:19:17:26 | password | main.go:17:19:17:26 | password | $@ flows to a logging call. | main.go:17:19:17:26 | password | Sensitive data returned by an access to password | -| main.go:18:13:18:20 | password | main.go:18:13:18:20 | password | main.go:18:13:18:20 | password | $@ flows to a logging call. | main.go:18:13:18:20 | password | Sensitive data returned by an access to password | -| main.go:19:14:19:21 | password | main.go:19:14:19:21 | password | main.go:19:14:19:21 | password | $@ flows to a logging call. | main.go:19:14:19:21 | password | Sensitive data returned by an access to password | -| main.go:20:12:20:19 | password | main.go:20:12:20:19 | password | main.go:20:12:20:19 | password | $@ flows to a logging call. | main.go:20:12:20:19 | password | Sensitive data returned by an access to password | -| main.go:21:19:21:26 | password | main.go:21:19:21:26 | password | main.go:21:19:21:26 | password | $@ flows to a logging call. | main.go:21:19:21:26 | password | Sensitive data returned by an access to password | -| main.go:22:13:22:20 | password | main.go:22:13:22:20 | password | main.go:22:13:22:20 | password | $@ flows to a logging call. | main.go:22:13:22:20 | password | Sensitive data returned by an access to password | -| main.go:23:14:23:21 | password | main.go:23:14:23:21 | password | main.go:23:14:23:21 | password | $@ flows to a logging call. | main.go:23:14:23:21 | password | Sensitive data returned by an access to password | -| main.go:24:12:24:19 | password | main.go:24:12:24:19 | password | main.go:24:12:24:19 | password | $@ flows to a logging call. | main.go:24:12:24:19 | password | Sensitive data returned by an access to password | -| main.go:25:19:25:26 | password | main.go:25:19:25:26 | password | main.go:25:19:25:26 | password | $@ flows to a logging call. | main.go:25:19:25:26 | password | Sensitive data returned by an access to password | -| main.go:26:13:26:20 | password | main.go:26:13:26:20 | password | main.go:26:13:26:20 | password | $@ flows to a logging call. | main.go:26:13:26:20 | password | Sensitive data returned by an access to password | -| main.go:27:14:27:21 | password | main.go:27:14:27:21 | password | main.go:27:14:27:21 | password | $@ flows to a logging call. | main.go:27:14:27:21 | password | Sensitive data returned by an access to password | -| main.go:28:16:28:23 | password | main.go:28:16:28:23 | password | main.go:28:16:28:23 | password | $@ flows to a logging call. | main.go:28:16:28:23 | password | Sensitive data returned by an access to password | -| main.go:32:10:32:17 | password | main.go:32:10:32:17 | password | main.go:32:10:32:17 | password | $@ flows to a logging call. | main.go:32:10:32:17 | password | Sensitive data returned by an access to password | -| main.go:33:17:33:24 | password | main.go:33:17:33:24 | password | main.go:33:17:33:24 | password | $@ flows to a logging call. | main.go:33:17:33:24 | password | Sensitive data returned by an access to password | -| main.go:34:11:34:18 | password | main.go:34:11:34:18 | password | main.go:34:11:34:18 | password | $@ flows to a logging call. | main.go:34:11:34:18 | password | Sensitive data returned by an access to password | -| main.go:35:12:35:19 | password | main.go:35:12:35:19 | password | main.go:35:12:35:19 | password | $@ flows to a logging call. | main.go:35:12:35:19 | password | Sensitive data returned by an access to password | -| main.go:36:10:36:17 | password | main.go:36:10:36:17 | password | main.go:36:10:36:17 | password | $@ flows to a logging call. | main.go:36:10:36:17 | password | Sensitive data returned by an access to password | -| main.go:37:17:37:24 | password | main.go:37:17:37:24 | password | main.go:37:17:37:24 | password | $@ flows to a logging call. | main.go:37:17:37:24 | password | Sensitive data returned by an access to password | -| main.go:38:11:38:18 | password | main.go:38:11:38:18 | password | main.go:38:11:38:18 | password | $@ flows to a logging call. | main.go:38:11:38:18 | password | Sensitive data returned by an access to password | -| main.go:39:12:39:19 | password | main.go:39:12:39:19 | password | main.go:39:12:39:19 | password | $@ flows to a logging call. | main.go:39:12:39:19 | password | Sensitive data returned by an access to password | -| main.go:40:10:40:17 | password | main.go:40:10:40:17 | password | main.go:40:10:40:17 | password | $@ flows to a logging call. | main.go:40:10:40:17 | password | Sensitive data returned by an access to password | -| main.go:41:17:41:24 | password | main.go:41:17:41:24 | password | main.go:41:17:41:24 | password | $@ flows to a logging call. | main.go:41:17:41:24 | password | Sensitive data returned by an access to password | -| main.go:42:11:42:18 | password | main.go:42:11:42:18 | password | main.go:42:11:42:18 | password | $@ flows to a logging call. | main.go:42:11:42:18 | password | Sensitive data returned by an access to password | -| main.go:43:12:43:19 | password | main.go:43:12:43:19 | password | main.go:43:12:43:19 | password | $@ flows to a logging call. | main.go:43:12:43:19 | password | Sensitive data returned by an access to password | -| main.go:44:14:44:21 | password | main.go:44:14:44:21 | password | main.go:44:14:44:21 | password | $@ flows to a logging call. | main.go:44:14:44:21 | password | Sensitive data returned by an access to password | -| main.go:47:12:47:19 | password | main.go:47:12:47:19 | password | main.go:47:12:47:19 | password | $@ flows to a logging call. | main.go:47:12:47:19 | password | Sensitive data returned by an access to password | -| main.go:48:17:48:24 | password | main.go:48:17:48:24 | password | main.go:48:17:48:24 | password | $@ flows to a logging call. | main.go:48:17:48:24 | password | Sensitive data returned by an access to password | -| main.go:55:35:55:42 | password | main.go:55:35:55:42 | password | main.go:55:35:55:42 | password | $@ flows to a logging call. | main.go:55:35:55:42 | password | Sensitive data returned by an access to password | -| 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 | -| 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 | -| 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 | +| main.go:19:12:19:19 | password | main.go:17:2:17:9 | definition of password | main.go:19:12:19:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:20:19:20:26 | password | main.go:17:2:17:9 | definition of password | main.go:20:19:20:26 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:21:13:21:20 | password | main.go:17:2:17:9 | definition of password | main.go:21:13:21:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:22:14:22:21 | password | main.go:17:2:17:9 | definition of password | main.go:22:14:22:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:24:13:24:20 | password | main.go:17:2:17:9 | definition of password | main.go:24:13:24:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:27:20:27:27 | password | main.go:17:2:17:9 | definition of password | main.go:27:20:27:27 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:30:14:30:21 | password | main.go:17:2:17:9 | definition of password | main.go:30:14:30:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:33:15:33:22 | password | main.go:17:2:17:9 | definition of password | main.go:33:15:33:22 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:36:13:36:20 | password | main.go:17:2:17:9 | definition of password | main.go:36:13:36:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:39:20:39:27 | password | main.go:17:2:17:9 | definition of password | main.go:39:20:39:27 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:42:14:42:21 | password | main.go:17:2:17:9 | definition of password | main.go:42:14:42:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:45:15:45:22 | password | main.go:17:2:17:9 | definition of password | main.go:45:15:45:22 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:47:16:47:23 | password | main.go:17:2:17:9 | definition of password | main.go:47:16:47:23 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:51:10:51:17 | password | main.go:17:2:17:9 | definition of password | main.go:51:10:51:17 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:52:17:52:24 | password | main.go:17:2:17:9 | definition of password | main.go:52:17:52:24 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:53:11:53:18 | password | main.go:17:2:17:9 | definition of password | main.go:53:11:53:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:54:12:54:19 | password | main.go:17:2:17:9 | definition of password | main.go:54:12:54:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:56:11:56:18 | password | main.go:17:2:17:9 | definition of password | main.go:56:11:56:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:59:18:59:25 | password | main.go:17:2:17:9 | definition of password | main.go:59:18:59:25 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:62:12:62:19 | password | main.go:17:2:17:9 | definition of password | main.go:62:12:62:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:65:13:65:20 | password | main.go:17:2:17:9 | definition of password | main.go:65:13:65:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:68:11:68:18 | password | main.go:17:2:17:9 | definition of password | main.go:68:11:68:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:71:18:71:25 | password | main.go:17:2:17:9 | definition of password | main.go:71:18:71:25 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:74:12:74:19 | password | main.go:17:2:17:9 | definition of password | main.go:74:12:74:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:77:13:77:20 | password | main.go:17:2:17:9 | definition of password | main.go:77:13:77:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:79:14:79:21 | password | main.go:17:2:17:9 | definition of password | main.go:79:14:79:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:82:12:82:19 | password | main.go:17:2:17:9 | definition of password | main.go:82:12:82:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:83:17:83:24 | password | main.go:17:2:17:9 | definition of password | main.go:83:17:83:24 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:87:29:87:34 | fields | main.go:17:2:17:9 | definition of password | main.go:87:29:87:34 | fields | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| main.go:90:35:90:42 | password | main.go:17:2:17:9 | definition of password | main.go:90:35:90:42 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password | +| overrides.go:13:14:13:23 | call to String | overrides.go:8:2:8:9 | definition of password | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:8:2:8:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:9:14:9:14 | x | passwords.go:21:2:21:9 | definition of password | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:25:14:25:21 | password | passwords.go:21:2:21:9 | definition of password | passwords.go:25:14:25:21 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | | 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 | | 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 | | 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 | -| 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 | -| 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 | +| passwords.go:32:12:32:19 | password | passwords.go:21:2:21:9 | definition of password | passwords.go:32:12:32:19 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:34:14:34:35 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:34:14:34:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | | 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 | -| passwords.go:44:14:44:17 | obj2 | passwords.go:42:6:42:13 | password | passwords.go:44:14:44:17 | obj2 | $@ flows to a logging call. | passwords.go:42:6:42:13 | password | Sensitive data returned by an access to password | -| passwords.go:47:14:47:17 | obj3 | passwords.go:48:11:48:18 | password | passwords.go:47:14:47:17 | obj3 | $@ flows to a logging call. | passwords.go:48:11:48:18 | password | Sensitive data returned by an access to password | -| passwords.go:51:14:51:27 | fixed_password | passwords.go:51:14:51:27 | fixed_password | passwords.go:51:14:51:27 | fixed_password | $@ flows to a logging call. | passwords.go:51:14:51:27 | fixed_password | Sensitive data returned by an access to fixed_password | -| passwords.go:88:14:88:26 | utilityObject | passwords.go:86:16:86:36 | call to make | passwords.go:88:14:88:26 | utilityObject | $@ flows to a logging call. | passwords.go:86:16:86:36 | call to make | Sensitive data returned by an access to passwordSet | -| passwords.go:91:23:91:28 | secret | passwords.go:90:12:90:19 | password | passwords.go:91:23:91:28 | secret | $@ flows to a logging call. | passwords.go:90:12:90:19 | password | Sensitive data returned by an access to password | -| passwords.go:101:15:101:40 | ...+... | passwords.go:101:33:101:40 | password | passwords.go:101:15:101:40 | ...+... | $@ flows to a logging call. | passwords.go:101:33:101:40 | password | Sensitive data returned by an access to password | -| passwords.go:107:16:107:41 | ...+... | passwords.go:107:34:107:41 | password | passwords.go:107:16:107:41 | ...+... | $@ flows to a logging call. | passwords.go:107:34:107:41 | password | Sensitive data returned by an access to password | -| passwords.go:112:15:112:40 | ...+... | passwords.go:112:33:112:40 | password | passwords.go:112:15:112:40 | ...+... | $@ flows to a logging call. | passwords.go:112:33:112:40 | password | Sensitive data returned by an access to password | -| passwords.go:116:14:116:45 | ...+... | passwords.go:116:28:116:36 | password1 | passwords.go:116:14:116:45 | ...+... | $@ flows to a logging call. | passwords.go:116:28:116:36 | password1 | Sensitive data returned by an access to password1 | -| passwords.go:125:14:125:19 | config | passwords.go:119:13:119:13 | x | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:119:13:119:13 | x | Sensitive data returned by an access to password | -| passwords.go:125:14:125:19 | config | passwords.go:121:13:121:20 | password | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:121:13:121:20 | password | Sensitive data returned by an access to password | -| passwords.go:125:14:125:19 | config | passwords.go:122:13:122:25 | call to getPassword | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword | -| passwords.go:126:14:126:21 | selection of x | passwords.go:121:13:121:20 | password | passwords.go:126:14:126:21 | selection of x | $@ flows to a logging call. | passwords.go:121:13:121:20 | password | Sensitive data returned by an access to password | -| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword | passwords.go:127:14:127:21 | selection of y | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword | -| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:12:22:12:29 | password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:12:22:12:29 | password | Sensitive data returned by an access to password | +| passwords.go:44:14:44:17 | obj2 | passwords.go:21:2:21:9 | definition of password | passwords.go:44:14:44:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:47:14:47:17 | obj3 | passwords.go:21:2:21:9 | definition of password | passwords.go:47:14:47:17 | obj3 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:51:14:51:27 | fixed_password | passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | $@ flows to a logging call. | passwords.go:50:2:50:15 | definition of fixed_password | Sensitive data returned by an access to fixed_password | +| passwords.go:89:14:89:26 | utilityObject | passwords.go:87:16:87:36 | call to make | passwords.go:89:14:89:26 | utilityObject | $@ flows to a logging call. | passwords.go:87:16:87:36 | call to make | Sensitive data returned by an access to passwordSet | +| passwords.go:92:23:92:28 | secret | passwords.go:21:2:21:9 | definition of password | passwords.go:92:23:92:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:102:15:102:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:102:15:102:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:108:16:108:41 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:108:16:108:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:113:15:113:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:113:15:113:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:117:14:117:45 | ...+... | passwords.go:116:6:116:14 | definition of password1 | passwords.go:117:14:117:45 | ...+... | $@ flows to a logging call. | passwords.go:116:6:116:14 | definition of password1 | Sensitive data returned by an access to password1 | +| passwords.go:127:14:127:19 | config | passwords.go:21:2:21:9 | definition of password | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:127:14:127:19 | config | passwords.go:121:13:121:14 | x3 | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:121:13:121:14 | x3 | Sensitive data returned by an access to password | +| passwords.go:127:14:127:19 | config | passwords.go:124:13:124:25 | call to getPassword | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:124:13:124:25 | call to getPassword | Sensitive data returned by a call to getPassword | +| passwords.go:128:14:128:21 | selection of x | passwords.go:21:2:21:9 | definition of password | passwords.go:128:14:128:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:129:14:129:21 | selection of y | passwords.go:124:13:124:25 | call to getPassword | passwords.go:129:14:129:21 | selection of y | $@ flows to a logging call. | passwords.go:124:13:124:25 | call to getPassword | Sensitive data returned by a call to getPassword | +| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:9 | definition of password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:9 | definition of password | Sensitive data returned by an access to password | edges | klog.go:21:3:26:3 | range statement[1] | klog.go:22:27:22:33 | headers | provenance | | -| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | range statement[1] | provenance | Src:MaD:1 Config | +| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | range statement[1] | provenance | Src:MaD:11 Config | | klog.go:22:4:25:4 | range statement[1] | klog.go:23:15:23:20 | header | provenance | | | klog.go:22:27:22:33 | headers | klog.go:22:4:25:4 | range statement[1] | provenance | Config | -| klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | provenance | Src:MaD:1 Config | +| klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | provenance | Src:MaD:11 Config | +| main.go:17:2:17:9 | definition of password | main.go:19:12:19:19 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:20:19:20:26 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:21:13:21:20 | password | provenance | Sink:MaD:6 | +| main.go:17:2:17:9 | definition of password | main.go:22:14:22:21 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:24:13:24:20 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:27:20:27:27 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:30:14:30:21 | password | provenance | Sink:MaD:3 | +| main.go:17:2:17:9 | definition of password | main.go:33:15:33:22 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:36:13:36:20 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:39:20:39:27 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:42:14:42:21 | password | provenance | Sink:MaD:5 | +| main.go:17:2:17:9 | definition of password | main.go:45:15:45:22 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:47:16:47:23 | password | provenance | Sink:MaD:4 | +| main.go:17:2:17:9 | definition of password | main.go:51:10:51:17 | password | provenance | | +| main.go:17:2:17:9 | definition of password | main.go:51:10:51:17 | password | provenance | | +| main.go:51:10:51:17 | password | main.go:52:17:52:24 | password | provenance | | +| main.go:51:10:51:17 | password | main.go:52:17:52:24 | password | provenance | | +| main.go:52:17:52:24 | password | main.go:53:11:53:18 | password | provenance | | +| main.go:52:17:52:24 | password | main.go:53:11:53:18 | password | provenance | Sink:MaD:10 | +| main.go:53:11:53:18 | password | main.go:54:12:54:19 | password | provenance | | +| main.go:53:11:53:18 | password | main.go:54:12:54:19 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:56:11:56:18 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:56:11:56:18 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:59:18:59:25 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:59:18:59:25 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:62:12:62:19 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 | +| main.go:54:12:54:19 | password | main.go:65:13:65:20 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:65:13:65:20 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:74:12:74:19 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | +| main.go:54:12:54:19 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:54:12:54:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:54:12:54:19 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:59:18:59:25 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:59:18:59:25 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:62:12:62:19 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 | +| main.go:56:11:56:18 | password | main.go:65:13:65:20 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:65:13:65:20 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:74:12:74:19 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | +| main.go:56:11:56:18 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:56:11:56:18 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:56:11:56:18 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:62:12:62:19 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 | +| main.go:59:18:59:25 | password | main.go:65:13:65:20 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:65:13:65:20 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:74:12:74:19 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | +| main.go:59:18:59:25 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:59:18:59:25 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:59:18:59:25 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:65:13:65:20 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:65:13:65:20 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:74:12:74:19 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | +| main.go:62:12:62:19 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:62:12:62:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:62:12:62:19 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:65:13:65:20 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:65:13:65:20 | password | main.go:68:11:68:18 | password | provenance | | +| main.go:65:13:65:20 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:65:13:65:20 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:65:13:65:20 | password | main.go:74:12:74:19 | password | provenance | | +| main.go:65:13:65:20 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | +| main.go:65:13:65:20 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:65:13:65:20 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:65:13:65:20 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:65:13:65:20 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:68:11:68:18 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:68:11:68:18 | password | main.go:71:18:71:25 | password | provenance | | +| main.go:68:11:68:18 | password | main.go:74:12:74:19 | password | provenance | | +| main.go:68:11:68:18 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | +| main.go:68:11:68:18 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:68:11:68:18 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:68:11:68:18 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:68:11:68:18 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:71:18:71:25 | password | main.go:74:12:74:19 | password | provenance | | +| main.go:71:18:71:25 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | +| main.go:71:18:71:25 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:71:18:71:25 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:71:18:71:25 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:71:18:71:25 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:74:12:74:19 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:74:12:74:19 | password | main.go:77:13:77:20 | password | provenance | | +| main.go:74:12:74:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:74:12:74:19 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:77:13:77:20 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | +| main.go:77:13:77:20 | password | main.go:80:17:80:24 | password | provenance | | +| main.go:80:17:80:24 | password | main.go:82:12:82:19 | password | provenance | | +| main.go:80:17:80:24 | password | main.go:83:17:83:24 | password | provenance | | +| main.go:80:17:80:24 | password | main.go:86:19:86:26 | password | provenance | | +| main.go:85:2:85:7 | definition of fields | main.go:87:29:87:34 | fields | provenance | Sink:MaD:2 | +| main.go:86:19:86:26 | password | main.go:85:2:85:7 | definition of fields | provenance | Config | +| main.go:86:19:86:26 | password | main.go:90:35:90:42 | password | provenance | Sink:MaD:1 | +| overrides.go:8:2:8:9 | definition of password | overrides.go:9:9:9:16 | password | provenance | | | overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | provenance | | | passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | provenance | | +| passwords.go:21:2:21:9 | definition of password | passwords.go:25:14:25:21 | password | provenance | | +| passwords.go:21:2:21:9 | definition of password | passwords.go:30:8:30:15 | password | provenance | | +| passwords.go:21:2:21:9 | definition of password | passwords.go:32:12:32:19 | password | provenance | | +| passwords.go:21:2:21:9 | definition of password | passwords.go:34:28:34:35 | password | provenance | | | passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | | | passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | provenance | Config | +| passwords.go:34:28:34:35 | password | passwords.go:42:6:42:13 | password | provenance | | | passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | | | passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal | provenance | Config | | passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | | | passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal | provenance | Config | +| passwords.go:42:6:42:13 | password | passwords.go:48:11:48:18 | password | provenance | | | passwords.go:46:6:46:9 | definition of obj3 | passwords.go:47:14:47:17 | obj3 | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:46:6:46:9 | definition of obj3 | provenance | Config | -| passwords.go:85:19:87:2 | struct literal | passwords.go:88:14:88:26 | utilityObject | provenance | | -| passwords.go:86:16:86:36 | call to make | passwords.go:85:19:87:2 | struct literal | provenance | Config | -| passwords.go:90:12:90:19 | password | passwords.go:91:23:91:28 | secret | provenance | | -| passwords.go:101:33:101:40 | password | passwords.go:101:15:101:40 | ...+... | provenance | Config | -| passwords.go:107:34:107:41 | password | passwords.go:107:16:107:41 | ...+... | provenance | Config | -| passwords.go:112:33:112:40 | password | passwords.go:112:15:112:40 | ...+... | provenance | Config | -| passwords.go:116:28:116:36 | password1 | passwords.go:116:28:116:45 | call to String | provenance | Config | -| passwords.go:116:28:116:45 | call to String | passwords.go:116:14:116:45 | ...+... | provenance | Config | -| 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:126:14:126:19 | config [x] | provenance | | -| passwords.go:118:12:123:2 | struct literal [y] | passwords.go:127:14:127:19 | 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 | | -| passwords.go:122:13:122:25 | call to getPassword | passwords.go:118:12:123:2 | struct literal | provenance | Config | -| passwords.go:122:13:122:25 | call to getPassword | passwords.go:118:12:123:2 | struct literal [y] | provenance | | -| passwords.go:126:14:126:19 | config [x] | passwords.go:126:14:126:21 | selection of x | provenance | | -| passwords.go:127:14:127:19 | config [y] | passwords.go:127:14:127:21 | selection of y | provenance | | +| passwords.go:48:11:48:18 | password | passwords.go:92:23:92:28 | secret | provenance | | +| passwords.go:48:11:48:18 | password | passwords.go:102:33:102:40 | password | provenance | | +| passwords.go:48:11:48:18 | password | passwords.go:108:34:108:41 | password | provenance | | +| passwords.go:48:11:48:18 | password | passwords.go:113:33:113:40 | password | provenance | | +| passwords.go:48:11:48:18 | password | passwords.go:123:13:123:20 | password | provenance | | +| passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | provenance | | +| passwords.go:86:19:88:2 | struct literal | passwords.go:89:14:89:26 | utilityObject | provenance | | +| passwords.go:87:16:87:36 | call to make | passwords.go:86:19:88:2 | struct literal | provenance | Config | +| passwords.go:102:33:102:40 | password | passwords.go:102:15:102:40 | ...+... | provenance | Config | +| passwords.go:102:33:102:40 | password | passwords.go:108:34:108:41 | password | provenance | | +| passwords.go:102:33:102:40 | password | passwords.go:113:33:113:40 | password | provenance | | +| passwords.go:102:33:102:40 | password | passwords.go:123:13:123:20 | password | provenance | | +| passwords.go:108:34:108:41 | password | passwords.go:108:16:108:41 | ...+... | provenance | Config | +| passwords.go:108:34:108:41 | password | passwords.go:113:33:113:40 | password | provenance | | +| passwords.go:108:34:108:41 | password | passwords.go:123:13:123:20 | password | provenance | | +| passwords.go:113:33:113:40 | password | passwords.go:113:15:113:40 | ...+... | provenance | Config | +| passwords.go:113:33:113:40 | password | passwords.go:123:13:123:20 | password | provenance | | +| passwords.go:116:6:116:14 | definition of password1 | passwords.go:117:28:117:36 | password1 | provenance | | +| passwords.go:117:28:117:36 | password1 | passwords.go:117:28:117:45 | call to String | provenance | Config | +| passwords.go:117:28:117:45 | call to String | passwords.go:117:14:117:45 | ...+... | provenance | Config | +| passwords.go:120:12:125:2 | struct literal | passwords.go:127:14:127:19 | config | provenance | | +| passwords.go:120:12:125:2 | struct literal [x] | passwords.go:128:14:128:19 | config [x] | provenance | | +| passwords.go:120:12:125:2 | struct literal [y] | passwords.go:129:14:129:19 | config [y] | provenance | | +| passwords.go:121:13:121:14 | x3 | passwords.go:120:12:125:2 | struct literal | provenance | Config | +| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal | provenance | Config | +| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [x] | provenance | | +| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal | provenance | Config | +| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [y] | provenance | | +| passwords.go:128:14:128:19 | config [x] | passwords.go:128:14:128:21 | selection of x | provenance | | +| passwords.go:129:14:129:19 | config [y] | passwords.go:129:14:129:21 | selection of y | provenance | | +| protobuf.go:9:2:9:9 | definition of password | protobuf.go:12:22:12:29 | password | provenance | | | protobuf.go:11:2:11:6 | definition of query [pointer, Description] | protobuf.go:12:2:12:6 | query [pointer, Description] | provenance | | -| protobuf.go:11:2:11:6 | definition of query [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | | | protobuf.go:12:2:12:6 | implicit dereference [Description] | protobuf.go:11:2:11:6 | definition of query [pointer, Description] | provenance | | | protobuf.go:12:2:12:6 | query [pointer, Description] | protobuf.go:12:2:12:6 | implicit dereference [Description] | provenance | | +| protobuf.go:12:2:12:6 | query [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | | | protobuf.go:12:22:12:29 | password | protobuf.go:12:2:12:6 | implicit dereference [Description] | provenance | | | protobuf.go:14:14:14:18 | query [pointer, Description] | protobuf.go:14:14:14:35 | call to GetDescription | provenance | | | protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | provenance | | @@ -99,7 +237,17 @@ edges | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | provenance | | | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | provenance | | models -| 1 | Source: net/http; Request; true; Header; ; ; ; remote; manual | +| 1 | Sink: group:logrus; ; false; WithField; ; ; Argument[0..1]; log-injection; manual | +| 2 | Sink: group:logrus; ; false; WithFields; ; ; Argument[0]; log-injection; manual | +| 3 | Sink: log; ; false; Fatalf; ; ; Argument[0..1]; log-injection; manual | +| 4 | Sink: log; ; false; Output; ; ; Argument[1]; log-injection; manual | +| 5 | Sink: log; ; false; Panicf; ; ; Argument[0..1]; log-injection; manual | +| 6 | Sink: log; ; false; Printf; ; ; Argument[0..1]; log-injection; manual | +| 7 | Sink: log; Logger; true; Fatalf; ; ; Argument[0..1]; log-injection; manual | +| 8 | Sink: log; Logger; true; Output; ; ; Argument[1]; log-injection; manual | +| 9 | Sink: log; Logger; true; Panicf; ; ; Argument[0..1]; log-injection; manual | +| 10 | Sink: log; Logger; true; Printf; ; ; Argument[0..1]; log-injection; manual | +| 11 | Source: net/http; Request; true; Header; ; ; ; remote; manual | nodes | klog.go:21:3:26:3 | range statement[1] | semmle.label | range statement[1] | | klog.go:21:30:21:37 | selection of Header | semmle.label | selection of Header | @@ -108,39 +256,58 @@ nodes | klog.go:23:15:23:20 | header | semmle.label | header | | klog.go:29:13:29:20 | selection of Header | semmle.label | selection of Header | | klog.go:29:13:29:41 | call to Get | semmle.label | call to Get | -| main.go:16:12:16:19 | password | semmle.label | password | -| main.go:17:19:17:26 | password | semmle.label | password | -| main.go:18:13:18:20 | password | semmle.label | password | -| main.go:19:14:19:21 | password | semmle.label | password | -| main.go:20:12:20:19 | password | semmle.label | password | -| main.go:21:19:21:26 | password | semmle.label | password | -| main.go:22:13:22:20 | password | semmle.label | password | -| main.go:23:14:23:21 | password | semmle.label | password | -| main.go:24:12:24:19 | password | semmle.label | password | -| main.go:25:19:25:26 | password | semmle.label | password | -| main.go:26:13:26:20 | password | semmle.label | password | -| main.go:27:14:27:21 | password | semmle.label | password | -| main.go:28:16:28:23 | password | semmle.label | password | -| main.go:32:10:32:17 | password | semmle.label | password | -| main.go:33:17:33:24 | password | semmle.label | password | -| main.go:34:11:34:18 | password | semmle.label | password | -| main.go:35:12:35:19 | password | semmle.label | password | -| main.go:36:10:36:17 | password | semmle.label | password | -| main.go:37:17:37:24 | password | semmle.label | password | -| main.go:38:11:38:18 | password | semmle.label | password | -| main.go:39:12:39:19 | password | semmle.label | password | -| main.go:40:10:40:17 | password | semmle.label | password | -| main.go:41:17:41:24 | password | semmle.label | password | -| main.go:42:11:42:18 | password | semmle.label | password | -| main.go:43:12:43:19 | password | semmle.label | password | -| main.go:44:14:44:21 | password | semmle.label | password | -| main.go:47:12:47:19 | password | semmle.label | password | -| main.go:48:17:48:24 | password | semmle.label | password | -| main.go:55:35:55:42 | password | semmle.label | password | +| main.go:17:2:17:9 | definition of password | semmle.label | definition of password | +| main.go:19:12:19:19 | password | semmle.label | password | +| main.go:20:19:20:26 | password | semmle.label | password | +| main.go:21:13:21:20 | password | semmle.label | password | +| main.go:22:14:22:21 | password | semmle.label | password | +| main.go:24:13:24:20 | password | semmle.label | password | +| main.go:27:20:27:27 | password | semmle.label | password | +| main.go:30:14:30:21 | password | semmle.label | password | +| main.go:33:15:33:22 | password | semmle.label | password | +| main.go:36:13:36:20 | password | semmle.label | password | +| main.go:39:20:39:27 | password | semmle.label | password | +| main.go:42:14:42:21 | password | semmle.label | password | +| main.go:45:15:45:22 | password | semmle.label | password | +| main.go:47:16:47:23 | password | semmle.label | password | +| main.go:51:10:51:17 | password | semmle.label | password | +| main.go:51:10:51:17 | password | semmle.label | password | +| main.go:52:17:52:24 | password | semmle.label | password | +| main.go:52:17:52:24 | password | semmle.label | password | +| main.go:53:11:53:18 | password | semmle.label | password | +| main.go:53:11:53:18 | password | semmle.label | password | +| main.go:54:12:54:19 | password | semmle.label | password | +| main.go:54:12:54:19 | password | semmle.label | password | +| main.go:56:11:56:18 | password | semmle.label | password | +| main.go:56:11:56:18 | password | semmle.label | password | +| main.go:59:18:59:25 | password | semmle.label | password | +| main.go:59:18:59:25 | password | semmle.label | password | +| main.go:62:12:62:19 | password | semmle.label | password | +| main.go:62:12:62:19 | password | semmle.label | password | +| main.go:65:13:65:20 | password | semmle.label | password | +| main.go:65:13:65:20 | password | semmle.label | password | +| main.go:68:11:68:18 | password | semmle.label | password | +| main.go:68:11:68:18 | password | semmle.label | password | +| main.go:71:18:71:25 | password | semmle.label | password | +| main.go:71:18:71:25 | password | semmle.label | password | +| main.go:74:12:74:19 | password | semmle.label | password | +| main.go:74:12:74:19 | password | semmle.label | password | +| main.go:77:13:77:20 | password | semmle.label | password | +| main.go:77:13:77:20 | password | semmle.label | password | +| main.go:79:14:79:21 | password | semmle.label | password | +| main.go:80:17:80:24 | password | semmle.label | password | +| main.go:82:12:82:19 | password | semmle.label | password | +| main.go:83:17:83:24 | password | semmle.label | password | +| main.go:85:2:85:7 | definition of fields | semmle.label | definition of fields | +| main.go:86:19:86:26 | password | semmle.label | password | +| main.go:87:29:87:34 | fields | semmle.label | fields | +| main.go:90:35:90:42 | password | semmle.label | password | +| overrides.go:8:2:8:9 | definition of password | semmle.label | definition of password | | overrides.go:9:9:9:16 | password | semmle.label | password | | overrides.go:13:14:13:23 | call to String | semmle.label | call to String | | passwords.go:8:12:8:12 | definition of x | semmle.label | definition of x | | passwords.go:9:14:9:14 | x | semmle.label | x | +| passwords.go:21:2:21:9 | definition of password | semmle.label | definition of password | | passwords.go:25:14:25:21 | password | semmle.label | password | | passwords.go:26:14:26:23 | selection of password | semmle.label | selection of password | | passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword | @@ -158,32 +325,34 @@ nodes | 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:50:2:50:15 | definition of fixed_password | semmle.label | definition of fixed_password | | passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password | -| 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: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 | ...+... | -| passwords.go:101:33:101:40 | password | semmle.label | password | -| passwords.go:107:16:107:41 | ...+... | semmle.label | ...+... | -| passwords.go:107:34:107:41 | password | semmle.label | password | -| passwords.go:112:15:112:40 | ...+... | semmle.label | ...+... | -| passwords.go:112:33:112:40 | password | semmle.label | password | -| 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: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 | -| passwords.go:121:13:121:20 | password | semmle.label | password | -| passwords.go:122:13:122:25 | call to getPassword | semmle.label | call to getPassword | -| passwords.go:125:14:125:19 | config | semmle.label | config | -| passwords.go:126:14:126:19 | config [x] | semmle.label | config [x] | -| passwords.go:126:14:126:21 | selection of x | semmle.label | selection of x | -| passwords.go:127:14:127:19 | config [y] | semmle.label | config [y] | -| passwords.go:127:14:127:21 | selection of y | semmle.label | selection of y | +| passwords.go:86:19:88:2 | struct literal | semmle.label | struct literal | +| passwords.go:87:16:87:36 | call to make | semmle.label | call to make | +| passwords.go:89:14:89:26 | utilityObject | semmle.label | utilityObject | +| passwords.go:92:23:92:28 | secret | semmle.label | secret | +| passwords.go:102:15:102:40 | ...+... | semmle.label | ...+... | +| passwords.go:102:33:102:40 | password | semmle.label | password | +| passwords.go:108:16:108:41 | ...+... | semmle.label | ...+... | +| passwords.go:108:34:108:41 | password | semmle.label | password | +| passwords.go:113:15:113:40 | ...+... | semmle.label | ...+... | +| passwords.go:113:33:113:40 | password | semmle.label | password | +| passwords.go:116:6:116:14 | definition of password1 | semmle.label | definition of password1 | +| passwords.go:117:14:117:45 | ...+... | semmle.label | ...+... | +| passwords.go:117:28:117:36 | password1 | semmle.label | password1 | +| passwords.go:117:28:117:45 | call to String | semmle.label | call to String | +| passwords.go:120:12:125:2 | struct literal | semmle.label | struct literal | +| passwords.go:120:12:125:2 | struct literal [x] | semmle.label | struct literal [x] | +| passwords.go:120:12:125:2 | struct literal [y] | semmle.label | struct literal [y] | +| passwords.go:121:13:121:14 | x3 | semmle.label | x3 | +| passwords.go:123:13:123:20 | password | semmle.label | password | +| passwords.go:124:13:124:25 | call to getPassword | semmle.label | call to getPassword | +| passwords.go:127:14:127:19 | config | semmle.label | config | +| passwords.go:128:14:128:19 | config [x] | semmle.label | config [x] | +| passwords.go:128:14:128:21 | selection of x | semmle.label | selection of x | +| passwords.go:129:14:129:19 | config [y] | semmle.label | config [y] | +| passwords.go:129:14:129:21 | selection of y | semmle.label | selection of y | +| protobuf.go:9:2:9:9 | definition of password | semmle.label | definition of password | | protobuf.go:11:2:11:6 | definition of query [pointer, Description] | semmle.label | definition of query [pointer, Description] | | protobuf.go:12:2:12:6 | implicit dereference [Description] | semmle.label | implicit dereference [Description] | | protobuf.go:12:2:12:6 | query [pointer, Description] | semmle.label | query [pointer, Description] | @@ -196,3 +365,18 @@ nodes | protos/query/query.pb.go:119:10:119:22 | selection of Description | semmle.label | selection of Description | subpaths | 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 | +testFailures +| main.go:17:2:17:9 | definition of password | Unexpected result: Source | +| main.go:87:29:87:34 | fields | Unexpected result: Alert | +| overrides.go:8:2:8:9 | definition of password | Unexpected result: Source | +| overrides.go:9:18:9:28 | comment | Missing result: Source | +| passwords.go:21:2:21:9 | definition of password | Unexpected result: Source | +| passwords.go:30:18:30:28 | comment | Missing result: Source | +| passwords.go:42:16:42:26 | comment | Missing result: Source | +| passwords.go:48:20:48:30 | comment | Missing result: Source | +| passwords.go:50:2:50:15 | definition of fixed_password | Unexpected result: Source | +| passwords.go:91:31:91:41 | comment | Missing result: Source | +| passwords.go:116:6:116:14 | definition of password1 | Unexpected result: Source | +| passwords.go:123:28:123:38 | comment | Missing result: Source | +| protobuf.go:9:2:9:9 | definition of password | Unexpected result: Source | +| protobuf.go:12:31:12:41 | comment | Missing result: Source | diff --git a/go/ql/test/query-tests/Security/CWE-312/main.go b/go/ql/test/query-tests/Security/CWE-312/main.go index 17a183ff209..0372fc2df14 100644 --- a/go/ql/test/query-tests/Security/CWE-312/main.go +++ b/go/ql/test/query-tests/Security/CWE-312/main.go @@ -5,11 +5,14 @@ package main import ( "log" + "math/rand" "github.com/golang/glog" "github.com/sirupsen/logrus" ) +var i int = rand.Int() + func main() { password := "P4ssw0rd" @@ -17,15 +20,31 @@ func main() { log.Printf("%s", password) // $ Alert log.Printf(password, "") // $ Alert log.Println(password) // $ Alert - log.Fatal(password) // $ Alert - log.Fatalf("%s", password) // $ Alert - log.Fatalf(password, "") // $ Alert - log.Fatalln(password) // $ Alert - log.Panic(password) // $ Alert - log.Panicf("%s", password) // $ Alert - log.Panicf(password, "") // $ Alert - log.Panicln(password) // $ Alert - log.Output(0, password) // $ Alert + if i == 0 { + log.Fatal(password) // $ Alert + } + if i == 1 { + log.Fatalf("%s", password) // $ Alert + } + if i == 2 { + log.Fatalf(password, "") // $ Alert + } + if i == 3 { + log.Fatalln(password) // $ Alert + } + if i == 4 { + log.Panic(password) // $ Alert + } + if i == 5 { + log.Panicf("%s", password) // $ Alert + } + if i == 6 { + log.Panicf(password, "") // $ Alert + } + if i == 7 { + log.Panicln(password) // $ Alert + } + log.Output(0, password) // $ Alert log.Printf("%T", password) l := log.Default() @@ -33,15 +52,31 @@ func main() { l.Printf("%s", password) // $ Alert l.Printf(password, "") // $ Alert l.Println(password) // $ Alert - l.Fatal(password) // $ Alert - l.Fatalf("%s", password) // $ Alert - l.Fatalf(password, "") // $ Alert - l.Fatalln(password) // $ Alert - l.Panic(password) // $ Alert - l.Panicf("%s", password) // $ Alert - l.Panicf(password, "") // $ Alert - l.Panicln(password) // $ Alert - l.Output(0, password) // $ Alert + if i == 100 { + l.Fatal(password) // $ Alert + } + if i == 101 { + l.Fatalf("%s", password) // $ Alert + } + if i == 102 { + l.Fatalf(password, "") // $ Alert + } + if i == 103 { + l.Fatalln(password) // $ Alert + } + if i == 104 { + l.Panic(password) // $ Alert + } + if i == 105 { + l.Panicf("%s", password) // $ Alert + } + if i == 106 { + l.Panicf(password, "") // $ Alert + } + if i == 107 { + l.Panicln(password) // $ Alert + } + l.Output(0, password) // $ Alert l.Printf("%T", password) glog.Info(password) // $ Alert diff --git a/go/ql/test/query-tests/Security/CWE-312/passwords.go b/go/ql/test/query-tests/Security/CWE-312/passwords.go index f99178f0fae..6be68be7265 100644 --- a/go/ql/test/query-tests/Security/CWE-312/passwords.go +++ b/go/ql/test/query-tests/Security/CWE-312/passwords.go @@ -65,7 +65,8 @@ func test() { log.Println(actually_secure_password) // OK var user1 cryptedStruct - user1.cryptedPassword = x + x2 := "perhaps sensitive" + user1.cryptedPassword = x2 log.Println(user1) // OK var user2 passStruct @@ -115,8 +116,9 @@ func test() { var password1 stringable = stringable{"arstneio"} log.Println(name + ", " + password1.String()) // $ Alert + x3 := "sheepbatterystaplecorrect" config := Config{ - password: x, // $ Source + password: x3, // $ Source hostname: "tarski", x: password, // $ Source y: getPassword(), // $ Source diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index f8d193348ba..65d24e8b45b 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -2,69 +2,71 @@ | OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | This path to an untrusted URL redirection depends on a $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value | | stdlib.go:15:30:15:35 | target | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:15:30:15:35 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:13:13:13:18 | selection of Form | user-provided value | | stdlib.go:24:30:24:35 | target | stdlib.go:22:13:22:18 | selection of Form | stdlib.go:24:30:24:35 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:22:13:22:18 | selection of Form | user-provided value | -| stdlib.go:35:30:35:39 | ...+... | stdlib.go:31:13:31:18 | selection of Form | stdlib.go:35:30:35:39 | ...+... | This path to an untrusted URL redirection depends on a $@. | stdlib.go:31:13:31:18 | selection of Form | user-provided value | -| stdlib.go:46:23:46:28 | target | stdlib.go:44:13:44:18 | selection of Form | stdlib.go:46:23:46:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:44:13:44:18 | selection of Form | user-provided value | -| stdlib.go:67:23:67:40 | ...+... | stdlib.go:64:13:64:18 | selection of Form | stdlib.go:67:23:67:40 | ...+... | This path to an untrusted URL redirection depends on a $@. | stdlib.go:64:13:64:18 | selection of Form | user-provided value | -| stdlib.go:92:23:92:28 | target | stdlib.go:89:13:89:18 | selection of Form | stdlib.go:92:23:92:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:89:13:89:18 | selection of Form | user-provided value | -| stdlib.go:152:23:152:28 | target | stdlib.go:146:13:146:18 | selection of Form | stdlib.go:152:23:152:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:146:13:146:18 | selection of Form | user-provided value | -| stdlib.go:184:23:184:28 | target | stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:182:13:182:33 | call to FormValue | user-provided value | -| stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | -| stdlib.go:194:23:194:42 | call to EscapedPath | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | +| stdlib.go:39:30:39:40 | ...+... | stdlib.go:33:13:33:18 | selection of Form | stdlib.go:39:30:39:40 | ...+... | This path to an untrusted URL redirection depends on a $@. | stdlib.go:33:13:33:18 | selection of Form | user-provided value | +| stdlib.go:50:23:50:28 | target | stdlib.go:48:13:48:18 | selection of Form | stdlib.go:50:23:50:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:48:13:48:18 | selection of Form | user-provided value | +| stdlib.go:71:23:71:40 | ...+... | stdlib.go:68:13:68:18 | selection of Form | stdlib.go:71:23:71:40 | ...+... | This path to an untrusted URL redirection depends on a $@. | stdlib.go:68:13:68:18 | selection of Form | user-provided value | +| stdlib.go:96:23:96:28 | target | stdlib.go:93:13:93:18 | selection of Form | stdlib.go:96:23:96:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:93:13:93:18 | selection of Form | user-provided value | +| stdlib.go:156:23:156:28 | target | stdlib.go:150:13:150:18 | selection of Form | stdlib.go:156:23:156:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:150:13:150:18 | selection of Form | user-provided value | +| stdlib.go:188:23:188:28 | target | stdlib.go:186:13:186:33 | call to FormValue | stdlib.go:188:23:188:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:186:13:186:33 | call to FormValue | user-provided value | +| stdlib.go:196:23:196:33 | selection of Path | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:196:23:196:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | +| stdlib.go:198:23:198:42 | call to EscapedPath | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:198:23:198:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | edges | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | provenance | Src:MaD:2 Config Sink:MaD:1 | | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:13:13:13:32 | call to Get | provenance | Src:MaD:2 Config | | stdlib.go:13:13:13:32 | call to Get | stdlib.go:15:30:15:35 | target | provenance | | | stdlib.go:22:13:22:18 | selection of Form | stdlib.go:22:13:22:32 | call to Get | provenance | Src:MaD:2 Config | | stdlib.go:22:13:22:32 | call to Get | stdlib.go:24:30:24:35 | target | provenance | | -| stdlib.go:31:13:31:18 | selection of Form | stdlib.go:31:13:31:32 | call to Get | provenance | Src:MaD:2 Config | -| stdlib.go:31:13:31:32 | call to Get | stdlib.go:35:34:35:39 | target | provenance | | -| stdlib.go:35:34:35:39 | target | stdlib.go:35:30:35:39 | ...+... | provenance | Config | -| stdlib.go:44:13:44:18 | selection of Form | stdlib.go:44:13:44:32 | call to Get | provenance | Src:MaD:2 Config | -| stdlib.go:44:13:44:32 | call to Get | stdlib.go:46:23:46:28 | target | provenance | Sink:MaD:1 | -| stdlib.go:64:13:64:18 | selection of Form | stdlib.go:64:13:64:32 | call to Get | provenance | Src:MaD:2 Config | -| stdlib.go:64:13:64:32 | call to Get | stdlib.go:67:23:67:28 | target | provenance | | -| stdlib.go:67:23:67:28 | target | stdlib.go:67:23:67:37 | ...+... | provenance | Config | -| stdlib.go:67:23:67:37 | ...+... | stdlib.go:67:23:67:40 | ...+... | provenance | Config Sink:MaD:1 | -| stdlib.go:89:13:89:18 | selection of Form | stdlib.go:89:13:89:32 | call to Get | provenance | Src:MaD:2 Config | -| stdlib.go:89:13:89:32 | call to Get | stdlib.go:90:3:90:8 | target | provenance | | -| stdlib.go:90:3:90:8 | target | stdlib.go:90:3:90:25 | ... += ... | provenance | Config | -| stdlib.go:90:3:90:25 | ... += ... | stdlib.go:92:23:92:28 | target | provenance | Sink:MaD:1 | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | provenance | | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:112:4:112:4 | r [pointer, URL] | provenance | | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:113:24:113:24 | r [pointer, URL] | provenance | | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | provenance | | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | stdlib.go:112:4:112:8 | selection of URL [pointer] | provenance | | -| stdlib.go:112:4:112:4 | implicit dereference [URL] | stdlib.go:107:54:107:54 | definition of r [pointer, URL] | provenance | | -| stdlib.go:112:4:112:4 | implicit dereference [URL] | stdlib.go:112:4:112:8 | selection of URL | provenance | | -| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | provenance | | -| stdlib.go:112:4:112:4 | r [pointer, URL] | stdlib.go:112:4:112:4 | implicit dereference [URL] | provenance | | -| stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | selection of URL | provenance | Config | -| stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | selection of URL [pointer] | provenance | | -| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:4 | implicit dereference [URL] | provenance | Src:MaD:4 | -| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:8 | implicit dereference | provenance | Src:MaD:4 Config | -| stdlib.go:112:4:112:8 | selection of URL [pointer] | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | provenance | | -| stdlib.go:112:4:112:8 | selection of URL [pointer] | stdlib.go:112:4:112:8 | implicit dereference | provenance | | -| stdlib.go:113:24:113:24 | implicit dereference [URL] | stdlib.go:113:24:113:28 | selection of URL | provenance | | -| stdlib.go:113:24:113:24 | r [pointer, URL] | stdlib.go:113:24:113:24 | implicit dereference [URL] | provenance | | -| stdlib.go:113:24:113:28 | selection of URL | stdlib.go:113:24:113:37 | call to String | provenance | Src:MaD:4 Config Sink:MaD:1 | -| stdlib.go:146:13:146:18 | selection of Form | stdlib.go:146:13:146:32 | call to Get | provenance | Src:MaD:2 Config | -| stdlib.go:146:13:146:32 | call to Get | stdlib.go:152:23:152:28 | target | provenance | Sink:MaD:1 | -| stdlib.go:159:10:159:15 | star expression | stdlib.go:159:11:159:15 | selection of URL | provenance | Config | -| stdlib.go:159:10:159:15 | star expression | stdlib.go:162:24:162:26 | url | provenance | | -| stdlib.go:159:11:159:15 | selection of URL | stdlib.go:159:10:159:15 | star expression | provenance | Src:MaD:4 Config | -| stdlib.go:162:24:162:26 | url | stdlib.go:162:24:162:35 | call to String | provenance | Config Sink:MaD:1 | -| stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:35:173:52 | call to RequestURI | provenance | Src:MaD:4 Config | -| stdlib.go:173:35:173:52 | call to RequestURI | stdlib.go:173:24:173:52 | ...+... | provenance | Config Sink:MaD:1 | -| stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | provenance | Src:MaD:3 Sink:MaD:1 | -| stdlib.go:190:3:190:8 | definition of target | stdlib.go:192:23:192:28 | target | provenance | | -| stdlib.go:190:3:190:8 | definition of target | stdlib.go:194:23:194:28 | target | provenance | | -| stdlib.go:190:3:190:57 | ... := ...[0] | stdlib.go:190:3:190:8 | definition of target | provenance | | -| stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:190:3:190:57 | ... := ...[0] | provenance | Src:MaD:3 Config | -| stdlib.go:192:23:192:28 | implicit dereference | stdlib.go:190:3:190:8 | definition of target | provenance | Config | -| stdlib.go:192:23:192:28 | implicit dereference | stdlib.go:192:23:192:33 | selection of Path | provenance | Config Sink:MaD:1 | -| stdlib.go:192:23:192:28 | target | stdlib.go:192:23:192:28 | implicit dereference | provenance | Config | -| stdlib.go:192:23:192:28 | target | stdlib.go:192:23:192:33 | selection of Path | provenance | Config Sink:MaD:1 | -| stdlib.go:194:23:194:28 | target | stdlib.go:194:23:194:42 | call to EscapedPath | provenance | Config Sink:MaD:1 | +| stdlib.go:33:13:33:18 | selection of Form | stdlib.go:33:13:33:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:33:13:33:32 | call to Get | stdlib.go:39:34:39:40 | target2 | provenance | | +| stdlib.go:39:34:39:40 | target2 | stdlib.go:39:30:39:40 | ...+... | provenance | Config | +| stdlib.go:48:13:48:18 | selection of Form | stdlib.go:48:13:48:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:48:13:48:32 | call to Get | stdlib.go:50:23:50:28 | target | provenance | Sink:MaD:1 | +| stdlib.go:68:13:68:18 | selection of Form | stdlib.go:68:13:68:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:68:13:68:32 | call to Get | stdlib.go:71:23:71:28 | target | provenance | | +| stdlib.go:71:23:71:28 | target | stdlib.go:71:23:71:37 | ...+... | provenance | Config | +| stdlib.go:71:23:71:37 | ...+... | stdlib.go:71:23:71:40 | ...+... | provenance | Config Sink:MaD:1 | +| stdlib.go:93:13:93:18 | selection of Form | stdlib.go:93:13:93:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:93:13:93:32 | call to Get | stdlib.go:94:3:94:8 | target | provenance | | +| stdlib.go:94:3:94:8 | target | stdlib.go:94:3:94:25 | ... += ... | provenance | Config | +| stdlib.go:94:3:94:25 | ... += ... | stdlib.go:96:23:96:28 | target | provenance | Sink:MaD:1 | +| stdlib.go:111:54:111:54 | definition of r [pointer, URL, pointer] | stdlib.go:115:6:115:6 | r [pointer, URL, pointer] | provenance | | +| stdlib.go:111:54:111:54 | definition of r [pointer, URL] | stdlib.go:115:6:115:6 | r [pointer, URL] | provenance | | +| stdlib.go:115:6:115:6 | r [pointer, URL, pointer] | stdlib.go:116:4:116:4 | r [pointer, URL, pointer] | provenance | | +| stdlib.go:115:6:115:6 | r [pointer, URL] | stdlib.go:116:4:116:4 | r [pointer, URL] | provenance | | +| stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | stdlib.go:111:54:111:54 | definition of r [pointer, URL, pointer] | provenance | | +| stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | stdlib.go:116:4:116:8 | selection of URL [pointer] | provenance | | +| stdlib.go:116:4:116:4 | implicit dereference [URL] | stdlib.go:111:54:111:54 | definition of r [pointer, URL] | provenance | | +| stdlib.go:116:4:116:4 | implicit dereference [URL] | stdlib.go:116:4:116:8 | selection of URL | provenance | | +| stdlib.go:116:4:116:4 | r [pointer, URL, pointer] | stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | provenance | | +| stdlib.go:116:4:116:4 | r [pointer, URL] | stdlib.go:116:4:116:4 | implicit dereference [URL] | provenance | | +| stdlib.go:116:4:116:4 | r [pointer, URL] | stdlib.go:117:24:117:24 | r [pointer, URL] | provenance | | +| stdlib.go:116:4:116:8 | implicit dereference | stdlib.go:116:4:116:8 | selection of URL | provenance | Config | +| stdlib.go:116:4:116:8 | implicit dereference | stdlib.go:116:4:116:8 | selection of URL [pointer] | provenance | | +| stdlib.go:116:4:116:8 | selection of URL | stdlib.go:116:4:116:4 | implicit dereference [URL] | provenance | Src:MaD:4 | +| stdlib.go:116:4:116:8 | selection of URL | stdlib.go:116:4:116:8 | implicit dereference | provenance | Src:MaD:4 Config | +| stdlib.go:116:4:116:8 | selection of URL [pointer] | stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | provenance | | +| stdlib.go:116:4:116:8 | selection of URL [pointer] | stdlib.go:116:4:116:8 | implicit dereference | provenance | | +| stdlib.go:117:24:117:24 | implicit dereference [URL] | stdlib.go:117:24:117:28 | selection of URL | provenance | | +| stdlib.go:117:24:117:24 | r [pointer, URL] | stdlib.go:117:24:117:24 | implicit dereference [URL] | provenance | | +| stdlib.go:117:24:117:28 | selection of URL | stdlib.go:117:24:117:37 | call to String | provenance | Src:MaD:4 Config Sink:MaD:1 | +| stdlib.go:150:13:150:18 | selection of Form | stdlib.go:150:13:150:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:150:13:150:32 | call to Get | stdlib.go:156:23:156:28 | target | provenance | Sink:MaD:1 | +| stdlib.go:163:10:163:15 | star expression | stdlib.go:163:11:163:15 | selection of URL | provenance | Config | +| stdlib.go:163:10:163:15 | star expression | stdlib.go:166:24:166:26 | url | provenance | | +| stdlib.go:163:11:163:15 | selection of URL | stdlib.go:163:10:163:15 | star expression | provenance | Src:MaD:4 Config | +| stdlib.go:166:24:166:26 | url | stdlib.go:166:24:166:35 | call to String | provenance | Config Sink:MaD:1 | +| stdlib.go:177:35:177:39 | selection of URL | stdlib.go:177:35:177:52 | call to RequestURI | provenance | Src:MaD:4 Config | +| stdlib.go:177:35:177:52 | call to RequestURI | stdlib.go:177:24:177:52 | ...+... | provenance | Config Sink:MaD:1 | +| stdlib.go:186:13:186:33 | call to FormValue | stdlib.go:188:23:188:28 | target | provenance | Src:MaD:3 Sink:MaD:1 | +| stdlib.go:194:3:194:8 | definition of target | stdlib.go:196:23:196:28 | target | provenance | | +| stdlib.go:194:3:194:57 | ... := ...[0] | stdlib.go:194:3:194:8 | definition of target | provenance | | +| stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:194:3:194:57 | ... := ...[0] | provenance | Src:MaD:3 Config | +| stdlib.go:196:23:196:28 | implicit dereference | stdlib.go:194:3:194:8 | definition of target | provenance | Config | +| stdlib.go:196:23:196:28 | implicit dereference | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 | +| stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config | +| stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 | +| stdlib.go:196:23:196:28 | target | stdlib.go:198:23:198:28 | target | provenance | | +| stdlib.go:198:23:198:28 | target | stdlib.go:198:23:198:42 | call to EscapedPath | provenance | Config Sink:MaD:1 | models | 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual | | 2 | Source: net/http; Request; true; Form; ; ; ; remote; manual | @@ -79,54 +81,56 @@ nodes | stdlib.go:22:13:22:18 | selection of Form | semmle.label | selection of Form | | stdlib.go:22:13:22:32 | call to Get | semmle.label | call to Get | | stdlib.go:24:30:24:35 | target | semmle.label | target | -| stdlib.go:31:13:31:18 | selection of Form | semmle.label | selection of Form | -| stdlib.go:31:13:31:32 | call to Get | semmle.label | call to Get | -| stdlib.go:35:30:35:39 | ...+... | semmle.label | ...+... | -| stdlib.go:35:34:35:39 | target | semmle.label | target | -| stdlib.go:44:13:44:18 | selection of Form | semmle.label | selection of Form | -| stdlib.go:44:13:44:32 | call to Get | semmle.label | call to Get | -| stdlib.go:46:23:46:28 | target | semmle.label | target | -| stdlib.go:64:13:64:18 | selection of Form | semmle.label | selection of Form | -| stdlib.go:64:13:64:32 | call to Get | semmle.label | call to Get | -| stdlib.go:67:23:67:28 | target | semmle.label | target | -| stdlib.go:67:23:67:37 | ...+... | semmle.label | ...+... | -| stdlib.go:67:23:67:40 | ...+... | semmle.label | ...+... | -| stdlib.go:89:13:89:18 | selection of Form | semmle.label | selection of Form | -| stdlib.go:89:13:89:32 | call to Get | semmle.label | call to Get | -| stdlib.go:90:3:90:8 | target | semmle.label | target | -| stdlib.go:90:3:90:25 | ... += ... | semmle.label | ... += ... | -| stdlib.go:92:23:92:28 | target | semmle.label | target | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | semmle.label | definition of r [pointer, URL, pointer] | -| stdlib.go:107:54:107:54 | definition of r [pointer, URL] | semmle.label | definition of r [pointer, URL] | -| stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | semmle.label | implicit dereference [URL, pointer] | -| stdlib.go:112:4:112:4 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | -| stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | semmle.label | r [pointer, URL, pointer] | -| stdlib.go:112:4:112:4 | r [pointer, URL] | semmle.label | r [pointer, URL] | -| stdlib.go:112:4:112:8 | implicit dereference | semmle.label | implicit dereference | -| stdlib.go:112:4:112:8 | selection of URL | semmle.label | selection of URL | -| stdlib.go:112:4:112:8 | selection of URL [pointer] | semmle.label | selection of URL [pointer] | -| stdlib.go:113:24:113:24 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | -| stdlib.go:113:24:113:24 | r [pointer, URL] | semmle.label | r [pointer, URL] | -| stdlib.go:113:24:113:28 | selection of URL | semmle.label | selection of URL | -| stdlib.go:113:24:113:37 | call to String | semmle.label | call to String | -| stdlib.go:146:13:146:18 | selection of Form | semmle.label | selection of Form | -| stdlib.go:146:13:146:32 | call to Get | semmle.label | call to Get | -| stdlib.go:152:23:152:28 | target | semmle.label | target | -| stdlib.go:159:10:159:15 | star expression | semmle.label | star expression | -| stdlib.go:159:11:159:15 | selection of URL | semmle.label | selection of URL | -| stdlib.go:162:24:162:26 | url | semmle.label | url | -| stdlib.go:162:24:162:35 | call to String | semmle.label | call to String | -| stdlib.go:173:24:173:52 | ...+... | semmle.label | ...+... | -| stdlib.go:173:35:173:39 | selection of URL | semmle.label | selection of URL | -| stdlib.go:173:35:173:52 | call to RequestURI | semmle.label | call to RequestURI | -| stdlib.go:182:13:182:33 | call to FormValue | semmle.label | call to FormValue | -| stdlib.go:184:23:184:28 | target | semmle.label | target | -| stdlib.go:190:3:190:8 | definition of target | semmle.label | definition of target | -| stdlib.go:190:3:190:57 | ... := ...[0] | semmle.label | ... := ...[0] | -| stdlib.go:190:36:190:56 | call to FormValue | semmle.label | call to FormValue | -| stdlib.go:192:23:192:28 | implicit dereference | semmle.label | implicit dereference | -| stdlib.go:192:23:192:28 | target | semmle.label | target | -| stdlib.go:192:23:192:33 | selection of Path | semmle.label | selection of Path | -| stdlib.go:194:23:194:28 | target | semmle.label | target | -| stdlib.go:194:23:194:42 | call to EscapedPath | semmle.label | call to EscapedPath | +| stdlib.go:33:13:33:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:33:13:33:32 | call to Get | semmle.label | call to Get | +| stdlib.go:39:30:39:40 | ...+... | semmle.label | ...+... | +| stdlib.go:39:34:39:40 | target2 | semmle.label | target2 | +| stdlib.go:48:13:48:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:48:13:48:32 | call to Get | semmle.label | call to Get | +| stdlib.go:50:23:50:28 | target | semmle.label | target | +| stdlib.go:68:13:68:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:68:13:68:32 | call to Get | semmle.label | call to Get | +| stdlib.go:71:23:71:28 | target | semmle.label | target | +| stdlib.go:71:23:71:37 | ...+... | semmle.label | ...+... | +| stdlib.go:71:23:71:40 | ...+... | semmle.label | ...+... | +| stdlib.go:93:13:93:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:93:13:93:32 | call to Get | semmle.label | call to Get | +| stdlib.go:94:3:94:8 | target | semmle.label | target | +| stdlib.go:94:3:94:25 | ... += ... | semmle.label | ... += ... | +| stdlib.go:96:23:96:28 | target | semmle.label | target | +| stdlib.go:111:54:111:54 | definition of r [pointer, URL, pointer] | semmle.label | definition of r [pointer, URL, pointer] | +| stdlib.go:111:54:111:54 | definition of r [pointer, URL] | semmle.label | definition of r [pointer, URL] | +| stdlib.go:115:6:115:6 | r [pointer, URL, pointer] | semmle.label | r [pointer, URL, pointer] | +| stdlib.go:115:6:115:6 | r [pointer, URL] | semmle.label | r [pointer, URL] | +| stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | semmle.label | implicit dereference [URL, pointer] | +| stdlib.go:116:4:116:4 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | +| stdlib.go:116:4:116:4 | r [pointer, URL, pointer] | semmle.label | r [pointer, URL, pointer] | +| stdlib.go:116:4:116:4 | r [pointer, URL] | semmle.label | r [pointer, URL] | +| stdlib.go:116:4:116:8 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:116:4:116:8 | selection of URL | semmle.label | selection of URL | +| stdlib.go:116:4:116:8 | selection of URL [pointer] | semmle.label | selection of URL [pointer] | +| stdlib.go:117:24:117:24 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | +| stdlib.go:117:24:117:24 | r [pointer, URL] | semmle.label | r [pointer, URL] | +| stdlib.go:117:24:117:28 | selection of URL | semmle.label | selection of URL | +| stdlib.go:117:24:117:37 | call to String | semmle.label | call to String | +| stdlib.go:150:13:150:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:150:13:150:32 | call to Get | semmle.label | call to Get | +| stdlib.go:156:23:156:28 | target | semmle.label | target | +| stdlib.go:163:10:163:15 | star expression | semmle.label | star expression | +| stdlib.go:163:11:163:15 | selection of URL | semmle.label | selection of URL | +| stdlib.go:166:24:166:26 | url | semmle.label | url | +| stdlib.go:166:24:166:35 | call to String | semmle.label | call to String | +| stdlib.go:177:24:177:52 | ...+... | semmle.label | ...+... | +| stdlib.go:177:35:177:39 | selection of URL | semmle.label | selection of URL | +| stdlib.go:177:35:177:52 | call to RequestURI | semmle.label | call to RequestURI | +| stdlib.go:186:13:186:33 | call to FormValue | semmle.label | call to FormValue | +| stdlib.go:188:23:188:28 | target | semmle.label | target | +| stdlib.go:194:3:194:8 | definition of target | semmle.label | definition of target | +| stdlib.go:194:3:194:57 | ... := ...[0] | semmle.label | ... := ...[0] | +| stdlib.go:194:36:194:56 | call to FormValue | semmle.label | call to FormValue | +| stdlib.go:196:23:196:28 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:196:23:196:28 | target | semmle.label | target | +| stdlib.go:196:23:196:33 | selection of Path | semmle.label | selection of Path | +| stdlib.go:198:23:198:28 | target | semmle.label | target | +| stdlib.go:198:23:198:42 | call to EscapedPath | semmle.label | call to EscapedPath | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go index 0ccacd7d87e..f6cd1e5576f 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go @@ -28,13 +28,17 @@ func serveStdlib() { http.HandleFunc("/ex2", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() + // Taking gratuitous copies of target so that sanitizing the use in + // the first request doesn't also sanitize other uses target := r.Form.Get("target") + target2 := target + target3 := target // GOOD: local redirects are unproblematic w.Header().Set("Location", "/local"+target) // BAD: this could be a non-local redirect - w.Header().Set("Location", "/"+target) + w.Header().Set("Location", "/"+target2) // GOOD: localhost redirects are unproblematic - w.Header().Set("Location", "//localhost/"+target) + w.Header().Set("Location", "//localhost/"+target3) w.WriteHeader(302) }) diff --git a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 696d8dd700b..1fa5431811b 100644 --- a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -1,18 +1,18 @@ #select | RequestForgery.go:11:15:11:66 | call to Get | RequestForgery.go:8:12:8:34 | call to FormValue | RequestForgery.go:11:24:11:65 | ...+... | The $@ of this request depends on a $@. | RequestForgery.go:11:24:11:65 | ...+... | URL | RequestForgery.go:8:12:8:34 | call to FormValue | user-provided value | -| tst.go:14:2:14:18 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:14:11:14:17 | tainted | The $@ of this request depends on a $@. | tst.go:14:11:14:17 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:16:2:16:19 | call to Head | tst.go:10:13:10:35 | call to FormValue | tst.go:16:12:16:18 | tainted | The $@ of this request depends on a $@. | tst.go:16:12:16:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:18:2:18:38 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:18:12:18:18 | tainted | The $@ of this request depends on a $@. | tst.go:18:12:18:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:20:2:20:28 | call to PostForm | tst.go:10:13:10:35 | call to FormValue | tst.go:20:16:20:22 | tainted | The $@ of this request depends on a $@. | tst.go:20:16:20:22 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:24:2:24:15 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:23:35:23:41 | tainted | The $@ of this request depends on a $@. | tst.go:23:35:23:41 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:27:2:27:15 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:26:68:26:74 | tainted | The $@ of this request depends on a $@. | tst.go:26:68:26:74 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:29:2:29:20 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:29:13:29:19 | tainted | The $@ of this request depends on a $@. | tst.go:29:13:29:19 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:30:2:30:21 | call to Head | tst.go:10:13:10:35 | call to FormValue | tst.go:30:14:30:20 | tainted | The $@ of this request depends on a $@. | tst.go:30:14:30:20 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:31:2:31:40 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:31:14:31:20 | tainted | The $@ of this request depends on a $@. | tst.go:31:14:31:20 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:32:2:32:30 | call to PostForm | tst.go:10:13:10:35 | call to FormValue | tst.go:32:18:32:24 | tainted | The $@ of this request depends on a $@. | tst.go:32:18:32:24 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:34:2:34:30 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:34:11:34:29 | ...+... | The $@ of this request depends on a $@. | tst.go:34:11:34:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:36:2:36:41 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:36:11:36:40 | ...+... | The $@ of this request depends on a $@. | tst.go:36:11:36:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | -| tst.go:44:2:44:21 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:44:11:44:20 | call to String | The $@ of this request depends on a $@. | tst.go:44:11:44:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:18:2:18:18 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:18:11:18:17 | tainted | The $@ of this request depends on a $@. | tst.go:18:11:18:17 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:20:2:20:19 | call to Head | tst.go:10:13:10:35 | call to FormValue | tst.go:20:12:20:18 | tainted | The $@ of this request depends on a $@. | tst.go:20:12:20:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:22:2:22:38 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:22:12:22:18 | tainted | The $@ of this request depends on a $@. | tst.go:22:12:22:18 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:24:2:24:28 | call to PostForm | tst.go:10:13:10:35 | call to FormValue | tst.go:24:16:24:22 | tainted | The $@ of this request depends on a $@. | tst.go:24:16:24:22 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:28:2:28:15 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:27:35:27:41 | tainted | The $@ of this request depends on a $@. | tst.go:27:35:27:41 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:31:2:31:15 | call to Do | tst.go:10:13:10:35 | call to FormValue | tst.go:30:68:30:74 | tainted | The $@ of this request depends on a $@. | tst.go:30:68:30:74 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:33:2:33:20 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:33:13:33:19 | tainted | The $@ of this request depends on a $@. | tst.go:33:13:33:19 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:34:2:34:21 | call to Head | tst.go:10:13:10:35 | call to FormValue | tst.go:34:14:34:20 | tainted | The $@ of this request depends on a $@. | tst.go:34:14:34:20 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:35:2:35:40 | call to Post | tst.go:10:13:10:35 | call to FormValue | tst.go:35:14:35:20 | tainted | The $@ of this request depends on a $@. | tst.go:35:14:35:20 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:36:2:36:30 | call to PostForm | tst.go:10:13:10:35 | call to FormValue | tst.go:36:18:36:24 | tainted | The $@ of this request depends on a $@. | tst.go:36:18:36:24 | tainted | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:38:2:38:30 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:38:11:38:29 | ...+... | The $@ of this request depends on a $@. | tst.go:38:11:38:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:40:2:40:41 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:40:11:40:40 | ...+... | The $@ of this request depends on a $@. | tst.go:40:11:40:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | +| tst.go:48:2:48:21 | call to Get | tst.go:10:13:10:35 | call to FormValue | tst.go:48:11:48:20 | call to String | The $@ of this request depends on a $@. | tst.go:48:11:48:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue | user-provided value | | websocket.go:65:12:65:53 | call to Dial | websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:65:27:65:40 | untrustedInput | WebSocket URL | websocket.go:60:21:60:31 | call to Referer | user-provided value | | websocket.go:79:13:79:40 | call to DialConfig | websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:78:36:78:49 | untrustedInput | WebSocket URL | websocket.go:74:21:74:31 | call to Referer | user-provided value | | websocket.go:91:3:91:50 | call to Dial | websocket.go:88:21:88:31 | call to Referer | websocket.go:91:31:91:44 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:91:31:91:44 | untrustedInput | WebSocket URL | websocket.go:88:21:88:31 | call to Referer | user-provided value | @@ -24,29 +24,28 @@ | websocket.go:204:7:204:29 | call to New | websocket.go:202:21:202:31 | call to Referer | websocket.go:204:15:204:28 | untrustedInput | The $@ of this request depends on a $@. | websocket.go:204:15:204:28 | untrustedInput | WebSocket URL | websocket.go:202:21:202:31 | call to Referer | user-provided value | edges | RequestForgery.go:8:12:8:34 | call to FormValue | RequestForgery.go:11:24:11:65 | ...+... | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:14:11:14:17 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:16:12:16:18 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:18:12:18:18 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:20:16:20:22 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:23:35:23:41 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:26:68:26:74 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:29:13:29:19 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:30:14:30:20 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:31:14:31:20 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:32:18:32:24 | tainted | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:34:11:34:29 | ...+... | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:36:11:36:40 | ...+... | provenance | Src:MaD:1 | -| tst.go:10:13:10:35 | call to FormValue | tst.go:43:11:43:17 | tainted | provenance | Src:MaD:1 | -| tst.go:42:2:42:2 | definition of u [pointer] | tst.go:43:2:43:2 | u [pointer] | provenance | | -| tst.go:43:2:43:2 | implicit dereference | tst.go:42:2:42:2 | definition of u [pointer] | provenance | | -| tst.go:43:2:43:2 | implicit dereference | tst.go:43:2:43:2 | u | provenance | | -| tst.go:43:2:43:2 | implicit dereference | tst.go:44:11:44:11 | u | provenance | | -| tst.go:43:2:43:2 | u | tst.go:43:2:43:2 | implicit dereference | provenance | | -| tst.go:43:2:43:2 | u | tst.go:44:11:44:11 | u | provenance | | -| tst.go:43:2:43:2 | u [pointer] | tst.go:43:2:43:2 | implicit dereference | provenance | | -| tst.go:43:11:43:17 | tainted | tst.go:43:2:43:2 | u | provenance | Config | -| tst.go:43:11:43:17 | tainted | tst.go:44:11:44:11 | u | provenance | Config | -| tst.go:44:11:44:11 | u | tst.go:44:11:44:20 | call to String | provenance | MaD:3 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:18:11:18:17 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:20:12:20:18 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:22:12:22:18 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:24:16:24:22 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:27:35:27:41 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:30:68:30:74 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:33:13:33:19 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:34:14:34:20 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:35:14:35:20 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:36:18:36:24 | tainted | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:38:11:38:29 | ...+... | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:40:11:40:40 | ...+... | provenance | Src:MaD:1 | +| tst.go:10:13:10:35 | call to FormValue | tst.go:47:11:47:18 | tainted2 | provenance | Src:MaD:1 | +| tst.go:46:2:46:2 | definition of u [pointer] | tst.go:47:2:47:2 | u [pointer] | provenance | | +| tst.go:47:2:47:2 | implicit dereference | tst.go:46:2:46:2 | definition of u [pointer] | provenance | | +| tst.go:47:2:47:2 | implicit dereference | tst.go:47:2:47:2 | u | provenance | | +| tst.go:47:2:47:2 | u | tst.go:47:2:47:2 | implicit dereference | provenance | | +| tst.go:47:2:47:2 | u | tst.go:48:11:48:11 | u | provenance | | +| tst.go:47:2:47:2 | u [pointer] | tst.go:47:2:47:2 | implicit dereference | provenance | | +| tst.go:47:11:47:18 | tainted2 | tst.go:47:2:47:2 | u | provenance | Config | +| tst.go:47:11:47:18 | tainted2 | tst.go:48:11:48:11 | u | provenance | Config | +| tst.go:48:11:48:11 | u | tst.go:48:11:48:20 | call to String | provenance | MaD:3 | | websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | provenance | Src:MaD:2 | | websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | provenance | Src:MaD:2 | | websocket.go:88:21:88:31 | call to Referer | websocket.go:91:31:91:44 | untrustedInput | provenance | Src:MaD:2 | @@ -64,25 +63,25 @@ nodes | RequestForgery.go:8:12:8:34 | call to FormValue | semmle.label | call to FormValue | | RequestForgery.go:11:24:11:65 | ...+... | semmle.label | ...+... | | tst.go:10:13:10:35 | call to FormValue | semmle.label | call to FormValue | -| tst.go:14:11:14:17 | tainted | semmle.label | tainted | -| tst.go:16:12:16:18 | tainted | semmle.label | tainted | -| tst.go:18:12:18:18 | tainted | semmle.label | tainted | -| tst.go:20:16:20:22 | tainted | semmle.label | tainted | -| tst.go:23:35:23:41 | tainted | semmle.label | tainted | -| tst.go:26:68:26:74 | tainted | semmle.label | tainted | -| tst.go:29:13:29:19 | tainted | semmle.label | tainted | -| tst.go:30:14:30:20 | tainted | semmle.label | tainted | -| tst.go:31:14:31:20 | tainted | semmle.label | tainted | -| tst.go:32:18:32:24 | tainted | semmle.label | tainted | -| tst.go:34:11:34:29 | ...+... | semmle.label | ...+... | -| tst.go:36:11:36:40 | ...+... | semmle.label | ...+... | -| tst.go:42:2:42:2 | definition of u [pointer] | semmle.label | definition of u [pointer] | -| tst.go:43:2:43:2 | implicit dereference | semmle.label | implicit dereference | -| tst.go:43:2:43:2 | u | semmle.label | u | -| tst.go:43:2:43:2 | u [pointer] | semmle.label | u [pointer] | -| tst.go:43:11:43:17 | tainted | semmle.label | tainted | -| tst.go:44:11:44:11 | u | semmle.label | u | -| tst.go:44:11:44:20 | call to String | semmle.label | call to String | +| tst.go:18:11:18:17 | tainted | semmle.label | tainted | +| tst.go:20:12:20:18 | tainted | semmle.label | tainted | +| tst.go:22:12:22:18 | tainted | semmle.label | tainted | +| tst.go:24:16:24:22 | tainted | semmle.label | tainted | +| tst.go:27:35:27:41 | tainted | semmle.label | tainted | +| tst.go:30:68:30:74 | tainted | semmle.label | tainted | +| tst.go:33:13:33:19 | tainted | semmle.label | tainted | +| tst.go:34:14:34:20 | tainted | semmle.label | tainted | +| tst.go:35:14:35:20 | tainted | semmle.label | tainted | +| tst.go:36:18:36:24 | tainted | semmle.label | tainted | +| tst.go:38:11:38:29 | ...+... | semmle.label | ...+... | +| tst.go:40:11:40:40 | ...+... | semmle.label | ...+... | +| tst.go:46:2:46:2 | definition of u [pointer] | semmle.label | definition of u [pointer] | +| tst.go:47:2:47:2 | implicit dereference | semmle.label | implicit dereference | +| tst.go:47:2:47:2 | u | semmle.label | u | +| tst.go:47:2:47:2 | u [pointer] | semmle.label | u [pointer] | +| tst.go:47:11:47:18 | tainted2 | semmle.label | tainted2 | +| tst.go:48:11:48:11 | u | semmle.label | u | +| tst.go:48:11:48:20 | call to String | semmle.label | call to String | | websocket.go:60:21:60:31 | call to Referer | semmle.label | call to Referer | | websocket.go:65:27:65:40 | untrustedInput | semmle.label | untrustedInput | | websocket.go:74:21:74:31 | call to Referer | semmle.label | call to Referer | diff --git a/go/ql/test/query-tests/Security/CWE-918/tst.go b/go/ql/test/query-tests/Security/CWE-918/tst.go index 44a172ddad0..02f65507abd 100644 --- a/go/ql/test/query-tests/Security/CWE-918/tst.go +++ b/go/ql/test/query-tests/Security/CWE-918/tst.go @@ -8,6 +8,10 @@ import ( func handler2(w http.ResponseWriter, req *http.Request) { tainted := req.FormValue("target") // $ Source + // Gratuitous copy due to use-use flow propagating sanitization when + // used as a suffix in the last two OK cases forwards onto the final + // Not OK case. + tainted2 := tainted http.Get("example.com") // OK @@ -40,7 +44,7 @@ func handler2(w http.ResponseWriter, req *http.Request) { http.Get("http://example.com/?" + tainted) // OK u, _ := url.Parse("http://example.com/relative-path") - u.Host = tainted + u.Host = tainted2 http.Get(u.String()) // $ Alert } From 4484d5bfa95c65b98bf3792e821ac8ad53e0342c Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 28 Nov 2023 16:02:14 +0000 Subject: [PATCH 07/70] Add missing QLDoc --- go/ql/lib/semmle/go/dataflow/SSA.qll | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/SSA.qll b/go/ql/lib/semmle/go/dataflow/SSA.qll index 5891c0ed800..b255c14f66c 100644 --- a/go/ql/lib/semmle/go/dataflow/SSA.qll +++ b/go/ql/lib/semmle/go/dataflow/SSA.qll @@ -198,6 +198,11 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef { override Location getLocation() { result = this.getInstruction().getLocation() } + /** + * Gets the first instruction that the value of this `SsaDefinition` can + * reach without passing through any other instructions, but possibly through + * phi nodes. + */ IR::Instruction getAFirstUse() { firstUse(this, result) } } @@ -413,4 +418,11 @@ DataFlow::Node getASimilarReadNode(DataFlow::Node node) { ) } +/** + * Gets an instruction such that `pred` and `result` form an adjacent + * use-use-pair of the same`SsaSourceVariable`, that is, the value read in + * `pred` can reach `result` without passing through any other use or any SSA + * definition of the variable except for phi nodes and uncertain implicit + * updates. + */ IR::Instruction getAnAdjacentUse(IR::Instruction pred) { adjacentUseUse(pred, result) } From 5267671b1502e3657c14c5a6f881ebbb21ad0044 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 28 Nov 2023 13:25:45 +0000 Subject: [PATCH 08/70] Clean up code in basicLocalFlowStep No changes in functionality. --- .../semmle/go/dataflow/internal/DataFlowPrivate.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 15f8a8462a1..ee612bde0e4 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -69,22 +69,22 @@ predicate basicLocalFlowStep(Node nodeFrom, Node nodeTo) { exists(IR::Instruction pred, SsaExplicitDefinition succ | succ.getRhs() = pred and nodeFrom = instructionNode(pred) and - nodeTo = ssaNode(succ) + nodeTo = ssaNode(succ.getVariable()) ) or // SSA defn -> SSA capture exists(SsaExplicitDefinition pred, SsaVariableCapture succ | // Check: should these flow from PHIs as well? Perhaps they should be included // in the use-use graph? - succ.(SsaVariableCapture).getSourceVariable() = pred.(SsaExplicitDefinition).getSourceVariable() + succ.getSourceVariable() = pred.getSourceVariable() | - nodeFrom = ssaNode(pred) and - nodeTo = ssaNode(succ) + nodeFrom = ssaNode(pred.getVariable()) and + nodeTo = ssaNode(succ.getVariable()) ) or // SSA defn -> first SSA use exists(SsaExplicitDefinition pred, IR::Instruction succ | succ = pred.getAFirstUse() | - nodeFrom = ssaNode(pred) and + nodeFrom = ssaNode(pred.getVariable()) and nodeTo = instructionNode(succ) ) or From b4743155f6c2f3a3c063a931f8a6631501171170 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 28 Nov 2023 15:47:55 +0000 Subject: [PATCH 09/70] Include first step from SsaVariableCapture Without this change the test go/ql/test/query-tests/InconsistentCode/UnhandledCloseWritableHandle/UnhandledCloseWritableHandle.qlref was failing. --- go/ql/lib/semmle/go/dataflow/SSA.qll | 14 +++++++------- .../go/dataflow/internal/DataFlowPrivate.qll | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/SSA.qll b/go/ql/lib/semmle/go/dataflow/SSA.qll index b255c14f66c..98dae5f3d01 100644 --- a/go/ql/lib/semmle/go/dataflow/SSA.qll +++ b/go/ql/lib/semmle/go/dataflow/SSA.qll @@ -166,6 +166,13 @@ class SsaDefinition extends TSsaDefinition { ) { this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } + + /** + * Gets the first instruction that the value of this `SsaDefinition` can + * reach without passing through any other instructions, but possibly through + * phi nodes. + */ + IR::Instruction getAFirstUse() { firstUse(this, result) } } /** @@ -197,13 +204,6 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef { override string prettyPrintDef() { result = "definition of " + this.getSourceVariable() } override Location getLocation() { result = this.getInstruction().getLocation() } - - /** - * Gets the first instruction that the value of this `SsaDefinition` can - * reach without passing through any other instructions, but possibly through - * phi nodes. - */ - IR::Instruction getAFirstUse() { firstUse(this, result) } } /** Provides a helper predicate for working with explicit SSA definitions. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index ee612bde0e4..3b8ed07c1a3 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -83,7 +83,8 @@ predicate basicLocalFlowStep(Node nodeFrom, Node nodeTo) { ) or // SSA defn -> first SSA use - exists(SsaExplicitDefinition pred, IR::Instruction succ | succ = pred.getAFirstUse() | + exists(SsaDefinition pred, IR::Instruction succ | succ = pred.getAFirstUse() | + (pred instanceof SsaExplicitDefinition or pred instanceof SsaVariableCapture) and nodeFrom = ssaNode(pred.getVariable()) and nodeTo = instructionNode(succ) ) From 49b8b0bca3e21e849cc46ad78ddc82650e36ee68 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 5 Sep 2025 14:20:06 +0100 Subject: [PATCH 10/70] Remove local flow step from SSA defn to SSA capture --- .../semmle/go/dataflow/internal/DataFlowPrivate.qll | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 3b8ed07c1a3..f05859de813 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -72,16 +72,6 @@ predicate basicLocalFlowStep(Node nodeFrom, Node nodeTo) { nodeTo = ssaNode(succ.getVariable()) ) or - // SSA defn -> SSA capture - exists(SsaExplicitDefinition pred, SsaVariableCapture succ | - // Check: should these flow from PHIs as well? Perhaps they should be included - // in the use-use graph? - succ.getSourceVariable() = pred.getSourceVariable() - | - nodeFrom = ssaNode(pred.getVariable()) and - nodeTo = ssaNode(succ.getVariable()) - ) - or // SSA defn -> first SSA use exists(SsaDefinition pred, IR::Instruction succ | succ = pred.getAFirstUse() | (pred instanceof SsaExplicitDefinition or pred instanceof SsaVariableCapture) and From 4e04d27d3212cffb0d694056d99bf07a8268c7b2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 29 Nov 2023 11:19:00 +0000 Subject: [PATCH 11/70] Adjust SafeFormatArgumentSanitizer to use-use flow Make it sanitize the result of the call rather than the input, so that further uses of the input are still tainted. This means that it catches things like `log.Print(fmt.Sprintf("user %q logged in.\n", username))` where the argument to the LoggerCall contains a StringFormatCall, but it misses things like `log.Printf("user %q logged in.\n", username)`. So we extract the logic into a predicate and apply it as a condition in the sink as well. The downside of this approach is that if there are two tainted inputs and only one has a safe format argument then we still sanitize the result. Hopefully this is rare. --- .../security/LogInjectionCustomizations.qll | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll b/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll index 565cf29a450..4518104d33a 100644 --- a/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll +++ b/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll @@ -35,7 +35,15 @@ module LogInjection { /** An argument to a logging mechanism. */ class LoggerSink extends Sink { - LoggerSink() { this = any(LoggerCall log).getAValueFormattedMessageComponent() } + LoggerSink() { + exists(LoggerCall call | + this = call.getAValueFormattedMessageComponent() and + // exclude arguments to `call` which have a safe format argument, which + // aren't caught by SafeFormatArgumentSanitizer as that sanitizes the + // result of the call. + not safeFormatArgument(this, call) + ) + } } /** @@ -47,6 +55,22 @@ module LogInjection { ReplaceSanitizer() { this.getReplacedString() = ["\r", "\n"] } } + /** + * Holds if `arg` is an argument to `call` that is formatted using the `%q` + * directive. This formatting directive replaces newline characters with + * escape sequences, so `arg` would not be a sink for log injection. + */ + private predicate safeFormatArgument( + DataFlow::Node arg, StringOps::Formatting::StringFormatCall call + ) { + exists(string safeDirective | + // Mark "%q" formats as safe, but not "%#q", which would preserve newline characters. + safeDirective.regexpMatch("%[^%#]*q") + | + arg = call.getOperand(_, safeDirective) + ) + } + /** * An argument that is formatted using the `%q` directive, considered as a sanitizer * for log injection. @@ -55,10 +79,10 @@ module LogInjection { */ private class SafeFormatArgumentSanitizer extends Sanitizer { SafeFormatArgumentSanitizer() { - exists(StringOps::Formatting::StringFormatCall call, string safeDirective | - this = call.getOperand(_, safeDirective) and - // Mark "%q" formats as safe, but not "%#q", which would preserve newline characters. - safeDirective.regexpMatch("%[^%#]*q") + exists(DataFlow::Node arg, StringOps::Formatting::StringFormatCall call | + safeFormatArgument(arg, call) + | + this = call.getAResult() ) } } From b2a9cecd69c3411ee63c1c0c70cebf3120a058e7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 30 Nov 2023 14:17:18 +0000 Subject: [PATCH 12/70] Fix Allocation Size Overflow for use-use flow We have an operator expression like `x * 5`. We want to follow where the value of the operator expression goes. We used to follow local flow from an operand, but now there is flow from that operand to the next use of the variable. The fix is to explicitly start local flow from the operator expression. There are also some expected edge changes due to use-use flow. --- .../AllocationSizeOverflowCustomizations.qll | 23 +++++++++++-------- .../CWE-190/AllocationSizeOverflow.expected | 10 ++++++-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/go/ql/lib/semmle/go/security/AllocationSizeOverflowCustomizations.qll b/go/ql/lib/semmle/go/security/AllocationSizeOverflowCustomizations.qll index 60841b048f4..3eced801f20 100644 --- a/go/ql/lib/semmle/go/security/AllocationSizeOverflowCustomizations.qll +++ b/go/ql/lib/semmle/go/security/AllocationSizeOverflowCustomizations.qll @@ -32,7 +32,10 @@ module AllocationSizeOverflow { /** * A data-flow node that is an operand to an operation that may overflow. */ - abstract class OverflowProneOperand extends DataFlow::Node { } + abstract class OverflowProneOperand extends DataFlow::Node { + /** Gets the operation that may overflow that `this` is an operand of. */ + abstract DataFlow::Node getOverflowProneOperation(); + } /** * A data-flow node that represents the size argument of an allocation, such as the `n` in @@ -91,8 +94,7 @@ module AllocationSizeOverflow { AllocationSize allocsz; DefaultSink() { - this instanceof OverflowProneOperand and - localStep*(this, allocsz) and + localStep*(this.(OverflowProneOperand).getOverflowProneOperation(), allocsz) and not allocsz instanceof AllocationSizeCheckBarrier } @@ -134,15 +136,18 @@ module AllocationSizeOverflow { /** An operand of an arithmetic expression that could cause overflow. */ private class DefaultOverflowProneOperand extends OverflowProneOperand { + OperatorExpr parent; + DefaultOverflowProneOperand() { - exists(OperatorExpr parent | isOverflowProne(parent) | - this.asExpr() = parent.getAnOperand() and - // only consider outermost operands to avoid double reporting - not exists(OperatorExpr grandparent | parent = grandparent.getAnOperand().stripParens() | - isOverflowProne(grandparent) - ) + isOverflowProne(parent) and + this.asExpr() = parent.getAnOperand() and + // only consider outermost operands to avoid double reporting + not exists(OperatorExpr grandparent | parent = grandparent.getAnOperand().stripParens() | + isOverflowProne(grandparent) ) } + + override DataFlow::Node getOverflowProneOperation() { result.asExpr() = parent } } /** diff --git a/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.expected b/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.expected index 3a9de1ebe60..ec1835a6f8a 100644 --- a/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.expected +++ b/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.expected @@ -17,10 +17,13 @@ edges | tst2.go:14:2:14:29 | ... := ...[0] | tst2.go:15:26:15:29 | data | provenance | | | tst2.go:15:26:15:29 | data | tst2.go:15:22:15:30 | call to len | provenance | Config | | tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:7:26:7:33 | jsonData | provenance | | -| tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:24:20:24:27 | jsonData | provenance | | -| tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:32:20:32:27 | jsonData | provenance | | | tst3.go:7:26:7:33 | jsonData | tst3.go:7:22:7:34 | call to len | provenance | Config | +| tst3.go:7:26:7:33 | jsonData | tst3.go:9:32:9:39 | jsonData | provenance | | +| tst3.go:9:32:9:39 | jsonData | tst3.go:11:9:11:16 | jsonData | provenance | | +| tst3.go:11:9:11:16 | jsonData | tst3.go:16:20:16:27 | jsonData | provenance | | +| tst3.go:16:20:16:27 | jsonData | tst3.go:24:20:24:27 | jsonData | provenance | | | tst3.go:24:20:24:27 | jsonData | tst3.go:24:16:24:28 | call to len | provenance | Config | +| tst3.go:24:20:24:27 | jsonData | tst3.go:32:20:32:27 | jsonData | provenance | | | tst3.go:32:20:32:27 | jsonData | tst3.go:32:16:32:28 | call to len | provenance | Config | | tst.go:14:2:14:30 | ... = ...[0] | tst.go:15:26:15:33 | jsonData | provenance | | | tst.go:15:26:15:33 | jsonData | tst.go:15:22:15:34 | call to len | provenance | Config | @@ -45,6 +48,9 @@ nodes | tst3.go:6:2:6:31 | ... := ...[0] | semmle.label | ... := ...[0] | | tst3.go:7:22:7:34 | call to len | semmle.label | call to len | | tst3.go:7:26:7:33 | jsonData | semmle.label | jsonData | +| tst3.go:9:32:9:39 | jsonData | semmle.label | jsonData | +| tst3.go:11:9:11:16 | jsonData | semmle.label | jsonData | +| tst3.go:16:20:16:27 | jsonData | semmle.label | jsonData | | tst3.go:24:16:24:28 | call to len | semmle.label | call to len | | tst3.go:24:20:24:27 | jsonData | semmle.label | jsonData | | tst3.go:32:16:32:28 | call to len | semmle.label | call to len | From 9068315f038c52a599b191e7952cc646ac7fe100 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 30 Nov 2023 21:23:22 +0000 Subject: [PATCH 13/70] Fix IncorrectIntegerConversion for use-use flow We were assuming that `sink` only had one successor, the TypeCastNode, but it can now have an adjacent use as well. --- .../go/security/IncorrectIntegerConversionLib.qll | 12 ++++++++---- .../CWE-681/IncorrectIntegerConversionQuery.ql | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll index 7864205d1dc..161916cd11e 100644 --- a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll +++ b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll @@ -290,13 +290,17 @@ private predicate integerTypeBound(IntegerType it, int bitSize, int architecture * the type assertion succeeded. If it is not checked then there will be a * run-time panic if the type assertion fails, so we can assume it succeeded. */ -class TypeAssertionCheck extends DataFlow::ExprNode, FlowStateTransformer { +class TypeAssertionCheck extends DataFlow::InstructionNode, FlowStateTransformer { IntegerType it; TypeAssertionCheck() { - exists(TypeAssertExpr tae | - this = DataFlow::exprNode(tae.getExpr()) and - it = tae.getTypeExpr().getType().getUnderlyingType() + exists(IR::Instruction evalAssert, TypeAssertExpr assert | + it = assert.getTypeExpr().getType().getUnderlyingType() and + evalAssert = IR::evalExprInstruction(assert) + | + if exists(IR::extractTupleElement(evalAssert, _)) + then this.asInstruction() = IR::extractTupleElement(evalAssert, 0) + else this.asInstruction() = evalAssert ) } diff --git a/go/ql/src/Security/CWE-681/IncorrectIntegerConversionQuery.ql b/go/ql/src/Security/CWE-681/IncorrectIntegerConversionQuery.ql index a310f024a2d..ce5081a92e9 100644 --- a/go/ql/src/Security/CWE-681/IncorrectIntegerConversionQuery.ql +++ b/go/ql/src/Security/CWE-681/IncorrectIntegerConversionQuery.ql @@ -18,7 +18,8 @@ import semmle.go.security.IncorrectIntegerConversionLib import Flow::PathGraph from - Flow::PathNode source, Flow::PathNode sink, DataFlow::CallNode call, DataFlow::Node sinkConverted + Flow::PathNode source, Flow::PathNode sink, DataFlow::CallNode call, + DataFlow::TypeCastNode sinkConverted where Flow::flowPath(source, sink) and call.getResult(0) = source.getNode() and From a3eb0100a653c3a4c37e9bae20cb332645e135ab Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 26 Jan 2021 14:00:06 +0000 Subject: [PATCH 14/70] Optimise join order for varBlockReaches --- go/ql/lib/semmle/go/dataflow/SsaImpl.qll | 39 +++++++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/SsaImpl.qll b/go/ql/lib/semmle/go/dataflow/SsaImpl.qll index 7380aaf60eb..fb1ec99c310 100644 --- a/go/ql/lib/semmle/go/dataflow/SsaImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/SsaImpl.qll @@ -306,6 +306,38 @@ private module Internal { exists(getDefReachingEndOf(b, v)) } + /** + * Holds if `v` occurs in `b1` and `b2` is one of `b1`'s successors. + * + * Factored out of `varBlockReaches` to force join order compared to the larger + * set `blockPrecedesVar(v, b2)`. + */ + pragma[noinline] + private predicate varBlockReachesBaseCand( + SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2 + ) { + varOccursInBlock(v, b1) and + b2 = b1.getASuccessor() + } + + /** + * Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and + * in `b2` or one of its transitive successors but not in any block on the path + * between `b1` and `b2`. Unlike `varBlockReaches` this may include blocks `b2` + * where `v` is dead. + * + * Factored out of `varBlockReaches` to force join order compared to the larger + * set `blockPrecedesVar(v, b2)`. + */ + pragma[noinline] + private predicate varBlockReachesRecCand( + SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock mid, ReachableBasicBlock b2 + ) { + varBlockReaches(v, b1, mid) and + not varOccursInBlock(v, mid) and + b2 = mid.getASuccessor() + } + /** * Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and * in `b2` or one of its transitive successors but not in any block on the path @@ -314,14 +346,11 @@ private module Internal { private predicate varBlockReaches( SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2 ) { - varOccursInBlock(v, b1) and - b2 = b1.getASuccessor() and + varBlockReachesBaseCand(v, b1, b2) and blockPrecedesVar(v, b2) or exists(ReachableBasicBlock mid | - varBlockReaches(v, b1, mid) and - b2 = mid.getASuccessor() and - not varOccursInBlock(v, mid) and + varBlockReachesRecCand(v, b1, mid, b2) and blockPrecedesVar(v, b2) ) } From 32de2113a6a5057c121884eed42848aca7644769 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Sep 2025 15:51:37 +0100 Subject: [PATCH 15/70] Use `_` instead of exists variable x2 --- go/ql/lib/semmle/go/dataflow/SsaImpl.qll | 6 ++---- go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/SsaImpl.qll b/go/ql/lib/semmle/go/dataflow/SsaImpl.qll index fb1ec99c310..8549d9b497a 100644 --- a/go/ql/lib/semmle/go/dataflow/SsaImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/SsaImpl.qll @@ -349,10 +349,8 @@ private module Internal { varBlockReachesBaseCand(v, b1, b2) and blockPrecedesVar(v, b2) or - exists(ReachableBasicBlock mid | - varBlockReachesRecCand(v, b1, mid, b2) and - blockPrecedesVar(v, b2) - ) + varBlockReachesRecCand(v, b1, _, b2) and + blockPrecedesVar(v, b2) } /** diff --git a/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll b/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll index 4518104d33a..9160c204df1 100644 --- a/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll +++ b/go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll @@ -79,9 +79,7 @@ module LogInjection { */ private class SafeFormatArgumentSanitizer extends Sanitizer { SafeFormatArgumentSanitizer() { - exists(DataFlow::Node arg, StringOps::Formatting::StringFormatCall call | - safeFormatArgument(arg, call) - | + exists(StringOps::Formatting::StringFormatCall call | safeFormatArgument(_, call) | this = call.getAResult() ) } From 3594dba83c91471e217064aa6e6fc16497260c87 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 6 Mar 2025 15:05:17 +0000 Subject: [PATCH 16/70] Make insecure randomness test more realistic --- .../InsecureRandomness/InsecureRandomness.expected | 9 +++------ .../Security/CWE-338/InsecureRandomness/sample.go | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) 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 b2659fffde7..40be0e8df69 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 @@ -1,8 +1,7 @@ #select | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | InsecureRandomness.go:12:18:12:40 | call to Intn | random number | | sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 | sample.go:26:25:26:30 | call to Guid | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:15:49:15:61 | call to Uint32 | random number | -| sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New | sample.go:37:25:37:29 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | -| sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New | sample.go:37:32:37:36 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | +| sample.go:37:35:37:39 | nonce | sample.go:34:12:34:40 | call to New | sample.go:37:35:37:39 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | | 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 @@ -13,8 +12,7 @@ edges | 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 expression | 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:33:2:33:6 | definition of nonce | sample.go:37:35:37:39 | nonce | provenance | | | sample.go:34:12:34:40 | call to New | sample.go:35:14:35:19 | random | provenance | | | sample.go:35:14:35:19 | random | sample.go:33:2:33:6 | definition of nonce | provenance | MaD:2 | | sample.go:55:17:55:42 | call to Intn | sample.go:56:29:56:38 | randNumber | provenance | | @@ -36,8 +34,7 @@ nodes | 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 | | sample.go:35:14:35:19 | random | semmle.label | random | -| sample.go:37:25:37:29 | nonce | semmle.label | nonce | -| sample.go:37:32:37:36 | nonce | semmle.label | nonce | +| sample.go:37:35:37:39 | nonce | semmle.label | nonce | | sample.go:43:17:43:39 | call to Intn | semmle.label | call to Intn | | sample.go:44:17:44:39 | call to Intn | semmle.label | call to Intn | | sample.go:45:17:45:39 | call to Intn | semmle.label | call to Intn | diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/sample.go b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/sample.go index df703ff0dfa..9eef81f63bb 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/sample.go +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/sample.go @@ -34,7 +34,7 @@ func encrypt(data []byte, password string) []byte { random := rand.New(rand.NewSource(999)) io.ReadFull(random, nonce) - ciphertext := gcm.Seal(nonce, nonce, data, nil) // BAD: use of an insecure rng to generate a nonce + ciphertext := gcm.Seal(data[:0], nonce, data, nil) // BAD: use of an insecure rng to generate a nonce return ciphertext } From 521066578bc5a05b590c4dc82648742cc90d0899 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 10 Nov 2023 14:58:52 +0000 Subject: [PATCH 17/70] Test result that was missing is now found --- .../library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go | 2 +- .../library-tests/semmle/go/dataflow/ExternalValueFlow/test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go index 14b9a43b599..c9d732e7400 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go @@ -158,7 +158,7 @@ func simpleflow() { ch := make(chan string) ch <- a.Src1().(string) taint16 := test.StepArgCollectionContentRes(ch) - b.Sink1(taint16) // $ MISSING: hasTaintFlow="taint16" // currently fails due to lack of post-update nodes after send statements + b.Sink1(taint16) // $ hasTaintFlow="taint16" c1 := test.C{""} c1.Set(a.Src1().(string)) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go index f118880d497..3c172e6082d 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go @@ -158,7 +158,7 @@ func simpleflow() { ch := make(chan string) ch <- a.Src1().(string) taint16 := test.StepArgCollectionContentRes(ch) - b.Sink1(taint16) // $ MISSING: hasValueFlow="taint16" // currently fails due to lack of post-update nodes after send statements + b.Sink1(taint16) // $ hasValueFlow="taint16" c1 := test.C{""} c1.Set(a.Src1().(string)) From c20abf6d58fd93d54bc3f7a5ec92e8f774dfdc4c Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 29 Nov 2023 15:30:29 +0000 Subject: [PATCH 18/70] Line numbers change because 3 lines were added --- .../go/frameworks/Echo/TaintedPath.expected | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/TaintedPath.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/TaintedPath.expected index c579c480fb3..6a26aba5d76 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/TaintedPath.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/TaintedPath.expected @@ -1,16 +1,16 @@ #select -| test.go:222:17:222:24 | filepath | test.go:221:15:221:38 | call to QueryParam | test.go:222:17:222:24 | filepath | This path depends on a $@. | test.go:221:15:221:38 | call to QueryParam | user-provided value | -| test.go:226:23:226:30 | filepath | test.go:225:15:225:38 | call to QueryParam | test.go:226:23:226:30 | filepath | This path depends on a $@. | test.go:225:15:225:38 | call to QueryParam | user-provided value | +| test.go:225:17:225:24 | filepath | test.go:224:15:224:38 | call to QueryParam | test.go:225:17:225:24 | filepath | This path depends on a $@. | test.go:224:15:224:38 | call to QueryParam | user-provided value | +| test.go:229:23:229:30 | filepath | test.go:228:15:228:38 | call to QueryParam | test.go:229:23:229:30 | filepath | This path depends on a $@. | test.go:228:15:228:38 | call to QueryParam | user-provided value | edges -| test.go:221:15:221:38 | call to QueryParam | test.go:222:17:222:24 | filepath | provenance | Src:MaD:3 Sink:MaD:2 | -| test.go:225:15:225:38 | call to QueryParam | test.go:226:23:226:30 | filepath | provenance | Src:MaD:3 Sink:MaD:1 | +| test.go:224:15:224:38 | call to QueryParam | test.go:225:17:225:24 | filepath | provenance | Src:MaD:3 Sink:MaD:2 | +| test.go:228:15:228:38 | call to QueryParam | test.go:229:23:229:30 | filepath | provenance | Src:MaD:3 Sink:MaD:1 | models | 1 | Sink: github.com/labstack/echo; Context; true; Attachment; ; ; Argument[0]; path-injection; manual | | 2 | Sink: github.com/labstack/echo; Context; true; File; ; ; Argument[0]; path-injection; manual | | 3 | Source: github.com/labstack/echo; Context; true; QueryParam; ; ; ReturnValue[0]; remote; manual | nodes -| test.go:221:15:221:38 | call to QueryParam | semmle.label | call to QueryParam | -| test.go:222:17:222:24 | filepath | semmle.label | filepath | -| test.go:225:15:225:38 | call to QueryParam | semmle.label | call to QueryParam | -| test.go:226:23:226:30 | filepath | semmle.label | filepath | +| test.go:224:15:224:38 | call to QueryParam | semmle.label | call to QueryParam | +| test.go:225:17:225:24 | filepath | semmle.label | filepath | +| test.go:228:15:228:38 | call to QueryParam | semmle.label | call to QueryParam | +| test.go:229:23:229:30 | filepath | semmle.label | filepath | subpaths From 14301e0af4bef171c8fe9ffd6f35a9c73c3f68a2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 10 Nov 2023 15:28:21 +0000 Subject: [PATCH 19/70] Expected changes in dataflow edges --- .../CWE-1004/CookieWithoutHttpOnly.expected | 35 +++--- .../DecompressionBombs.expected | 2 +- .../dataflow/FlowSteps/LocalFlowStep.expected | 3 +- .../PromotedFields/LocalFlowStep.expected | 112 +++++++++--------- .../Beego/CleartextLogging.expected | 103 ++++++++++------ .../Security/CWE-022/TaintedPath.expected | 2 +- .../CWE-078/CommandInjection.expected | 16 +-- .../Security/CWE-078/SanitizingDoubleDash.go | 22 ++-- .../Security/CWE-089/SqlInjection.expected | 24 ++-- 9 files changed, 174 insertions(+), 145 deletions(-) diff --git a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected index 5c7bef1155e..0c60eb3f97e 100644 --- a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected +++ b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected @@ -255,8 +255,6 @@ edges | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | | CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | provenance | Config | @@ -272,8 +270,6 @@ edges | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | provenance | | @@ -282,12 +278,14 @@ edges | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | Config | @@ -298,7 +296,6 @@ edges | CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | | CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | @@ -312,14 +309,14 @@ edges | CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | provenance | | | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | provenance | | | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:149:2:149:8 | session | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | | +| CookieWithoutHttpOnly.go:149:2:149:8 | session | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | | +| CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | Config | | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:149:20:151:2 | &... | provenance | | @@ -329,8 +326,6 @@ edges | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | | CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | @@ -346,8 +341,6 @@ edges | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | provenance | | @@ -356,12 +349,14 @@ edges | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | Config | @@ -376,8 +371,6 @@ edges | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | | CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | @@ -393,8 +386,6 @@ edges | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | provenance | | @@ -403,12 +394,14 @@ edges | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | Config | diff --git a/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombs.expected b/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombs.expected index 34703cdeef4..46bccc77a97 100644 --- a/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombs.expected +++ b/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombs.expected @@ -68,9 +68,9 @@ edges | test.go:91:15:91:26 | selection of Body | test.go:555:19:555:22 | definition of file | provenance | Src:MaD:1 | | test.go:93:5:93:16 | selection of Body | test.go:580:9:580:12 | definition of file | provenance | Src:MaD:1 | | test.go:128:20:128:27 | definition of filename | test.go:130:33:130:40 | filename | provenance | | -| test.go:128:20:128:27 | definition of filename | test.go:143:51:143:58 | filename | provenance | | | test.go:130:2:130:41 | ... := ...[0] | test.go:132:12:132:12 | f | provenance | | | test.go:130:33:130:40 | filename | test.go:130:2:130:41 | ... := ...[0] | provenance | Config | +| test.go:130:33:130:40 | filename | test.go:143:51:143:58 | filename | provenance | | | test.go:132:3:132:19 | ... := ...[0] | test.go:134:37:134:38 | rc | provenance | | | test.go:132:12:132:12 | f | test.go:132:3:132:19 | ... := ...[0] | provenance | MaD:4 | | test.go:143:2:143:59 | ... := ...[0] | test.go:145:12:145:12 | f | provenance | | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected index b48b6fec1a7..cf8a278a903 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected @@ -68,9 +68,8 @@ | main.go:11:14:11:14 | z | main.go:11:9:11:15 | type conversion | | main.go:14:6:14:10 | function test2 | main.go:34:8:34:12 | test2 | | main.go:14:6:14:10 | function test2 | main.go:34:19:34:23 | test2 | -| main.go:15:2:15:4 | definition of acc | main.go:16:9:19:2 | capture variable acc | | main.go:15:9:15:9 | 0 | main.go:15:2:15:4 | definition of acc | -| main.go:17:3:17:7 | definition of acc | main.go:16:9:19:2 | capture variable acc | +| main.go:16:9:19:2 | capture variable acc | main.go:17:3:17:5 | acc | | main.go:17:3:17:7 | definition of acc | main.go:18:10:18:12 | acc | | main.go:17:3:17:7 | rhs of increment statement | main.go:17:3:17:7 | definition of acc | | main.go:22:12:22:12 | argument corresponding to b | main.go:22:12:22:12 | definition of b | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/LocalFlowStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/LocalFlowStep.expected index d61d6be9c5f..a74e39db2f1 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/LocalFlowStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/LocalFlowStep.expected @@ -79,106 +79,106 @@ | main.go:7:6:7:9 | function sink | main.go:149:2:149:5 | sink | | main.go:7:6:7:9 | function sink | main.go:150:2:150:5 | sink | | main.go:22:2:22:6 | definition of outer | main.go:25:7:25:11 | outer | -| main.go:22:2:22:6 | definition of outer | main.go:26:7:26:11 | outer | -| main.go:22:2:22:6 | definition of outer | main.go:27:7:27:11 | outer | -| main.go:22:2:22:6 | definition of outer | main.go:28:7:28:11 | outer | | main.go:22:11:24:2 | struct literal | main.go:22:2:22:6 | definition of outer | +| main.go:25:7:25:11 | outer | main.go:26:7:26:11 | outer | +| main.go:26:7:26:11 | outer | main.go:27:7:27:11 | outer | +| main.go:27:7:27:11 | outer | main.go:28:7:28:11 | outer | | main.go:30:2:30:7 | definition of outerp | main.go:33:7:33:12 | outerp | -| main.go:30:2:30:7 | definition of outerp | main.go:34:7:34:12 | outerp | -| main.go:30:2:30:7 | definition of outerp | main.go:35:7:35:12 | outerp | -| main.go:30:2:30:7 | definition of outerp | main.go:36:7:36:12 | outerp | | main.go:30:12:32:2 | &... | main.go:30:2:30:7 | definition of outerp | +| main.go:33:7:33:12 | outerp | main.go:34:7:34:12 | outerp | +| main.go:34:7:34:12 | outerp | main.go:35:7:35:12 | outerp | +| main.go:35:7:35:12 | outerp | main.go:36:7:36:12 | outerp | | main.go:40:2:40:6 | definition of outer | main.go:41:7:41:11 | outer | -| main.go:40:2:40:6 | definition of outer | main.go:42:7:42:11 | outer | -| main.go:40:2:40:6 | definition of outer | main.go:43:7:43:11 | outer | -| main.go:40:2:40:6 | definition of outer | main.go:44:7:44:11 | outer | | main.go:40:11:40:40 | struct literal | main.go:40:2:40:6 | definition of outer | +| main.go:41:7:41:11 | outer | main.go:42:7:42:11 | outer | +| main.go:42:7:42:11 | outer | main.go:43:7:43:11 | outer | +| main.go:43:7:43:11 | outer | main.go:44:7:44:11 | outer | | main.go:46:2:46:7 | definition of outerp | main.go:47:7:47:12 | outerp | -| main.go:46:2:46:7 | definition of outerp | main.go:48:7:48:12 | outerp | -| main.go:46:2:46:7 | definition of outerp | main.go:49:7:49:12 | outerp | -| main.go:46:2:46:7 | definition of outerp | main.go:50:7:50:12 | outerp | | main.go:46:12:46:42 | &... | main.go:46:2:46:7 | definition of outerp | +| main.go:47:7:47:12 | outerp | main.go:48:7:48:12 | outerp | +| main.go:48:7:48:12 | outerp | main.go:49:7:49:12 | outerp | +| main.go:49:7:49:12 | outerp | main.go:50:7:50:12 | outerp | | main.go:54:2:54:6 | definition of inner | main.go:55:19:55:23 | inner | | main.go:54:11:54:25 | struct literal | main.go:54:2:54:6 | definition of inner | | main.go:55:2:55:7 | definition of middle | main.go:56:17:56:22 | middle | | main.go:55:12:55:24 | struct literal | main.go:55:2:55:7 | definition of middle | | main.go:56:2:56:6 | definition of outer | main.go:57:7:57:11 | outer | -| main.go:56:2:56:6 | definition of outer | main.go:58:7:58:11 | outer | -| main.go:56:2:56:6 | definition of outer | main.go:59:7:59:11 | outer | -| main.go:56:2:56:6 | definition of outer | main.go:60:7:60:11 | outer | | main.go:56:11:56:23 | struct literal | main.go:56:2:56:6 | definition of outer | +| main.go:57:7:57:11 | outer | main.go:58:7:58:11 | outer | +| main.go:58:7:58:11 | outer | main.go:59:7:59:11 | outer | +| main.go:59:7:59:11 | outer | main.go:60:7:60:11 | outer | | main.go:62:2:62:7 | definition of innerp | main.go:63:20:63:25 | innerp | | main.go:62:12:62:26 | struct literal | main.go:62:2:62:7 | definition of innerp | | main.go:63:2:63:8 | definition of middlep | main.go:64:18:64:24 | middlep | | main.go:63:13:63:26 | struct literal | main.go:63:2:63:8 | definition of middlep | | main.go:64:2:64:7 | definition of outerp | main.go:65:7:65:12 | outerp | -| main.go:64:2:64:7 | definition of outerp | main.go:66:7:66:12 | outerp | -| main.go:64:2:64:7 | definition of outerp | main.go:67:7:67:12 | outerp | -| main.go:64:2:64:7 | definition of outerp | main.go:68:7:68:12 | outerp | | main.go:64:12:64:25 | struct literal | main.go:64:2:64:7 | definition of outerp | +| main.go:65:7:65:12 | outerp | main.go:66:7:66:12 | outerp | +| main.go:66:7:66:12 | outerp | main.go:67:7:67:12 | outerp | +| main.go:67:7:67:12 | outerp | main.go:68:7:68:12 | outerp | | main.go:72:2:72:6 | definition of inner | main.go:73:26:73:30 | inner | | main.go:72:11:72:25 | struct literal | main.go:72:2:72:6 | definition of inner | | main.go:73:2:73:7 | definition of middle | main.go:74:25:74:30 | middle | | main.go:73:12:73:31 | struct literal | main.go:73:2:73:7 | definition of middle | | main.go:74:2:74:6 | definition of outer | main.go:75:7:75:11 | outer | -| main.go:74:2:74:6 | definition of outer | main.go:76:7:76:11 | outer | -| main.go:74:2:74:6 | definition of outer | main.go:77:7:77:11 | outer | -| main.go:74:2:74:6 | definition of outer | main.go:78:7:78:11 | outer | | main.go:74:11:74:31 | struct literal | main.go:74:2:74:6 | definition of outer | +| main.go:75:7:75:11 | outer | main.go:76:7:76:11 | outer | +| main.go:76:7:76:11 | outer | main.go:77:7:77:11 | outer | +| main.go:77:7:77:11 | outer | main.go:78:7:78:11 | outer | | main.go:80:2:80:7 | definition of innerp | main.go:81:27:81:32 | innerp | | main.go:80:12:80:26 | struct literal | main.go:80:2:80:7 | definition of innerp | | main.go:81:2:81:8 | definition of middlep | main.go:82:26:82:32 | middlep | | main.go:81:13:81:33 | struct literal | main.go:81:2:81:8 | definition of middlep | | main.go:82:2:82:7 | definition of outerp | main.go:83:7:83:12 | outerp | -| main.go:82:2:82:7 | definition of outerp | main.go:84:7:84:12 | outerp | -| main.go:82:2:82:7 | definition of outerp | main.go:85:7:85:12 | outerp | -| main.go:82:2:82:7 | definition of outerp | main.go:86:7:86:12 | outerp | | main.go:82:12:82:33 | struct literal | main.go:82:2:82:7 | definition of outerp | +| main.go:83:7:83:12 | outerp | main.go:84:7:84:12 | outerp | +| main.go:84:7:84:12 | outerp | main.go:85:7:85:12 | outerp | +| main.go:85:7:85:12 | outerp | main.go:86:7:86:12 | outerp | | main.go:90:6:90:10 | definition of outer | main.go:91:2:91:6 | outer | -| main.go:90:6:90:10 | definition of outer | main.go:92:7:92:11 | outer | -| main.go:90:6:90:10 | definition of outer | main.go:93:7:93:11 | outer | -| main.go:90:6:90:10 | definition of outer | main.go:94:7:94:11 | outer | -| main.go:90:6:90:10 | definition of outer | main.go:95:7:95:11 | outer | | main.go:90:6:90:10 | zero value for outer | main.go:90:6:90:10 | definition of outer | +| main.go:91:2:91:6 | outer | main.go:92:7:92:11 | outer | +| main.go:92:7:92:11 | outer | main.go:93:7:93:11 | outer | +| main.go:93:7:93:11 | outer | main.go:94:7:94:11 | outer | +| main.go:94:7:94:11 | outer | main.go:95:7:95:11 | outer | | main.go:97:6:97:11 | definition of outerp | main.go:98:2:98:7 | outerp | -| main.go:97:6:97:11 | definition of outerp | main.go:99:7:99:12 | outerp | -| main.go:97:6:97:11 | definition of outerp | main.go:100:7:100:12 | outerp | -| main.go:97:6:97:11 | definition of outerp | main.go:101:7:101:12 | outerp | -| main.go:97:6:97:11 | definition of outerp | main.go:102:7:102:12 | outerp | | main.go:97:6:97:11 | zero value for outerp | main.go:97:6:97:11 | definition of outerp | +| main.go:98:2:98:7 | outerp | main.go:99:7:99:12 | outerp | +| main.go:99:7:99:12 | outerp | main.go:100:7:100:12 | outerp | +| main.go:100:7:100:12 | outerp | main.go:101:7:101:12 | outerp | +| main.go:101:7:101:12 | outerp | main.go:102:7:102:12 | outerp | | main.go:106:6:106:10 | definition of outer | main.go:107:2:107:6 | outer | -| main.go:106:6:106:10 | definition of outer | main.go:108:7:108:11 | outer | -| main.go:106:6:106:10 | definition of outer | main.go:109:7:109:11 | outer | -| main.go:106:6:106:10 | definition of outer | main.go:110:7:110:11 | outer | -| main.go:106:6:106:10 | definition of outer | main.go:111:7:111:11 | outer | | main.go:106:6:106:10 | zero value for outer | main.go:106:6:106:10 | definition of outer | +| main.go:107:2:107:6 | outer | main.go:108:7:108:11 | outer | +| main.go:108:7:108:11 | outer | main.go:109:7:109:11 | outer | +| main.go:109:7:109:11 | outer | main.go:110:7:110:11 | outer | +| main.go:110:7:110:11 | outer | main.go:111:7:111:11 | outer | | main.go:113:6:113:11 | definition of outerp | main.go:114:2:114:7 | outerp | -| main.go:113:6:113:11 | definition of outerp | main.go:115:7:115:12 | outerp | -| main.go:113:6:113:11 | definition of outerp | main.go:116:7:116:12 | outerp | -| main.go:113:6:113:11 | definition of outerp | main.go:117:7:117:12 | outerp | -| main.go:113:6:113:11 | definition of outerp | main.go:118:7:118:12 | outerp | | main.go:113:6:113:11 | zero value for outerp | main.go:113:6:113:11 | definition of outerp | +| main.go:114:2:114:7 | outerp | main.go:115:7:115:12 | outerp | +| main.go:115:7:115:12 | outerp | main.go:116:7:116:12 | outerp | +| main.go:116:7:116:12 | outerp | main.go:117:7:117:12 | outerp | +| main.go:117:7:117:12 | outerp | main.go:118:7:118:12 | outerp | | main.go:122:6:122:10 | definition of outer | main.go:123:2:123:6 | outer | -| main.go:122:6:122:10 | definition of outer | main.go:124:7:124:11 | outer | -| main.go:122:6:122:10 | definition of outer | main.go:125:7:125:11 | outer | -| main.go:122:6:122:10 | definition of outer | main.go:126:7:126:11 | outer | -| main.go:122:6:122:10 | definition of outer | main.go:127:7:127:11 | outer | | main.go:122:6:122:10 | zero value for outer | main.go:122:6:122:10 | definition of outer | +| main.go:123:2:123:6 | outer | main.go:124:7:124:11 | outer | +| main.go:124:7:124:11 | outer | main.go:125:7:125:11 | outer | +| main.go:125:7:125:11 | outer | main.go:126:7:126:11 | outer | +| main.go:126:7:126:11 | outer | main.go:127:7:127:11 | outer | | main.go:129:6:129:11 | definition of outerp | main.go:130:2:130:7 | outerp | -| main.go:129:6:129:11 | definition of outerp | main.go:131:7:131:12 | outerp | -| main.go:129:6:129:11 | definition of outerp | main.go:132:7:132:12 | outerp | -| main.go:129:6:129:11 | definition of outerp | main.go:133:7:133:12 | outerp | -| main.go:129:6:129:11 | definition of outerp | main.go:134:7:134:12 | outerp | | main.go:129:6:129:11 | zero value for outerp | main.go:129:6:129:11 | definition of outerp | +| main.go:130:2:130:7 | outerp | main.go:131:7:131:12 | outerp | +| main.go:131:7:131:12 | outerp | main.go:132:7:132:12 | outerp | +| main.go:132:7:132:12 | outerp | main.go:133:7:133:12 | outerp | +| main.go:133:7:133:12 | outerp | main.go:134:7:134:12 | outerp | | main.go:138:6:138:10 | definition of outer | main.go:139:2:139:6 | outer | -| main.go:138:6:138:10 | definition of outer | main.go:140:7:140:11 | outer | -| main.go:138:6:138:10 | definition of outer | main.go:141:7:141:11 | outer | -| main.go:138:6:138:10 | definition of outer | main.go:142:7:142:11 | outer | -| main.go:138:6:138:10 | definition of outer | main.go:143:7:143:11 | outer | | main.go:138:6:138:10 | zero value for outer | main.go:138:6:138:10 | definition of outer | +| main.go:139:2:139:6 | outer | main.go:140:7:140:11 | outer | +| main.go:140:7:140:11 | outer | main.go:141:7:141:11 | outer | +| main.go:141:7:141:11 | outer | main.go:142:7:142:11 | outer | +| main.go:142:7:142:11 | outer | main.go:143:7:143:11 | outer | | main.go:145:6:145:11 | definition of outerp | main.go:146:2:146:7 | outerp | -| main.go:145:6:145:11 | definition of outerp | main.go:147:7:147:12 | outerp | -| main.go:145:6:145:11 | definition of outerp | main.go:148:7:148:12 | outerp | -| main.go:145:6:145:11 | definition of outerp | main.go:149:7:149:12 | outerp | -| main.go:145:6:145:11 | definition of outerp | main.go:150:7:150:12 | outerp | | main.go:145:6:145:11 | zero value for outerp | main.go:145:6:145:11 | definition of outerp | +| main.go:146:2:146:7 | outerp | main.go:147:7:147:12 | outerp | +| main.go:147:7:147:12 | outerp | main.go:148:7:148:12 | outerp | +| main.go:148:7:148:12 | outerp | main.go:149:7:149:12 | outerp | +| main.go:149:7:149:12 | outerp | main.go:150:7:150:12 | outerp | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.expected index 6fd71942356..591d990be47 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/CleartextLogging.expected @@ -1,5 +1,40 @@ edges +| test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:156:14:156:21 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:157:18:157:25 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:158:14:158:21 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:159:13:159:20 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:160:22:160:29 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:161:15:161:22 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | provenance | | +| test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | provenance | Sink:MaD:380 | +| test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | provenance | Sink:MaD:381 | +| test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | provenance | Sink:MaD:382 | +| test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | provenance | Sink:MaD:383 | +| test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | provenance | Sink:MaD:384 | +| test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | provenance | Sink:MaD:385 | +| test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | provenance | Sink:MaD:386 | +| test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | provenance | Sink:MaD:387 | +| test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | provenance | Sink:MaD:388 | +| test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | provenance | Sink:MaD:389 | +| test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | provenance | Sink:MaD:390 | +| test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | provenance | Sink:MaD:391 | +| test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | provenance | Sink:MaD:392 | +| test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | provenance | Sink:MaD:393 | +| test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | provenance | Sink:MaD:394 | +| test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | provenance | Sink:MaD:395 | +| test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | provenance | Sink:MaD:396 | +| test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | provenance | Sink:MaD:397 | +| test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | provenance | Sink:MaD:398 | +| test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | provenance | Sink:MaD:399 | +| test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | provenance | Sink:MaD:400 | +| test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | provenance | Sink:MaD:401 | +| test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | provenance | | nodes +| test.go:153:17:153:24 | definition of password | semmle.label | definition of password | | test.go:154:14:154:21 | password | semmle.label | password | | test.go:155:17:155:24 | password | semmle.label | password | | test.go:156:14:156:21 | password | semmle.label | password | @@ -36,37 +71,37 @@ nodes | test.go:187:16:187:23 | password | semmle.label | password | subpaths #select -| test.go:154:14:154:21 | password | test.go:154:14:154:21 | password | test.go:154:14:154:21 | password | $@ flows to a logging call. | test.go:154:14:154:21 | password | Sensitive data returned by an access to password | -| test.go:155:17:155:24 | password | test.go:155:17:155:24 | password | test.go:155:17:155:24 | password | $@ flows to a logging call. | test.go:155:17:155:24 | password | Sensitive data returned by an access to password | -| test.go:156:14:156:21 | password | test.go:156:14:156:21 | password | test.go:156:14:156:21 | password | $@ flows to a logging call. | test.go:156:14:156:21 | password | Sensitive data returned by an access to password | -| test.go:157:18:157:25 | password | test.go:157:18:157:25 | password | test.go:157:18:157:25 | password | $@ flows to a logging call. | test.go:157:18:157:25 | password | Sensitive data returned by an access to password | -| test.go:158:14:158:21 | password | test.go:158:14:158:21 | password | test.go:158:14:158:21 | password | $@ flows to a logging call. | test.go:158:14:158:21 | password | Sensitive data returned by an access to password | -| test.go:159:13:159:20 | password | test.go:159:13:159:20 | password | test.go:159:13:159:20 | password | $@ flows to a logging call. | test.go:159:13:159:20 | password | Sensitive data returned by an access to password | -| test.go:160:22:160:29 | password | test.go:160:22:160:29 | password | test.go:160:22:160:29 | password | $@ flows to a logging call. | test.go:160:22:160:29 | password | Sensitive data returned by an access to password | -| test.go:161:15:161:22 | password | test.go:161:15:161:22 | password | test.go:161:15:161:22 | password | $@ flows to a logging call. | test.go:161:15:161:22 | password | Sensitive data returned by an access to password | -| test.go:162:14:162:21 | password | test.go:162:14:162:21 | password | test.go:162:14:162:21 | password | $@ flows to a logging call. | test.go:162:14:162:21 | password | Sensitive data returned by an access to password | -| test.go:163:13:163:20 | password | test.go:163:13:163:20 | password | test.go:163:13:163:20 | password | $@ flows to a logging call. | test.go:163:13:163:20 | password | Sensitive data returned by an access to password | -| test.go:164:16:164:23 | password | test.go:164:16:164:23 | password | test.go:164:16:164:23 | password | $@ flows to a logging call. | test.go:164:16:164:23 | password | Sensitive data returned by an access to password | -| test.go:165:13:165:20 | password | test.go:165:13:165:20 | password | test.go:165:13:165:20 | password | $@ flows to a logging call. | test.go:165:13:165:20 | password | Sensitive data returned by an access to password | -| test.go:166:16:166:23 | password | test.go:166:16:166:23 | password | test.go:166:16:166:23 | password | $@ flows to a logging call. | test.go:166:16:166:23 | password | Sensitive data returned by an access to password | -| test.go:167:13:167:20 | password | test.go:167:13:167:20 | password | test.go:167:13:167:20 | password | $@ flows to a logging call. | test.go:167:13:167:20 | password | Sensitive data returned by an access to password | -| test.go:168:17:168:24 | password | test.go:168:17:168:24 | password | test.go:168:17:168:24 | password | $@ flows to a logging call. | test.go:168:17:168:24 | password | Sensitive data returned by an access to password | -| test.go:169:13:169:20 | password | test.go:169:13:169:20 | password | test.go:169:13:169:20 | password | $@ flows to a logging call. | test.go:169:13:169:20 | password | Sensitive data returned by an access to password | -| test.go:170:12:170:19 | password | test.go:170:12:170:19 | password | test.go:170:12:170:19 | password | $@ flows to a logging call. | test.go:170:12:170:19 | password | Sensitive data returned by an access to password | -| test.go:171:21:171:28 | password | test.go:171:21:171:28 | password | test.go:171:21:171:28 | password | $@ flows to a logging call. | test.go:171:21:171:28 | password | Sensitive data returned by an access to password | -| test.go:172:14:172:21 | password | test.go:172:14:172:21 | password | test.go:172:14:172:21 | password | $@ flows to a logging call. | test.go:172:14:172:21 | password | Sensitive data returned by an access to password | -| test.go:173:13:173:20 | password | test.go:173:13:173:20 | password | test.go:173:13:173:20 | password | $@ flows to a logging call. | test.go:173:13:173:20 | password | Sensitive data returned by an access to password | -| test.go:174:12:174:19 | password | test.go:174:12:174:19 | password | test.go:174:12:174:19 | password | $@ flows to a logging call. | test.go:174:12:174:19 | password | Sensitive data returned by an access to password | -| test.go:175:15:175:22 | password | test.go:175:15:175:22 | password | test.go:175:15:175:22 | password | $@ flows to a logging call. | test.go:175:15:175:22 | password | Sensitive data returned by an access to password | -| test.go:176:15:176:22 | password | test.go:176:15:176:22 | password | test.go:176:15:176:22 | password | $@ flows to a logging call. | test.go:176:15:176:22 | password | Sensitive data returned by an access to password | -| test.go:177:18:177:25 | password | test.go:177:18:177:25 | password | test.go:177:18:177:25 | password | $@ flows to a logging call. | test.go:177:18:177:25 | password | Sensitive data returned by an access to password | -| test.go:178:15:178:22 | password | test.go:178:15:178:22 | password | test.go:178:15:178:22 | password | $@ flows to a logging call. | test.go:178:15:178:22 | password | Sensitive data returned by an access to password | -| test.go:179:19:179:26 | password | test.go:179:19:179:26 | password | test.go:179:19:179:26 | password | $@ flows to a logging call. | test.go:179:19:179:26 | password | Sensitive data returned by an access to password | -| test.go:180:15:180:22 | password | test.go:180:15:180:22 | password | test.go:180:15:180:22 | password | $@ flows to a logging call. | test.go:180:15:180:22 | password | Sensitive data returned by an access to password | -| test.go:181:14:181:21 | password | test.go:181:14:181:21 | password | test.go:181:14:181:21 | password | $@ flows to a logging call. | test.go:181:14:181:21 | password | Sensitive data returned by an access to password | -| test.go:182:23:182:30 | password | test.go:182:23:182:30 | password | test.go:182:23:182:30 | password | $@ flows to a logging call. | test.go:182:23:182:30 | password | Sensitive data returned by an access to password | -| test.go:183:16:183:23 | password | test.go:183:16:183:23 | password | test.go:183:16:183:23 | password | $@ flows to a logging call. | test.go:183:16:183:23 | password | Sensitive data returned by an access to password | -| test.go:184:15:184:22 | password | test.go:184:15:184:22 | password | test.go:184:15:184:22 | password | $@ flows to a logging call. | test.go:184:15:184:22 | password | Sensitive data returned by an access to password | -| test.go:185:14:185:21 | password | test.go:185:14:185:21 | password | test.go:185:14:185:21 | password | $@ flows to a logging call. | test.go:185:14:185:21 | password | Sensitive data returned by an access to password | -| test.go:186:17:186:24 | password | test.go:186:17:186:24 | password | test.go:186:17:186:24 | password | $@ flows to a logging call. | test.go:186:17:186:24 | password | Sensitive data returned by an access to password | -| test.go:187:16:187:23 | password | test.go:187:16:187:23 | password | test.go:187:16:187:23 | password | $@ flows to a logging call. | test.go:187:16:187:23 | password | Sensitive data returned by an access to password | +| test.go:154:14:154:21 | password | test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:155:17:155:24 | password | test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:156:14:156:21 | password | test.go:153:17:153:24 | definition of password | test.go:156:14:156:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:157:18:157:25 | password | test.go:153:17:153:24 | definition of password | test.go:157:18:157:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:158:14:158:21 | password | test.go:153:17:153:24 | definition of password | test.go:158:14:158:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:159:13:159:20 | password | test.go:153:17:153:24 | definition of password | test.go:159:13:159:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:160:22:160:29 | password | test.go:153:17:153:24 | definition of password | test.go:160:22:160:29 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:161:15:161:22 | password | test.go:153:17:153:24 | definition of password | test.go:161:15:161:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:162:14:162:21 | password | test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:163:13:163:20 | password | test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:164:16:164:23 | password | test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:165:13:165:20 | password | test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:166:16:166:23 | password | test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:167:13:167:20 | password | test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:168:17:168:24 | password | test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:169:13:169:20 | password | test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:170:12:170:19 | password | test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:171:21:171:28 | password | test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:172:14:172:21 | password | test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:173:13:173:20 | password | test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:174:12:174:19 | password | test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:175:15:175:22 | password | test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:176:15:176:22 | password | test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:177:18:177:25 | password | test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:178:15:178:22 | password | test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:179:19:179:26 | password | test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:180:15:180:22 | password | test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:181:14:181:21 | password | test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:182:23:182:30 | password | test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:183:16:183:23 | password | test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:184:15:184:22 | password | test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:185:14:185:21 | password | test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:186:17:186:24 | password | test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | +| test.go:187:16:187:23 | password | test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password | diff --git a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected index f5d86e68dbc..c95fa5e7af6 100644 --- a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected +++ b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected @@ -6,8 +6,8 @@ edges | TaintedPath.go:15:18:15:22 | selection of URL | TaintedPath.go:15:18:15:30 | call to Query | provenance | Src:MaD:2 MaD:3 | | TaintedPath.go:15:18:15:30 | call to Query | TaintedPath.go:18:29:18:40 | tainted_path | provenance | Sink:MaD:1 | | TaintedPath.go:15:18:15:30 | call to Query | TaintedPath.go:22:57:22:68 | tainted_path | provenance | | -| TaintedPath.go:15:18:15:30 | call to Query | TaintedPath.go:74:39:74:56 | ...+... | provenance | | | TaintedPath.go:22:57:22:68 | tainted_path | TaintedPath.go:22:28:22:69 | call to Join | provenance | FunctionModel Sink:MaD:1 | +| TaintedPath.go:22:57:22:68 | tainted_path | TaintedPath.go:74:39:74:56 | ...+... | provenance | | | TaintedPath.go:74:39:74:56 | ...+... | TaintedPath.go:74:28:74:57 | call to Clean | provenance | MaD:4 Sink:MaD:1 | models | 1 | Sink: io/ioutil; ; false; ReadFile; ; ; Argument[0]; path-injection; manual | 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 dff32df4e1f..78dde84a947 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -48,14 +48,14 @@ edges | GitSubcommands.go:11:13:11:27 | call to Query | GitSubcommands.go:17:36:17:42 | tainted | provenance | | | GitSubcommands.go:33:13:33:19 | selection of URL | GitSubcommands.go:33:13:33:27 | call to Query | provenance | Src:MaD:2 MaD:7 | | GitSubcommands.go:33:13:33:27 | call to Query | GitSubcommands.go:38:32:38:38 | tainted | provenance | | +| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:13:25:13:31 | tainted | provenance | | +| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | | +| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:39:31:39:37 | tainted | provenance | Config | +| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:52:24:52:30 | tainted | provenance | Config | +| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:68:31:68:37 | tainted | provenance | Config | +| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:80:23:80:29 | tainted | provenance | Config | | 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 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 | | -| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:53:21:53:28 | arrayLit | provenance | | -| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:68:31:68:37 | tainted | provenance | | -| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:80:23:80:29 | tainted | provenance | | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | provenance | | | SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | provenance | | | SanitizingDoubleDash.go:13:25:13:31 | tainted | SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | provenance | | | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | SanitizingDoubleDash.go:14:23:14:33 | slice element node | provenance | | @@ -67,6 +67,7 @@ edges | SanitizingDoubleDash.go:39:31:39:37 | tainted | SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | provenance | | | SanitizingDoubleDash.go:52:15:52:31 | slice literal [array] | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | provenance | | | SanitizingDoubleDash.go:52:24:52:30 | tainted | SanitizingDoubleDash.go:52:15:52:31 | slice literal [array] | provenance | | +| SanitizingDoubleDash.go:52:24:52:30 | tainted | SanitizingDoubleDash.go:53:21:53:28 | arrayLit | provenance | | | 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 | @@ -180,6 +181,7 @@ nodes | GitSubcommands.go:33:13:33:19 | selection of URL | semmle.label | selection of URL | | GitSubcommands.go:33:13:33:27 | call to Query | semmle.label | call to Query | | GitSubcommands.go:38:32:38:38 | tainted | semmle.label | tainted | +| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | semmle.label | definition of tainted | | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | semmle.label | selection of URL | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | semmle.label | call to Query | | SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | semmle.label | array literal [array] | diff --git a/go/ql/test/query-tests/Security/CWE-078/SanitizingDoubleDash.go b/go/ql/test/query-tests/Security/CWE-078/SanitizingDoubleDash.go index d69a970f0d0..0428df55086 100644 --- a/go/ql/test/query-tests/Security/CWE-078/SanitizingDoubleDash.go +++ b/go/ql/test/query-tests/Security/CWE-078/SanitizingDoubleDash.go @@ -93,62 +93,62 @@ func testDoubleDashIrrelevant(req *http.Request) { { arrayLit := [1]string{tainted} - exec.Command("sudo", arrayLit[:]...) + exec.Command("sudo", arrayLit[:]...) // BAD } { arrayLit := [2]string{"--", tainted} - exec.Command("sudo", arrayLit[:]...) + exec.Command("sudo", arrayLit[:]...) // BAD } { arrayLit := []string{"--", tainted} - exec.Command("sudo", arrayLit...) + exec.Command("sudo", arrayLit...) // BAD } { arrayLit := []string{} arrayLit = append(arrayLit, "--", tainted) - exec.Command("sudo", arrayLit...) + exec.Command("sudo", arrayLit...) // BAD } { arrayLit := []string{} arrayLit = append(arrayLit, tainted, "--") - exec.Command("sudo", arrayLit...) + exec.Command("sudo", arrayLit...) // BAD } { arrayLit := []string{"--"} arrayLit = append(arrayLit, tainted) - exec.Command("sudo", arrayLit...) + exec.Command("sudo", arrayLit...) // BAD } { arrayLit := []string{tainted} arrayLit = append(arrayLit, "--") - exec.Command("sudo", arrayLit...) + exec.Command("sudo", arrayLit...) // BAD } { arrayLit := []string{"--"} arrayLit = append(arrayLit, "something else") arrayLit = append(arrayLit, tainted) - exec.Command("sudo", arrayLit...) + exec.Command("sudo", arrayLit...) // BAD } { arrayLit := []string{"something else"} arrayLit = append(arrayLit, tainted) arrayLit = append(arrayLit, "--") - exec.Command("sudo", arrayLit...) + exec.Command("sudo", arrayLit...) // BAD } { - exec.Command("sudo", "--", tainted) + exec.Command("sudo", "--", tainted) // BAD } { - exec.Command("sudo", tainted, "--") + exec.Command("sudo", tainted, "--") // BAD } } diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 1ce8c3d1dcf..542f1b5b89c 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -117,22 +117,22 @@ edges | main.go:61:5:61:15 | RequestData [pointer, Category] | main.go:61:4:61:15 | star expression [Category] | provenance | | | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:42:28:42:41 | untrustedInput | provenance | Src:MaD:20 | | mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:50:34:50:39 | filter | provenance | | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:61:27:61:32 | filter | provenance | Sink:MaD:4 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:63:23:63:28 | filter | provenance | Sink:MaD:5 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:64:22:64:27 | filter | provenance | Sink:MaD:6 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:66:32:66:37 | filter | provenance | Sink:MaD:7 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:69:17:69:22 | filter | provenance | Sink:MaD:8 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:70:20:70:25 | filter | provenance | Sink:MaD:9 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:71:29:71:34 | filter | provenance | Sink:MaD:10 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:72:30:72:35 | filter | provenance | Sink:MaD:11 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:73:29:73:34 | filter | provenance | Sink:MaD:12 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:78:23:78:28 | filter | provenance | Sink:MaD:13 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:79:23:79:28 | filter | provenance | Sink:MaD:14 | -| mongoDB.go:42:19:42:42 | struct literal | mongoDB.go:80:22:80:27 | filter | provenance | Sink:MaD:15 | | mongoDB.go:42:28:42:41 | untrustedInput | mongoDB.go:42:19:42:42 | struct literal | provenance | Config | | mongoDB.go:50:23:50:40 | struct literal | mongoDB.go:57:22:57:29 | pipeline | provenance | Sink:MaD:3 | | mongoDB.go:50:23:50:40 | struct literal | mongoDB.go:81:18:81:25 | pipeline | provenance | Sink:MaD:16 | | mongoDB.go:50:34:50:39 | filter | mongoDB.go:50:23:50:40 | struct literal | provenance | Config | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:61:27:61:32 | filter | provenance | Sink:MaD:4 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:63:23:63:28 | filter | provenance | Sink:MaD:5 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:64:22:64:27 | filter | provenance | Sink:MaD:6 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:66:32:66:37 | filter | provenance | Sink:MaD:7 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:69:17:69:22 | filter | provenance | Sink:MaD:8 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:70:20:70:25 | filter | provenance | Sink:MaD:9 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:71:29:71:34 | filter | provenance | Sink:MaD:10 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:72:30:72:35 | filter | provenance | Sink:MaD:11 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:73:29:73:34 | filter | provenance | Sink:MaD:12 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:78:23:78:28 | filter | provenance | Sink:MaD:13 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:79:23:79:28 | filter | provenance | Sink:MaD:14 | +| mongoDB.go:50:34:50:39 | filter | mongoDB.go:80:22:80:27 | filter | provenance | Sink:MaD:15 | models | 1 | Sink: database/sql; DB; true; Query; ; ; Argument[0]; sql-injection; manual | | 2 | Sink: database/sql; Tx; true; Query; ; ; Argument[0]; sql-injection; manual | From d13d7173ed3a0a8b185a09446a0cce8818723e00 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Mon, 5 May 2025 17:34:30 -0400 Subject: [PATCH 20/70] Fix QLDoc typo --- go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 20a147a6454..61c67083cc0 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -866,7 +866,7 @@ module Public { int getPosition() { result = i } /** - * Gets a data-flow node for a syntactic argument corresponding this this + * Gets a data-flow node for a syntactic argument corresponding to this * argument. If this argument is not an implicit varargs slice then this * will just be the argument itself. If this argument is an implicit * varargs slice then this will be a data-flow node that for an argument From 7a515c101af5572d921497536abc8104fa528793 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Mon, 5 May 2025 17:51:25 -0400 Subject: [PATCH 21/70] Pull out post-update node logic into predicate --- .../go/dataflow/internal/DataFlowNodes.qll | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 61c67083cc0..79026544d4d 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -807,22 +807,24 @@ module Public { abstract Node getPreUpdateNode(); } + predicate hasPostUpdateNode(Node preupd) { + preupd instanceof AddressOperationNode + or + preupd = any(AddressOperationNode addr).getOperand() + or + preupd = any(PointerDereferenceNode deref).getOperand() + or + preupd = getAWrittenNode() + or + preupd = any(ArgumentNode arg).getACorrespondingSyntacticArgument() and + mutableType(preupd.getType()) + } + private class DefaultPostUpdateNode extends PostUpdateNode { Node preupd; DefaultPostUpdateNode() { - ( - preupd instanceof AddressOperationNode - or - preupd = any(AddressOperationNode addr).getOperand() - or - preupd = any(PointerDereferenceNode deref).getOperand() - or - preupd = getAWrittenNode() - or - preupd = any(ArgumentNode arg).getACorrespondingSyntacticArgument() and - mutableType(preupd.getType()) - ) and + hasPostUpdateNode(preupd) and ( preupd = this.(SsaNode).getAUse() or From c8b8e25fbb6bde1eb8f59ba98338e2c2616c49b0 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Mon, 5 May 2025 18:50:04 -0400 Subject: [PATCH 22/70] Convert post-update logic to IR (part 1) --- .../go/dataflow/internal/DataFlowNodes.qll | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 79026544d4d..cf93dd042f3 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -807,12 +807,18 @@ module Public { abstract Node getPreUpdateNode(); } + predicate insnHasPostUpdateNode(IR::Instruction insn) { + exists(Expr e | insn.(IR::EvalInstruction).getExpr() = e | + e instanceof AddressExpr or + e = any(AddressExpr ae).getOperand() or + e = any(StarExpr ae).getBase() or + e = any(DerefExpr ae).getOperand() or + e = any(IR::EvalImplicitDerefInstruction eidi).getOperand() + ) + } + predicate hasPostUpdateNode(Node preupd) { - preupd instanceof AddressOperationNode - or - preupd = any(AddressOperationNode addr).getOperand() - or - preupd = any(PointerDereferenceNode deref).getOperand() + insnHasPostUpdateNode(preupd.asInstruction()) or preupd = getAWrittenNode() or From 203952fa4750705caedf9e65d2d97e754cd0a000 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 10 Sep 2025 22:06:08 +0100 Subject: [PATCH 23/70] Convert post-update logic to IR (part 2) Note that we don't create post-update nodes for method receivers if the call to the method is indirect, via a function variable. We could aim to do this in future. --- .../go/dataflow/internal/DataFlowNodes.qll | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index cf93dd042f3..75f3188c79d 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -815,15 +815,28 @@ module Public { e = any(DerefExpr ae).getOperand() or e = any(IR::EvalImplicitDerefInstruction eidi).getOperand() ) + or + exists(CallExpr ce | + ce.getArgument(0).getType() instanceof TupleType and + insn = IR::extractTupleElement(IR::evalExprInstruction(ce.getArgument(0)), _) + or + not ce.getArgument(0).getType() instanceof TupleType and + insn = IR::evalExprInstruction(ce.getAnArgument()) + or + // Receiver of a method call + exists(IR::MethodReadInstruction mri | + ce.getTarget() instanceof Method and + mri = IR::evalExprInstruction(ce.getCalleeExpr()) and + insn = mri.getReceiver() + ) + ) and + mutableType(insn.getResultType()) } predicate hasPostUpdateNode(Node preupd) { insnHasPostUpdateNode(preupd.asInstruction()) or preupd = getAWrittenNode() - or - preupd = any(ArgumentNode arg).getACorrespondingSyntacticArgument() and - mutableType(preupd.getType()) } private class DefaultPostUpdateNode extends PostUpdateNode { From ad1801827b4169752d8ee8cb5d14c5f92db48aac Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 12 Sep 2025 09:51:27 +0100 Subject: [PATCH 24/70] Implement `writesComponent` at IR level --- .../go/controlflow/ControlFlowGraph.qll | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index f5905b89bea..37be62f3710 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -140,13 +140,17 @@ module ControlFlow { * node corresponding to `newWidth`. */ predicate writesField(DataFlow::Node base, Field f, DataFlow::Node rhs) { + this.writesFieldInsn(base.asInstruction(), f, rhs.asInstruction()) + } + + private predicate writesFieldInsn(IR::Instruction base, Field f, IR::Instruction rhs) { exists(IR::FieldTarget trg | trg = super.getLhs() | ( - trg.getBase() = base.asInstruction() or - trg.getBase() = MkImplicitDeref(base.asExpr()) + trg.getBase() = base or + trg.getBase() = MkImplicitDeref(base.(IR::EvalInstruction).getExpr()) ) and trg.getField() = f and - super.getRhs() = rhs.asInstruction() + super.getRhs() = rhs ) } @@ -160,13 +164,19 @@ module ControlFlow { * is the data-flow node corresponding to `base`. */ predicate writesElement(DataFlow::Node base, DataFlow::Node index, DataFlow::Node rhs) { + this.writesElementInsn(base.asInstruction(), index.asInstruction(), rhs.asInstruction()) + } + + private predicate writesElementInsn( + IR::Instruction base, IR::Instruction index, IR::Instruction rhs + ) { exists(IR::ElementTarget trg | trg = super.getLhs() | ( - trg.getBase() = base.asInstruction() or - trg.getBase() = MkImplicitDeref(base.asExpr()) + trg.getBase() = base or + trg.getBase() = MkImplicitDeref(base.(IR::EvalInstruction).getExpr()) ) and - trg.getIndex() = index.asInstruction() and - super.getRhs() = rhs.asInstruction() + trg.getIndex() = index and + super.getRhs() = rhs ) } @@ -174,7 +184,14 @@ module ControlFlow { * Holds if this node sets any field or element of `base` to `rhs`. */ predicate writesComponent(DataFlow::Node base, DataFlow::Node rhs) { - this.writesElement(base, _, rhs) or this.writesField(base, _, rhs) + this.writesComponentInstruction(base.asInstruction(), rhs.asInstruction()) + } + + /** + * Holds if this node sets any field or element of `base` to `rhs`. + */ + predicate writesComponentInstruction(IR::Instruction base, IR::Instruction rhs) { + this.writesElementInsn(base, _, rhs) or this.writesFieldInsn(base, _, rhs) } } From 05a16dc100fab6ad441d3c6a70100117ccd4b8df Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 11 Sep 2025 22:01:23 +0100 Subject: [PATCH 25/70] Convert post-update logic to IR (part 3) --- .../go/dataflow/internal/DataFlowNodes.qll | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 75f3188c79d..9fa5f5b4397 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -760,18 +760,27 @@ module Public { predicate isReceiverOf(MethodDecl m) { parm.isReceiverOf(m) } } - private Node getADirectlyWrittenNode() { - exists(Write w | w.writesComponent(result, _)) or - result = DataFlow::exprNode(any(SendStmt s).getChannel()) - } - - private DataFlow::Node getAccessPathPredecessor(DataFlow::Node node) { - result = node.(PointerDereferenceNode).getOperand() + private IR::Instruction getADirectlyWrittenInsn() { + exists(Write w | w.writesComponentInstruction(result, _)) or - result = node.(ComponentReadNode).getBase() + result = IR::evalExprInstruction(any(SendStmt s).getChannel()) } - private Node getAWrittenNode() { result = getAccessPathPredecessor*(getADirectlyWrittenNode()) } + private IR::Instruction getAccessPathPredecessorInsn(IR::Instruction insn) { + exists(Expr e1, Expr e2 | + insn = IR::evalExprInstruction(e1) and result = IR::evalExprInstruction(e2) + | + e2 = e1.(DerefExpr).getOperand() or e2 = e1.(StarExpr).getBase() + ) + or + exists(Expr e | insn = IR::implicitDerefInstruction(e) and result = IR::evalExprInstruction(e)) + or + result = insn.(IR::ComponentReadInstruction).getBase() + } + + private IR::Instruction getAWrittenInsn() { + result = getAccessPathPredecessorInsn*(getADirectlyWrittenInsn()) + } /** * Holds if `tp` is a type that may (directly or indirectly) reference a memory location. @@ -831,13 +840,11 @@ module Public { ) ) and mutableType(insn.getResultType()) + or + insn = getAWrittenInsn() } - predicate hasPostUpdateNode(Node preupd) { - insnHasPostUpdateNode(preupd.asInstruction()) - or - preupd = getAWrittenNode() - } + predicate hasPostUpdateNode(Node preupd) { insnHasPostUpdateNode(preupd.asInstruction()) } private class DefaultPostUpdateNode extends PostUpdateNode { Node preupd; From 89ae0e3bf3483a357d4c7e3f4c79f12ee5ea8e7f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 11 Sep 2025 22:02:06 +0100 Subject: [PATCH 26/70] Inline predicate only used once --- go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 9fa5f5b4397..4183a409b0a 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -844,13 +844,11 @@ module Public { insn = getAWrittenInsn() } - predicate hasPostUpdateNode(Node preupd) { insnHasPostUpdateNode(preupd.asInstruction()) } - private class DefaultPostUpdateNode extends PostUpdateNode { Node preupd; DefaultPostUpdateNode() { - hasPostUpdateNode(preupd) and + insnHasPostUpdateNode(preupd.asInstruction()) and ( preupd = this.(SsaNode).getAUse() or From 9892836f14532f585d60f0650e70da5b0aa24f79 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 12 Sep 2025 11:35:18 +0100 Subject: [PATCH 27/70] Switch order of PUN test output --- .../go/dataflow/PostUpdateNodes/test.expected | 22 +++++++++---------- .../go/dataflow/PostUpdateNodes/test.ql | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected index 9f29e364be9..6959eac7e2f 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected @@ -1,26 +1,26 @@ -| file://:0:0:0:0 | [summary] to write: Argument[0] in copy | file://:0:0:0:0 | [summary param] 0 in copy | -| test.go:22:2:22:2 | definition of a | test.go:23:2:23:2 | a | -| test.go:22:2:22:2 | definition of a | test.go:24:2:24:2 | a | -| test.go:22:2:22:2 | definition of a | test.go:25:2:25:2 | a | -| test.go:22:2:22:2 | definition of a | test.go:26:2:26:2 | a | -| test.go:22:2:22:2 | definition of a | test.go:29:6:29:6 | a | -| test.go:22:2:22:2 | definition of a | test.go:30:7:30:7 | a | -| test.go:22:2:22:2 | definition of a | test.go:35:4:35:4 | a | -| test.go:22:2:22:2 | definition of a | test.go:36:5:36:5 | a | +| file://:0:0:0:0 | [summary param] 0 in copy | file://:0:0:0:0 | [summary] to write: Argument[0] in copy | +| test.go:23:2:23:2 | a | test.go:22:2:22:2 | definition of a | | test.go:23:11:23:14 | &... | test.go:23:11:23:14 | &... | | test.go:23:12:23:14 | selection of b | test.go:23:12:23:14 | selection of b | +| test.go:24:2:24:2 | a | test.go:22:2:22:2 | definition of a | | test.go:24:2:24:5 | selection of bs | test.go:24:2:24:5 | selection of bs | | test.go:24:2:24:8 | index expression | test.go:24:2:24:8 | index expression | | test.go:24:17:24:20 | &... | test.go:24:17:24:20 | &... | | test.go:24:18:24:20 | struct literal | test.go:24:18:24:20 | struct literal | +| test.go:25:2:25:2 | a | test.go:22:2:22:2 | definition of a | | test.go:25:2:25:5 | selection of bs | test.go:25:2:25:5 | selection of bs | | test.go:25:2:25:8 | index expression | test.go:25:2:25:8 | index expression | | test.go:25:2:25:13 | implicit dereference | test.go:25:2:25:13 | implicit dereference | | test.go:25:2:25:13 | selection of cptr | test.go:25:2:25:13 | selection of cptr | +| test.go:26:2:26:2 | a | test.go:22:2:22:2 | definition of a | | test.go:26:2:26:7 | implicit dereference | test.go:26:2:26:7 | implicit dereference | | test.go:26:2:26:7 | selection of bptr | test.go:26:2:26:7 | selection of bptr | | test.go:26:2:26:12 | implicit dereference | test.go:26:2:26:12 | implicit dereference | | test.go:26:2:26:12 | selection of cptr | test.go:26:2:26:12 | selection of cptr | -| test.go:28:2:28:2 | definition of c | test.go:29:2:29:2 | c | -| test.go:28:2:28:2 | definition of c | test.go:30:2:30:2 | c | | test.go:28:7:28:10 | struct literal | test.go:28:7:28:10 | struct literal | +| test.go:29:2:29:2 | c | test.go:28:2:28:2 | definition of c | +| test.go:29:6:29:6 | a | test.go:22:2:22:2 | definition of a | +| test.go:30:2:30:2 | c | test.go:28:2:28:2 | definition of c | +| test.go:30:7:30:7 | a | test.go:22:2:22:2 | definition of a | +| test.go:35:4:35:4 | a | test.go:22:2:22:2 | definition of a | +| test.go:36:5:36:5 | a | test.go:22:2:22:2 | definition of a | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.ql b/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.ql index ca2a9c5980b..b200ed4b8a7 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.ql @@ -1,4 +1,4 @@ import go from DataFlow::PostUpdateNode pun -select pun, pun.getPreUpdateNode() +select pun.getPreUpdateNode(), pun From a0c647ce835d0f329e678e5408ee557f66913ae7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 18 Sep 2025 11:56:01 +0100 Subject: [PATCH 28/70] Add Email Injection tests for reverse flow models --- .../query-tests/Security/CWE-640/EmailBad.go | 4 +- .../Security/CWE-640/EmailInjection.expected | 136 +++++++++++------- .../Security/CWE-640/EmailInjection.qlref | 4 +- .../test/query-tests/Security/CWE-640/main.go | 65 +++++++-- 4 files changed, 137 insertions(+), 72 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-640/EmailBad.go b/go/ql/test/query-tests/Security/CWE-640/EmailBad.go index aab8467b340..7ceed9e7a36 100644 --- a/go/ql/test/query-tests/Security/CWE-640/EmailBad.go +++ b/go/ql/test/query-tests/Security/CWE-640/EmailBad.go @@ -6,8 +6,8 @@ import ( ) func mail(w http.ResponseWriter, r *http.Request) { - host := r.Header.Get("Host") + host := r.Header.Get("Host") // $ Source token := backend.getUserSecretResetToken(email) body := "Click to reset password: " + host + "/" + token - smtp.SendMail("test.test", nil, "from@from.com", nil, []byte(body)) + smtp.SendMail("test.test", nil, "from@from.com", nil, []byte(body)) // $ Alert } diff --git a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected index ac5985f110d..c56e35fa7a8 100644 --- a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected @@ -1,66 +1,94 @@ #select | EmailBad.go:12:56:12:67 | type conversion | EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:12:56:12:67 | type conversion | Email content may contain $@. | EmailBad.go:9:10:9:17 | selection of Header | untrusted input | -| main.go:31:57:31:78 | type conversion | main.go:29:21:29:31 | call to Referer | main.go:31:57:31:78 | type conversion | Email content may contain $@. | main.go:29:21:29:31 | call to Referer | untrusted input | -| main.go:40:3:40:7 | definition of write | main.go:37:21:37:31 | call to Referer | main.go:40:3:40:7 | definition of write | Email content may contain $@. | main.go:37:21:37:31 | call to Referer | untrusted input | -| main.go:52:46:52:59 | untrustedInput | main.go:46:21:46:31 | call to Referer | main.go:52:46:52:59 | untrustedInput | Email content may contain $@. | main.go:46:21:46:31 | call to Referer | untrusted input | -| main.go:53:52:53:65 | untrustedInput | main.go:46:21:46:31 | call to Referer | main.go:53:52:53:65 | untrustedInput | Email content may contain $@. | main.go:46:21:46:31 | call to Referer | untrusted input | -| main.go:63:16:63:22 | content | main.go:58:21:58:31 | call to Referer | main.go:63:16:63:22 | content | Email content may contain $@. | main.go:58:21:58:31 | call to Referer | untrusted input | -| main.go:76:50:76:56 | content | main.go:68:21:68:31 | call to Referer | main.go:76:50:76:56 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | -| main.go:76:59:76:65 | content | main.go:68:21:68:31 | call to Referer | main.go:76:59:76:65 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | -| main.go:77:16:77:22 | content | main.go:68:21:68:31 | call to Referer | main.go:77:16:77:22 | content | Email content may contain $@. | main.go:68:21:68:31 | call to Referer | untrusted input | -| main.go:89:37:89:50 | untrustedInput | main.go:82:21:82:31 | call to Referer | main.go:89:37:89:50 | untrustedInput | Email content may contain $@. | main.go:82:21:82:31 | call to Referer | untrusted input | -| main.go:93:16:93:23 | content2 | main.go:82:21:82:31 | call to Referer | main.go:93:16:93:23 | content2 | Email content may contain $@. | main.go:82:21:82:31 | call to Referer | untrusted input | +| main.go:33:57:33:78 | type conversion | main.go:31:21:31:31 | call to Referer | main.go:33:57:33:78 | type conversion | Email content may contain $@. | main.go:31:21:31:31 | call to Referer | untrusted input | +| main.go:42:3:42:7 | definition of write | main.go:39:21:39:31 | call to Referer | main.go:42:3:42:7 | definition of write | Email content may contain $@. | main.go:39:21:39:31 | call to Referer | untrusted input | +| main.go:54:46:54:59 | untrustedInput | main.go:48:21:48:31 | call to Referer | main.go:54:46:54:59 | untrustedInput | Email content may contain $@. | main.go:48:21:48:31 | call to Referer | untrusted input | +| main.go:55:52:55:65 | untrustedInput | main.go:48:21:48:31 | call to Referer | main.go:55:52:55:65 | untrustedInput | Email content may contain $@. | main.go:48:21:48:31 | call to Referer | untrusted input | +| main.go:65:16:65:22 | content | main.go:60:21:60:31 | call to Referer | main.go:65:16:65:22 | content | Email content may contain $@. | main.go:60:21:60:31 | call to Referer | untrusted input | +| main.go:78:50:78:56 | content | main.go:70:21:70:31 | call to Referer | main.go:78:50:78:56 | content | Email content may contain $@. | main.go:70:21:70:31 | call to Referer | untrusted input | +| main.go:78:59:78:65 | content | main.go:70:21:70:31 | call to Referer | main.go:78:59:78:65 | content | Email content may contain $@. | main.go:70:21:70:31 | call to Referer | untrusted input | +| main.go:79:16:79:22 | content | main.go:70:21:70:31 | call to Referer | main.go:79:16:79:22 | content | Email content may contain $@. | main.go:70:21:70:31 | call to Referer | untrusted input | +| main.go:91:37:91:50 | untrustedInput | main.go:84:21:84:31 | call to Referer | main.go:91:37:91:50 | untrustedInput | Email content may contain $@. | main.go:84:21:84:31 | call to Referer | untrusted input | +| main.go:95:16:95:23 | content2 | main.go:84:21:84:31 | call to Referer | main.go:95:16:95:23 | content2 | Email content may contain $@. | main.go:84:21:84:31 | call to Referer | untrusted input | +| main.go:124:57:124:65 | call to Bytes | main.go:113:21:113:31 | call to Referer | main.go:124:57:124:65 | call to Bytes | Email content may contain $@. | main.go:113:21:113:31 | call to Referer | untrusted input | +| main.go:141:57:141:65 | call to Bytes | main.go:129:21:129:31 | call to Referer | main.go:141:57:141:65 | call to Bytes | Email content may contain $@. | main.go:129:21:129:31 | call to Referer | untrusted input | edges -| EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:9:10:9:29 | call to Get | provenance | Src:MaD:1 MaD:5 | +| EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:9:10:9:29 | call to Get | provenance | Src:MaD:1 MaD:7 | | EmailBad.go:9:10:9:29 | call to Get | EmailBad.go:12:56:12:67 | type conversion | provenance | | -| main.go:29:21:29:31 | call to Referer | main.go:31:57:31:78 | type conversion | provenance | Src:MaD:2 | -| main.go:37:21:37:31 | call to Referer | main.go:41:25:41:38 | untrustedInput | provenance | Src:MaD:2 | -| main.go:41:25:41:38 | untrustedInput | main.go:40:3:40:7 | definition of write | provenance | MaD:4 | -| main.go:46:21:46:31 | call to Referer | main.go:52:46:52:59 | untrustedInput | provenance | Src:MaD:2 | -| main.go:46:21:46:31 | call to Referer | main.go:53:52:53:65 | untrustedInput | provenance | Src:MaD:2 | -| main.go:58:21:58:31 | call to Referer | main.go:60:47:60:60 | untrustedInput | provenance | Src:MaD:2 | -| main.go:60:14:60:61 | call to NewContent | main.go:63:16:63:22 | content | provenance | | -| main.go:60:47:60:60 | untrustedInput | main.go:60:14:60:61 | call to NewContent | provenance | MaD:3 | -| main.go:68:21:68:31 | call to Referer | main.go:74:47:74:60 | untrustedInput | provenance | Src:MaD:2 | -| main.go:74:14:74:61 | call to NewContent | main.go:76:50:76:56 | content | provenance | | -| main.go:74:14:74:61 | call to NewContent | main.go:76:59:76:65 | content | provenance | | -| main.go:74:14:74:61 | call to NewContent | main.go:77:16:77:22 | content | provenance | | -| main.go:74:47:74:60 | untrustedInput | main.go:74:14:74:61 | call to NewContent | provenance | MaD:3 | -| main.go:82:21:82:31 | call to Referer | main.go:89:37:89:50 | untrustedInput | provenance | Src:MaD:2 | -| main.go:82:21:82:31 | call to Referer | main.go:91:48:91:61 | untrustedInput | provenance | Src:MaD:2 | -| main.go:91:15:91:62 | call to NewContent | main.go:93:16:93:23 | content2 | provenance | | -| main.go:91:48:91:61 | untrustedInput | main.go:91:15:91:62 | call to NewContent | provenance | MaD:3 | +| main.go:31:21:31:31 | call to Referer | main.go:33:57:33:78 | type conversion | provenance | Src:MaD:2 | +| main.go:39:21:39:31 | call to Referer | main.go:43:25:43:38 | untrustedInput | provenance | Src:MaD:2 | +| main.go:43:25:43:38 | untrustedInput | main.go:42:3:42:7 | definition of write | provenance | MaD:5 | +| main.go:48:21:48:31 | call to Referer | main.go:54:46:54:59 | untrustedInput | provenance | Src:MaD:2 | +| main.go:48:21:48:31 | call to Referer | main.go:55:52:55:65 | untrustedInput | provenance | Src:MaD:2 | +| main.go:60:21:60:31 | call to Referer | main.go:62:47:62:60 | untrustedInput | provenance | Src:MaD:2 | +| main.go:62:14:62:61 | call to NewContent | main.go:65:16:65:22 | content | provenance | | +| main.go:62:47:62:60 | untrustedInput | main.go:62:14:62:61 | call to NewContent | provenance | MaD:4 | +| main.go:70:21:70:31 | call to Referer | main.go:76:47:76:60 | untrustedInput | provenance | Src:MaD:2 | +| main.go:76:14:76:61 | call to NewContent | main.go:78:50:78:56 | content | provenance | | +| main.go:76:14:76:61 | call to NewContent | main.go:78:59:78:65 | content | provenance | | +| main.go:76:14:76:61 | call to NewContent | main.go:79:16:79:22 | content | provenance | | +| main.go:76:47:76:60 | untrustedInput | main.go:76:14:76:61 | call to NewContent | provenance | MaD:4 | +| main.go:84:21:84:31 | call to Referer | main.go:91:37:91:50 | untrustedInput | provenance | Src:MaD:2 | +| main.go:84:21:84:31 | call to Referer | main.go:93:48:93:61 | untrustedInput | provenance | Src:MaD:2 | +| main.go:93:15:93:62 | call to NewContent | main.go:95:16:95:23 | content2 | provenance | | +| main.go:93:48:93:61 | untrustedInput | main.go:93:15:93:62 | call to NewContent | provenance | MaD:4 | +| main.go:113:21:113:31 | call to Referer | main.go:119:28:119:41 | untrustedInput | provenance | Src:MaD:2 | +| main.go:116:3:116:4 | definition of mw | main.go:116:29:116:30 | &... | provenance | FunctionModel | +| main.go:116:29:116:30 | &... | main.go:124:57:124:57 | b | provenance | | +| main.go:119:28:119:41 | untrustedInput | main.go:116:3:116:4 | definition of mw | provenance | MaD:6 | +| main.go:124:57:124:57 | b | main.go:124:57:124:65 | call to Bytes | provenance | MaD:3 | +| main.go:129:21:129:31 | call to Referer | main.go:136:30:136:43 | untrustedInput | provenance | Src:MaD:2 | +| main.go:132:3:132:4 | definition of mw | main.go:132:29:132:30 | &... | provenance | FunctionModel | +| main.go:132:29:132:30 | &... | main.go:141:57:141:57 | b | provenance | | +| main.go:135:3:135:12 | definition of formWriter | main.go:132:3:132:4 | definition of mw | provenance | FunctionModel | +| main.go:136:30:136:43 | untrustedInput | main.go:135:3:135:12 | definition of formWriter | provenance | MaD:5 | +| main.go:141:57:141:57 | b | main.go:141:57:141:65 | call to Bytes | provenance | MaD:3 | models | 1 | Source: net/http; Request; true; Header; ; ; ; remote; manual | | 2 | Source: net/http; Request; true; Referer; ; ; ReturnValue; remote; manual | -| 3 | Summary: github.com/sendgrid/sendgrid-go/helpers/mail; ; false; NewContent; ; ; Argument[1]; ReturnValue; taint; manual | -| 4 | Summary: io; ; false; WriteString; ; ; Argument[1]; Argument[0]; taint; manual | -| 5 | Summary: net/http; Header; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 3 | Summary: bytes; Buffer; true; Bytes; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 4 | Summary: github.com/sendgrid/sendgrid-go/helpers/mail; ; false; NewContent; ; ; Argument[1]; ReturnValue; taint; manual | +| 5 | Summary: io; ; false; WriteString; ; ; Argument[1]; Argument[0]; taint; manual | +| 6 | Summary: mime/multipart; Writer; true; WriteField; ; ; Argument[0..1]; Argument[receiver]; taint; manual | +| 7 | Summary: net/http; Header; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | nodes | EmailBad.go:9:10:9:17 | selection of Header | semmle.label | selection of Header | | EmailBad.go:9:10:9:29 | call to Get | semmle.label | call to Get | | EmailBad.go:12:56:12:67 | type conversion | semmle.label | type conversion | -| main.go:29:21:29:31 | call to Referer | semmle.label | call to Referer | -| main.go:31:57:31:78 | type conversion | semmle.label | type conversion | -| main.go:37:21:37:31 | call to Referer | semmle.label | call to Referer | -| main.go:40:3:40:7 | definition of write | semmle.label | definition of write | -| main.go:41:25:41:38 | untrustedInput | semmle.label | untrustedInput | -| main.go:46:21:46:31 | call to Referer | semmle.label | call to Referer | -| main.go:52:46:52:59 | untrustedInput | semmle.label | untrustedInput | -| main.go:53:52:53:65 | untrustedInput | semmle.label | untrustedInput | -| main.go:58:21:58:31 | call to Referer | semmle.label | call to Referer | -| main.go:60:14:60:61 | call to NewContent | semmle.label | call to NewContent | -| main.go:60:47:60:60 | untrustedInput | semmle.label | untrustedInput | -| main.go:63:16:63:22 | content | semmle.label | content | -| main.go:68:21:68:31 | call to Referer | semmle.label | call to Referer | -| main.go:74:14:74:61 | call to NewContent | semmle.label | call to NewContent | -| main.go:74:47:74:60 | untrustedInput | semmle.label | untrustedInput | -| main.go:76:50:76:56 | content | semmle.label | content | -| main.go:76:59:76:65 | content | semmle.label | content | -| main.go:77:16:77:22 | content | semmle.label | content | -| main.go:82:21:82:31 | call to Referer | semmle.label | call to Referer | -| main.go:89:37:89:50 | untrustedInput | semmle.label | untrustedInput | -| main.go:91:15:91:62 | call to NewContent | semmle.label | call to NewContent | -| main.go:91:48:91:61 | untrustedInput | semmle.label | untrustedInput | -| main.go:93:16:93:23 | content2 | semmle.label | content2 | +| main.go:31:21:31:31 | call to Referer | semmle.label | call to Referer | +| main.go:33:57:33:78 | type conversion | semmle.label | type conversion | +| main.go:39:21:39:31 | call to Referer | semmle.label | call to Referer | +| main.go:42:3:42:7 | definition of write | semmle.label | definition of write | +| main.go:43:25:43:38 | untrustedInput | semmle.label | untrustedInput | +| main.go:48:21:48:31 | call to Referer | semmle.label | call to Referer | +| main.go:54:46:54:59 | untrustedInput | semmle.label | untrustedInput | +| main.go:55:52:55:65 | untrustedInput | semmle.label | untrustedInput | +| main.go:60:21:60:31 | call to Referer | semmle.label | call to Referer | +| main.go:62:14:62:61 | call to NewContent | semmle.label | call to NewContent | +| main.go:62:47:62:60 | untrustedInput | semmle.label | untrustedInput | +| main.go:65:16:65:22 | content | semmle.label | content | +| main.go:70:21:70:31 | call to Referer | semmle.label | call to Referer | +| main.go:76:14:76:61 | call to NewContent | semmle.label | call to NewContent | +| main.go:76:47:76:60 | untrustedInput | semmle.label | untrustedInput | +| main.go:78:50:78:56 | content | semmle.label | content | +| main.go:78:59:78:65 | content | semmle.label | content | +| main.go:79:16:79:22 | content | semmle.label | content | +| main.go:84:21:84:31 | call to Referer | semmle.label | call to Referer | +| main.go:91:37:91:50 | untrustedInput | semmle.label | untrustedInput | +| main.go:93:15:93:62 | call to NewContent | semmle.label | call to NewContent | +| main.go:93:48:93:61 | untrustedInput | semmle.label | untrustedInput | +| main.go:95:16:95:23 | content2 | semmle.label | content2 | +| main.go:113:21:113:31 | call to Referer | semmle.label | call to Referer | +| main.go:116:3:116:4 | definition of mw | semmle.label | definition of mw | +| main.go:116:29:116:30 | &... | semmle.label | &... | +| main.go:119:28:119:41 | untrustedInput | semmle.label | untrustedInput | +| main.go:124:57:124:57 | b | semmle.label | b | +| main.go:124:57:124:65 | call to Bytes | semmle.label | call to Bytes | +| main.go:129:21:129:31 | call to Referer | semmle.label | call to Referer | +| main.go:132:3:132:4 | definition of mw | semmle.label | definition of mw | +| main.go:132:29:132:30 | &... | semmle.label | &... | +| main.go:135:3:135:12 | definition of formWriter | semmle.label | definition of formWriter | +| main.go:136:30:136:43 | untrustedInput | semmle.label | untrustedInput | +| main.go:141:57:141:57 | b | semmle.label | b | +| main.go:141:57:141:65 | call to Bytes | semmle.label | call to Bytes | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.qlref b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.qlref index c3b6cac3113..67240cd9df4 100644 --- a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.qlref +++ b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.qlref @@ -1,2 +1,4 @@ query: Security/CWE-640/EmailInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-640/main.go b/go/ql/test/query-tests/Security/CWE-640/main.go index c6685475a8d..f83b413ebc4 100644 --- a/go/ql/test/query-tests/Security/CWE-640/main.go +++ b/go/ql/test/query-tests/Security/CWE-640/main.go @@ -3,11 +3,13 @@ package main //go:generate depstubber -vendor github.com/sendgrid/sendgrid-go/helpers/mail "" NewEmail,NewSingleEmail,NewContent,NewV3Mail,NewV3MailInit import ( + "bytes" "crypto/hmac" "crypto/sha256" "encoding/base64" "io" "log" + "mime/multipart" "net/http" "net/smtp" @@ -26,46 +28,46 @@ func main() { // Not OK http.HandleFunc("/ex0", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source - smtp.SendMail("test.test", nil, "from@from.com", nil, []byte(untrustedInput)) + smtp.SendMail("test.test", nil, "from@from.com", nil, []byte(untrustedInput)) // $ Alert }) // Not OK http.HandleFunc("/ex1", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source s, _ := smtp.Dial("test.test") - write, _ := s.Data() + write, _ := s.Data() // $ Alert io.WriteString(write, untrustedInput) }) // Not OK http.HandleFunc("/ex2", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source from := sendgrid.NewEmail("from", "from@from.com") to := sendgrid.NewEmail("to", "to@to.com") subject := "test" body := "body" - sendgrid.NewSingleEmail(from, subject, to, untrustedInput, body) - sendgrid.NewSingleEmail(from, subject, to, body, untrustedInput) + sendgrid.NewSingleEmail(from, subject, to, untrustedInput, body) // $ Alert + sendgrid.NewSingleEmail(from, subject, to, body, untrustedInput) // $ Alert }) // Not OK http.HandleFunc("/ex3", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source content := sendgrid.NewContent("text/html", untrustedInput) v := sendgrid.NewV3Mail() - v.AddContent(content) + v.AddContent(content) // $ Alert }) // Not OK http.HandleFunc("/ex4", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source from := sendgrid.NewEmail("from", "from@from.com") to := sendgrid.NewEmail("to", "to@to.com") @@ -73,24 +75,24 @@ func main() { content := sendgrid.NewContent("text/html", untrustedInput) - v := sendgrid.NewV3MailInit(from, subject, to, content, content) - v.AddContent(content) + v := sendgrid.NewV3MailInit(from, subject, to, content, content) // $ Alert + v.AddContent(content) // $ Alert }) // Not OK http.HandleFunc("/ex5", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source from := sendgrid.NewEmail("from", "from@from.com") to := sendgrid.NewEmail("to", "to@to.com") content := sendgrid.NewContent("text/html", "test") - v := sendgrid.NewV3MailInit(from, untrustedInput, to, content, content) + v := sendgrid.NewV3MailInit(from, untrustedInput, to, content, content) // $ Alert content2 := sendgrid.NewContent("text/html", untrustedInput) - v.AddContent(content2) + v.AddContent(content2) // $ Alert }) // OK @@ -106,6 +108,39 @@ func main() { smtp.SendMail("test.test", nil, "from@from.com", nil, []byte(signature)) }) + // Not OK - mime/multipart.New.Writer test + http.HandleFunc("/multipart1", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() // $ Source + + var b bytes.Buffer + mw := multipart.NewWriter(&b) + + // Add user-controlled data directly to the multipart writer + mw.WriteField("message", untrustedInput) // Injection point + + mw.Close() + + // Send the potentially malicious email content + smtp.SendMail("test.test", nil, "from@from.com", nil, b.Bytes()) // $ Alert + }) + + // Not OK - alternative multipart test + http.HandleFunc("/multipart2", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() // $ Source + + var b bytes.Buffer + mw := multipart.NewWriter(&b) + + // Create form file with untrusted content + formWriter, _ := mw.CreateFormFile("attachment", "message.txt") + io.WriteString(formWriter, untrustedInput) // Injection point + + mw.Close() + + // Send email with user-controlled form file content + smtp.SendMail("test.test", nil, "from@from.com", nil, b.Bytes()) // $ Alert + }) + log.Println(http.ListenAndServe(":80", nil)) } From 118def8d28e78ec98a53438e95c838aa2d28d906 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 12 Sep 2025 11:49:50 +0100 Subject: [PATCH 29/70] Make separate post-update nodes --- .../go/dataflow/internal/DataFlowNodes.qll | 25 ++++++---- .../go/dataflow/internal/DataFlowPrivate.qll | 10 +++- .../dataflow/internal/TaintTrackingUtil.qll | 20 +++++--- .../go/dataflow/PostUpdateNodes/test.expected | 50 +++++++++---------- 4 files changed, 59 insertions(+), 46 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 4183a409b0a..5e9cc7f6b74 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -12,7 +12,8 @@ private newtype TNode = MkGlobalFunctionNode(Function f) or MkImplicitVarargsSlice(CallExpr c) { c.hasImplicitVarargs() } or MkSliceElementNode(SliceExpr se) or - MkFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) + MkFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or + MkDefaultPostUpdateNode(IR::Instruction insn) { insnHasPostUpdateNode(insn) } /** Nodes intended for only use inside the data-flow libraries. */ module Private { @@ -844,20 +845,22 @@ module Public { insn = getAWrittenInsn() } - private class DefaultPostUpdateNode extends PostUpdateNode { + private class DefaultPostUpdateNode extends PostUpdateNode, MkDefaultPostUpdateNode { Node preupd; - DefaultPostUpdateNode() { - insnHasPostUpdateNode(preupd.asInstruction()) and - ( - preupd = this.(SsaNode).getAUse() - or - preupd = this and - not basicLocalFlowStep(_, this) - ) - } + DefaultPostUpdateNode() { this = MkDefaultPostUpdateNode(preupd.asInstruction()) } override Node getPreUpdateNode() { result = preupd } + + override ControlFlow::Root getRoot() { result = preupd.getRoot() } + + override Type getType() { result = preupd.getType() } + + override string getNodeKind() { result = "post-update node" } + + override string toString() { result = preupd.toString() + " [postupdate]" } + + override Location getLocation() { result = preupd.getLocation() } } /** diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index f05859de813..7ca942fdf59 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -68,7 +68,10 @@ predicate basicLocalFlowStep(Node nodeFrom, Node nodeTo) { // Instruction -> SSA defn exists(IR::Instruction pred, SsaExplicitDefinition succ | succ.getRhs() = pred and - nodeFrom = instructionNode(pred) and + ( + nodeFrom = instructionNode(pred) or + nodeFrom.(PostUpdateNode).getPreUpdateNode() = instructionNode(pred) + ) and nodeTo = ssaNode(succ.getVariable()) ) or @@ -82,7 +85,10 @@ predicate basicLocalFlowStep(Node nodeFrom, Node nodeTo) { // SSA use -> successive SSA use // Note this case includes Phi node traversal exists(IR::Instruction pred, IR::Instruction succ | succ = getAnAdjacentUse(pred) | - nodeFrom = instructionNode(pred) and + ( + nodeFrom = instructionNode(pred) or + nodeFrom.(PostUpdateNode).getPreUpdateNode() = instructionNode(pred) + ) and nodeTo = instructionNode(succ) ) or diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index c69a7f32e63..05cb663f7be 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -88,14 +88,18 @@ class AdditionalTaintStep extends Unit { * global taint flow configurations. */ 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 - sliceStep(pred, succ) + exists(DataFlow::Node pred2 | + pred2 = pred + or + pred2 = pred.(DataFlow::PostUpdateNode).getPreUpdateNode() + | + referenceStep(pred2, succ) or + elementWriteStep(pred2, succ) or + fieldReadStep(pred2, succ) or + elementStep(pred2, succ) or + tupleStep(pred2, succ) or + stringConcatStep(pred2, succ) or + sliceStep(pred2, succ) ) and model = "" or diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected index 6959eac7e2f..d29d11627b0 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected @@ -1,26 +1,26 @@ | file://:0:0:0:0 | [summary param] 0 in copy | file://:0:0:0:0 | [summary] to write: Argument[0] in copy | -| test.go:23:2:23:2 | a | test.go:22:2:22:2 | definition of a | -| test.go:23:11:23:14 | &... | test.go:23:11:23:14 | &... | -| test.go:23:12:23:14 | selection of b | test.go:23:12:23:14 | selection of b | -| test.go:24:2:24:2 | a | test.go:22:2:22:2 | definition of a | -| test.go:24:2:24:5 | selection of bs | test.go:24:2:24:5 | selection of bs | -| test.go:24:2:24:8 | index expression | test.go:24:2:24:8 | index expression | -| test.go:24:17:24:20 | &... | test.go:24:17:24:20 | &... | -| test.go:24:18:24:20 | struct literal | test.go:24:18:24:20 | struct literal | -| test.go:25:2:25:2 | a | test.go:22:2:22:2 | definition of a | -| test.go:25:2:25:5 | selection of bs | test.go:25:2:25:5 | selection of bs | -| test.go:25:2:25:8 | index expression | test.go:25:2:25:8 | index expression | -| test.go:25:2:25:13 | implicit dereference | test.go:25:2:25:13 | implicit dereference | -| test.go:25:2:25:13 | selection of cptr | test.go:25:2:25:13 | selection of cptr | -| test.go:26:2:26:2 | a | test.go:22:2:22:2 | definition of a | -| test.go:26:2:26:7 | implicit dereference | test.go:26:2:26:7 | implicit dereference | -| test.go:26:2:26:7 | selection of bptr | test.go:26:2:26:7 | selection of bptr | -| test.go:26:2:26:12 | implicit dereference | test.go:26:2:26:12 | implicit dereference | -| test.go:26:2:26:12 | selection of cptr | test.go:26:2:26:12 | selection of cptr | -| test.go:28:7:28:10 | struct literal | test.go:28:7:28:10 | struct literal | -| test.go:29:2:29:2 | c | test.go:28:2:28:2 | definition of c | -| test.go:29:6:29:6 | a | test.go:22:2:22:2 | definition of a | -| test.go:30:2:30:2 | c | test.go:28:2:28:2 | definition of c | -| test.go:30:7:30:7 | a | test.go:22:2:22:2 | definition of a | -| test.go:35:4:35:4 | a | test.go:22:2:22:2 | definition of a | -| test.go:36:5:36:5 | a | test.go:22:2:22:2 | definition of a | +| test.go:23:2:23:2 | a | test.go:23:2:23:2 | a [postupdate] | +| test.go:23:11:23:14 | &... | test.go:23:11:23:14 | &... [postupdate] | +| test.go:23:12:23:14 | selection of b | test.go:23:12:23:14 | selection of b [postupdate] | +| test.go:24:2:24:2 | a | test.go:24:2:24:2 | a [postupdate] | +| test.go:24:2:24:5 | selection of bs | test.go:24:2:24:5 | selection of bs [postupdate] | +| test.go:24:2:24:8 | index expression | test.go:24:2:24:8 | index expression [postupdate] | +| test.go:24:17:24:20 | &... | test.go:24:17:24:20 | &... [postupdate] | +| test.go:24:18:24:20 | struct literal | test.go:24:18:24:20 | struct literal [postupdate] | +| test.go:25:2:25:2 | a | test.go:25:2:25:2 | a [postupdate] | +| test.go:25:2:25:5 | selection of bs | test.go:25:2:25:5 | selection of bs [postupdate] | +| test.go:25:2:25:8 | index expression | test.go:25:2:25:8 | index expression [postupdate] | +| test.go:25:2:25:13 | implicit dereference | test.go:25:2:25:13 | implicit dereference [postupdate] | +| test.go:25:2:25:13 | selection of cptr | test.go:25:2:25:13 | selection of cptr [postupdate] | +| test.go:26:2:26:2 | a | test.go:26:2:26:2 | a [postupdate] | +| test.go:26:2:26:7 | implicit dereference | test.go:26:2:26:7 | implicit dereference [postupdate] | +| test.go:26:2:26:7 | selection of bptr | test.go:26:2:26:7 | selection of bptr [postupdate] | +| test.go:26:2:26:12 | implicit dereference | test.go:26:2:26:12 | implicit dereference [postupdate] | +| test.go:26:2:26:12 | selection of cptr | test.go:26:2:26:12 | selection of cptr [postupdate] | +| test.go:28:7:28:10 | struct literal | test.go:28:7:28:10 | struct literal [postupdate] | +| test.go:29:2:29:2 | c | test.go:29:2:29:2 | c [postupdate] | +| test.go:29:6:29:6 | a | test.go:29:6:29:6 | a [postupdate] | +| test.go:30:2:30:2 | c | test.go:30:2:30:2 | c [postupdate] | +| test.go:30:7:30:7 | a | test.go:30:7:30:7 | a [postupdate] | +| test.go:35:4:35:4 | a | test.go:35:4:35:4 | a [postupdate] | +| test.go:36:5:36:5 | a | test.go:36:5:36:5 | a [postupdate] | From d2230c531d3777c40210b37825fc62ad4dea2f79 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 12 Sep 2025 15:42:02 +0100 Subject: [PATCH 30/70] Expected changes in test output --- .../CWE-1004/CookieWithoutHttpOnly.expected | 324 ++---------------- .../CWE-321-V2/HardCodedKeys.expected | 4 - .../CWE-74/DsnInjectionLocal.expected | 16 +- go/ql/test/experimental/CWE-918/SSRF.expected | 24 +- .../DefaultSanitizer.expected | 30 +- .../dataflow/ExternalTaintFlow/srcs.expected | 2 +- .../dataflow/ExternalTaintFlow/steps.expected | 14 +- .../dataflow/ExternalValueFlow/srcs.expected | 2 +- .../dataflow/ExternalValueFlow/steps.expected | 12 +- .../FlowSteps/LocalTaintStep.expected | 8 +- .../FunctionModelStep.expected | 6 +- .../FunctionOutput_getExitNode.expected | 20 +- .../database/test_gogf_gf_database_gdb.go | 12 +- .../go/frameworks/Beego/ReflectedXss.expected | 40 +-- .../go/frameworks/Beego/TaintedPath.expected | 6 +- .../go/frameworks/BeegoOrm/StoredXss.expected | 106 +++--- .../go/frameworks/Echo/OpenRedirect.expected | 4 +- .../go/frameworks/Echo/ReflectedXss.expected | 32 +- .../go/frameworks/Encoding/jsoniter.expected | 24 +- .../semmle/go/frameworks/Gin/Gin.expected | 72 ++-- .../frameworks/Gorestful/gorestful.expected | 12 +- .../go/frameworks/Revel/OpenRedirect.expected | 4 +- .../go/frameworks/Revel/ReflectedXss.expected | 6 +- .../frameworks/TaintSteps/TaintStep.expected | 86 +++-- .../go/frameworks/WebSocket/Read.expected | 8 +- .../WebSocket/RemoteFlowSources.expected | 8 +- .../frameworks/XNetHtml/ReflectedXss.expected | 26 +- .../semmle/go/frameworks/Yaml/yaml.go | 24 +- .../CWE-078/CommandInjection.expected | 36 +- .../Security/CWE-078/StoredCommand.expected | 6 +- .../Security/CWE-079/ReflectedXss.expected | 39 ++- .../Security/CWE-079/StoredXss.expected | 6 +- .../InsecureRandomness.expected | 6 +- .../OpenUrlRedirect/OpenUrlRedirect.expected | 46 +-- .../Security/CWE-918/RequestForgery.expected | 8 - 35 files changed, 399 insertions(+), 680 deletions(-) diff --git a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected index 0c60eb3f97e..7e8c6406211 100644 --- a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected +++ b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected @@ -1,90 +1,54 @@ edges | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | CookieWithoutHttpOnly.go:15:21:15:21 | c | provenance | | | CookieWithoutHttpOnly.go:12:10:12:18 | "session" | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:15:21:15:21 | c | provenance | | | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:21:15:21 | c | provenance | | | CookieWithoutHttpOnly.go:15:21:15:21 | c | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | | CookieWithoutHttpOnly.go:15:21:15:21 | c | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | | CookieWithoutHttpOnly.go:20:13:20:21 | "session" | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:22:13:22:17 | false | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | | CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | | CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | | CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | | CookieWithoutHttpOnly.go:29:13:29:21 | "session" | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:31:13:31:16 | true | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | | CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | | CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | | CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | | CookieWithoutHttpOnly.go:38:10:38:18 | "session" | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:41:15:41:18 | true | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | | CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | | CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | | CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | | CookieWithoutHttpOnly.go:47:10:47:18 | "session" | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:50:15:50:19 | false | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | | CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | | CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | | CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | provenance | | @@ -93,20 +57,12 @@ edges | CookieWithoutHttpOnly.go:55:9:55:13 | false | CookieWithoutHttpOnly.go:59:13:59:15 | val | provenance | | | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | | CookieWithoutHttpOnly.go:57:13:57:21 | "session" | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:59:13:59:15 | val | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | | CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | | CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | | CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | provenance | | @@ -115,20 +71,12 @@ edges | CookieWithoutHttpOnly.go:65:9:65:12 | true | CookieWithoutHttpOnly.go:69:13:69:15 | val | provenance | | | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | | CookieWithoutHttpOnly.go:67:13:67:21 | "session" | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:69:13:69:15 | val | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | | CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | | CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | | CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | provenance | | @@ -137,20 +85,12 @@ edges | CookieWithoutHttpOnly.go:75:9:75:12 | true | CookieWithoutHttpOnly.go:80:15:80:17 | val | provenance | | | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | | CookieWithoutHttpOnly.go:77:10:77:18 | "session" | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:80:15:80:17 | val | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | | CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | | CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | | CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | provenance | | @@ -159,51 +99,31 @@ edges | CookieWithoutHttpOnly.go:85:9:85:13 | false | CookieWithoutHttpOnly.go:90:15:90:17 | val | provenance | | | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | | CookieWithoutHttpOnly.go:87:10:87:18 | "session" | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:90:15:90:17 | val | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | | CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | | CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | | CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | | CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:21:100:21 | c | provenance | | | CookieWithoutHttpOnly.go:99:15:99:19 | false | CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... | CookieWithoutHttpOnly.go:100:21:100:21 | c | provenance | | | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:21:100:21 | c | provenance | | | CookieWithoutHttpOnly.go:100:21:100:21 | c | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | | CookieWithoutHttpOnly.go:100:21:100:21 | c | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | provenance | | | CookieWithoutHttpOnly.go:104:10:104:18 | "session" | CookieWithoutHttpOnly.go:106:10:106:13 | name | provenance | | | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | | CookieWithoutHttpOnly.go:106:10:106:13 | name | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:109:15:109:19 | false | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | | CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | | CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | | CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | provenance | | @@ -211,20 +131,12 @@ edges | CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | CookieWithoutHttpOnly.go:116:10:116:16 | session | provenance | | | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | | CookieWithoutHttpOnly.go:116:10:116:16 | session | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:119:15:119:19 | false | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | | CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | | CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | | CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | provenance | | @@ -235,226 +147,90 @@ edges | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | | CookieWithoutHttpOnly.go:126:2:126:43 | ... := ...[0] | CookieWithoutHttpOnly.go:129:2:129:8 | session | provenance | | | CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:126:2:126:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | | CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly | CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | provenance | | | CookieWithoutHttpOnly.go:133:14:133:18 | false | CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | provenance | | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | | CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | Config | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | provenance | | | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | | | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | | | CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | | CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | | -| CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:149:2:149:8 | session | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:149:2:149:8 | session | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | +| CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | Config | | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:149:20:151:2 | &... | provenance | | | CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | provenance | | | CookieWithoutHttpOnly.go:157:14:157:17 | true | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | provenance | | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | | CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | Config | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | provenance | | | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | | | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | | | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly | CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | provenance | | | CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | provenance | | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | provenance | | | CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | | CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | Config | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | provenance | | | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | | | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | | | CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:183:2:183:43 | ... := ...[0] | CookieWithoutHttpOnly.go:191:19:191:25 | session | provenance | | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | | CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:183:2:183:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | | CookieWithoutHttpOnly.go:195:2:195:43 | ... := ...[0] | CookieWithoutHttpOnly.go:202:19:202:25 | session | provenance | | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | | CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:195:2:195:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:191:2:191:6 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | nodes | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | semmle.label | struct literal | | CookieWithoutHttpOnly.go:12:10:12:18 | "session" | semmle.label | "session" | | CookieWithoutHttpOnly.go:15:20:15:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:15:21:15:21 | c | semmle.label | c | | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | semmle.label | struct literal | @@ -463,8 +239,6 @@ nodes | CookieWithoutHttpOnly.go:22:13:22:17 | false | semmle.label | false | | CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:24:21:24:21 | c | semmle.label | c | @@ -475,8 +249,6 @@ nodes | CookieWithoutHttpOnly.go:31:13:31:16 | true | semmle.label | true | | CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:33:21:33:21 | c | semmle.label | c | @@ -487,8 +259,6 @@ nodes | CookieWithoutHttpOnly.go:41:15:41:18 | true | semmle.label | true | | CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:42:21:42:21 | c | semmle.label | c | @@ -499,8 +269,6 @@ nodes | CookieWithoutHttpOnly.go:50:15:50:19 | false | semmle.label | false | | CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:51:21:51:21 | c | semmle.label | c | @@ -513,8 +281,6 @@ nodes | CookieWithoutHttpOnly.go:59:13:59:15 | val | semmle.label | val | | CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:61:21:61:21 | c | semmle.label | c | @@ -527,8 +293,6 @@ nodes | CookieWithoutHttpOnly.go:69:13:69:15 | val | semmle.label | val | | CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:71:21:71:21 | c | semmle.label | c | @@ -541,8 +305,6 @@ nodes | CookieWithoutHttpOnly.go:80:15:80:17 | val | semmle.label | val | | CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:81:21:81:21 | c | semmle.label | c | @@ -555,8 +317,6 @@ nodes | CookieWithoutHttpOnly.go:90:15:90:17 | val | semmle.label | val | | CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:91:21:91:21 | c | semmle.label | c | @@ -564,7 +324,6 @@ nodes | CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | semmle.label | struct literal | | CookieWithoutHttpOnly.go:99:15:99:19 | false | semmle.label | false | | CookieWithoutHttpOnly.go:100:20:100:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:100:21:100:21 | c | semmle.label | c | | CookieWithoutHttpOnly.go:104:10:104:18 | "session" | semmle.label | "session" | @@ -574,8 +333,6 @@ nodes | CookieWithoutHttpOnly.go:109:15:109:19 | false | semmle.label | false | | CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:110:21:110:21 | c | semmle.label | c | @@ -587,8 +344,6 @@ nodes | CookieWithoutHttpOnly.go:119:15:119:19 | false | semmle.label | false | | CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | semmle.label | &... [pointer] | | CookieWithoutHttpOnly.go:120:21:120:21 | c | semmle.label | c | @@ -599,20 +354,14 @@ nodes | CookieWithoutHttpOnly.go:129:2:129:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly | semmle.label | definition of httpOnly | | CookieWithoutHttpOnly.go:133:14:133:18 | false | semmle.label | false | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | -| CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:134:16:134:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | semmle.label | session [pointer] | -| CookieWithoutHttpOnly.go:135:2:135:8 | session [pointer] | semmle.label | session [pointer] | | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | semmle.label | implicit dereference | | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | semmle.label | implicit dereference | | CookieWithoutHttpOnly.go:137:2:137:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:137:2:137:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | semmle.label | session [pointer] | -| CookieWithoutHttpOnly.go:137:2:137:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | semmle.label | struct literal | @@ -621,34 +370,25 @@ nodes | CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | | CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:146:16:146:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | semmle.label | session [pointer] | | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | semmle.label | implicit dereference | | CookieWithoutHttpOnly.go:149:2:149:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:149:20:151:2 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | semmle.label | struct literal | | CookieWithoutHttpOnly.go:153:2:153:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:153:2:153:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | semmle.label | definition of httpOnly | | CookieWithoutHttpOnly.go:157:14:157:17 | true | semmle.label | true | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | -| CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | | CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:158:16:158:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | semmle.label | session [pointer] | -| CookieWithoutHttpOnly.go:159:2:159:8 | session [pointer] | semmle.label | session [pointer] | | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | semmle.label | implicit dereference | | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | semmle.label | implicit dereference | | CookieWithoutHttpOnly.go:161:2:161:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:161:2:161:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | semmle.label | session [pointer] | -| CookieWithoutHttpOnly.go:161:2:161:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | semmle.label | struct literal | @@ -659,20 +399,14 @@ nodes | CookieWithoutHttpOnly.go:166:2:166:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly | semmle.label | argument corresponding to httpOnly | | CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | semmle.label | definition of httpOnly | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | -| CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | semmle.label | definition of session [pointer] | | CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:170:16:170:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | semmle.label | session [pointer] | -| CookieWithoutHttpOnly.go:171:2:171:8 | session [pointer] | semmle.label | session [pointer] | | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | semmle.label | implicit dereference | | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | semmle.label | implicit dereference | | CookieWithoutHttpOnly.go:173:2:173:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:173:2:173:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | semmle.label | session [pointer] | -| CookieWithoutHttpOnly.go:173:2:173:8 | session [pointer] | semmle.label | session [pointer] | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | semmle.label | struct literal | @@ -683,11 +417,9 @@ nodes | CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:183:2:183:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:183:16:183:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:191:2:191:6 | store | semmle.label | store | | CookieWithoutHttpOnly.go:191:19:191:25 | session | semmle.label | session | | CookieWithoutHttpOnly.go:195:2:195:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:195:16:195:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:202:2:202:6 | store | semmle.label | store | | CookieWithoutHttpOnly.go:202:19:202:25 | session | semmle.label | session | | CookieWithoutHttpOnly.go:214:66:214:70 | false | semmle.label | false | subpaths diff --git a/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.expected b/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.expected index fa926d9be30..5b26a2a9b36 100644 --- a/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.expected +++ b/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.expected @@ -1,16 +1,12 @@ edges | go-jose.v3.go:13:14:13:34 | type conversion | go-jose.v3.go:24:32:24:37 | JwtKey | provenance | | -| go-jose.v3.go:13:14:13:34 | type conversion | go-jose.v3.go:24:32:24:37 | JwtKey | provenance | | | go-jose.v3.go:13:21:13:33 | "AllYourBase" | go-jose.v3.go:13:14:13:34 | type conversion | provenance | | -| go-jose.v3.go:24:32:24:37 | JwtKey | go-jose.v3.go:24:32:24:37 | JwtKey | provenance | | -| go-jose.v3.go:24:32:24:37 | JwtKey | go-jose.v3.go:24:32:24:37 | JwtKey | provenance | | | golang-jwt-v5.go:19:15:19:35 | type conversion | golang-jwt-v5.go:27:9:27:15 | JwtKey1 | provenance | | | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | golang-jwt-v5.go:19:15:19:35 | type conversion | provenance | | nodes | go-jose.v3.go:13:14:13:34 | type conversion | semmle.label | type conversion | | go-jose.v3.go:13:21:13:33 | "AllYourBase" | semmle.label | "AllYourBase" | | go-jose.v3.go:24:32:24:37 | JwtKey | semmle.label | JwtKey | -| go-jose.v3.go:24:32:24:37 | JwtKey | semmle.label | JwtKey | | golang-jwt-v5.go:19:15:19:35 | type conversion | semmle.label | type conversion | | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | semmle.label | "AllYourBase" | | golang-jwt-v5.go:27:9:27:15 | JwtKey1 | semmle.label | JwtKey1 | diff --git a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected index 634d637c588..4b26395c8e7 100644 --- a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected +++ b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected @@ -7,17 +7,14 @@ edges | Dsn.go:28:11:28:110 | call to Sprintf | Dsn.go:29:29:29:33 | dbDSN | 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 | | -| Dsn.go:62:2:62:4 | definition of cfg [pointer] | Dsn.go:67:102:67:104 | cfg [pointer] | provenance | | -| Dsn.go:63:9:63:11 | cfg [pointer] | Dsn.go:63:9:63:11 | implicit dereference | provenance | | -| Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:62:2:62:4 | definition of cfg [pointer] | provenance | | -| Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:67:102:67:108 | selection of dsn | provenance | | +| Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | Dsn.go:67:102:67:104 | cfg [pointer] | provenance | | +| Dsn.go:63:9:63:11 | implicit dereference [postupdate] | Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | provenance | | +| Dsn.go:63:9:63:11 | implicit dereference [postupdate] | Dsn.go:67:102:67:108 | selection of dsn | provenance | | | Dsn.go:63:19:63:25 | selection of Args | Dsn.go:63:19:63:29 | slice expression | provenance | Src:MaD:1 | -| Dsn.go:63:19:63:29 | slice expression | Dsn.go:63:9:63:11 | implicit dereference | provenance | FunctionModel | +| Dsn.go:63:19:63:29 | slice expression | Dsn.go:63:9:63:11 | implicit dereference [postupdate] | provenance | FunctionModel | | Dsn.go:67:11:67:109 | []type{args} [array] | Dsn.go:67:11:67:109 | call to Sprintf | provenance | MaD:2 | | Dsn.go:67:11:67:109 | call to Sprintf | Dsn.go:68:29:68:33 | dbDSN | provenance | | | Dsn.go:67:102:67:104 | cfg [pointer] | Dsn.go:67:102:67:104 | implicit dereference | provenance | | -| Dsn.go:67:102:67:104 | implicit dereference | Dsn.go:63:9:63:11 | implicit dereference | provenance | | | Dsn.go:67:102:67:104 | implicit dereference | Dsn.go:67:102:67:108 | selection of dsn | provenance | | | Dsn.go:67:102:67:108 | selection of dsn | Dsn.go:67:11:67:109 | []type{args} [array] | provenance | | | Dsn.go:67:102:67:108 | selection of dsn | Dsn.go:67:11:67:109 | call to Sprintf | provenance | FunctionModel | @@ -30,9 +27,8 @@ nodes | Dsn.go:28:11:28:110 | call to Sprintf | semmle.label | call to Sprintf | | 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] | -| Dsn.go:63:9:63:11 | cfg [pointer] | semmle.label | cfg [pointer] | -| Dsn.go:63:9:63:11 | implicit dereference | semmle.label | implicit dereference | +| Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | semmle.label | cfg [postupdate] [pointer] | +| Dsn.go:63:9:63:11 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | | Dsn.go:63:19:63:25 | selection of Args | semmle.label | selection of Args | | Dsn.go:63:19:63:29 | slice expression | semmle.label | slice expression | | Dsn.go:67:11:67:109 | []type{args} [array] | semmle.label | []type{args} [array] | diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index 87780085a54..a947101b354 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -4,9 +4,9 @@ | builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value. | | builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value. | | builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value. | -| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. | -| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. | -| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. | | new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value. | | new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value. | | new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value. | @@ -22,9 +22,9 @@ edges | builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | provenance | Src:MaD:8 | | builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | provenance | Src:MaD:8 | | builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | provenance | Src:MaD:8 | -| new-tests.go:26:26:26:30 | &... | new-tests.go:31:48:31:56 | selection of word | provenance | Src:MaD:3 | -| new-tests.go:26:26:26:30 | &... | new-tests.go:32:48:32:56 | selection of safe | provenance | Src:MaD:3 | -| new-tests.go:26:26:26:30 | &... | new-tests.go:35:49:35:57 | selection of word | provenance | Src:MaD:3 | +| new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:48:31:56 | selection of word | provenance | Src:MaD:3 | +| new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:32:48:32:56 | selection of safe | provenance | Src:MaD:3 | +| new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:35:49:35:57 | selection of word | provenance | Src:MaD:3 | | new-tests.go:31:11:31:57 | []type{args} [array] | new-tests.go:31:11:31:57 | call to Sprintf | provenance | MaD:11 | | new-tests.go:31:48:31:56 | selection of word | new-tests.go:31:11:31:57 | []type{args} [array] | provenance | | | new-tests.go:31:48:31:56 | selection of word | new-tests.go:31:11:31:57 | call to Sprintf | provenance | FunctionModel | @@ -38,10 +38,10 @@ edges | new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | provenance | Src:MaD:2 | | new-tests.go:62:2:62:39 | ... := ...[0] | new-tests.go:63:17:63:23 | reqBody | provenance | | | new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | provenance | Src:MaD:6 MaD:12 | -| new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... | provenance | MaD:10 | -| new-tests.go:63:26:63:30 | &... | new-tests.go:68:48:68:56 | selection of word | provenance | | -| new-tests.go:63:26:63:30 | &... | new-tests.go:69:48:69:56 | selection of safe | provenance | | -| new-tests.go:63:26:63:30 | &... | new-tests.go:74:49:74:57 | selection of word | provenance | | +| new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... [postupdate] | provenance | MaD:10 | +| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:68:48:68:56 | selection of word | provenance | | +| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:69:48:69:56 | selection of safe | provenance | | +| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:74:49:74:57 | selection of word | provenance | | | new-tests.go:68:11:68:57 | []type{args} [array] | new-tests.go:68:11:68:57 | call to Sprintf | provenance | MaD:11 | | new-tests.go:68:48:68:56 | selection of word | new-tests.go:68:11:68:57 | []type{args} [array] | provenance | | | new-tests.go:68:48:68:56 | selection of word | new-tests.go:68:11:68:57 | call to Sprintf | provenance | FunctionModel | @@ -86,7 +86,7 @@ nodes | builtin.go:114:15:114:28 | untrustedInput | semmle.label | untrustedInput | | builtin.go:129:21:129:31 | call to Referer | semmle.label | call to Referer | | builtin.go:132:38:132:51 | untrustedInput | semmle.label | untrustedInput | -| new-tests.go:26:26:26:30 | &... | semmle.label | &... | +| new-tests.go:26:26:26:30 | &... [postupdate] | semmle.label | &... [postupdate] | | new-tests.go:31:11:31:57 | []type{args} [array] | semmle.label | []type{args} [array] | | new-tests.go:31:11:31:57 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:31:48:31:56 | selection of word | semmle.label | selection of word | @@ -103,7 +103,7 @@ nodes | new-tests.go:62:2:62:39 | ... := ...[0] | semmle.label | ... := ...[0] | | new-tests.go:62:31:62:38 | selection of Body | semmle.label | selection of Body | | new-tests.go:63:17:63:23 | reqBody | semmle.label | reqBody | -| new-tests.go:63:26:63:30 | &... | semmle.label | &... | +| new-tests.go:63:26:63:30 | &... [postupdate] | semmle.label | &... [postupdate] | | new-tests.go:68:11:68:57 | []type{args} [array] | semmle.label | []type{args} [array] | | new-tests.go:68:11:68:57 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:68:48:68:56 | selection of word | semmle.label | selection of word | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/DefaultTaintSanitizer/DefaultSanitizer.expected b/go/ql/test/library-tests/semmle/go/dataflow/DefaultTaintSanitizer/DefaultSanitizer.expected index b198361df04..72124e7dae0 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/DefaultTaintSanitizer/DefaultSanitizer.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/DefaultTaintSanitizer/DefaultSanitizer.expected @@ -4,27 +4,27 @@ models | 3 | Summary: io; Reader; true; Read; ; ; Argument[receiver]; Argument[0]; taint; manual | | 4 | Summary: os; File; true; Read; ; ; Argument[receiver]; Argument[0]; taint; manual | edges -| Builtin.go:6:2:6:2 | definition of b | Builtin.go:8:9:8:17 | type conversion | provenance | | -| Builtin.go:7:2:7:15 | selection of Body | Builtin.go:6:2:6:2 | definition of b | provenance | Src:MaD:1 MaD:2 | -| Builtin.go:7:2:7:15 | selection of Body | Builtin.go:6:2:6:2 | definition of b | provenance | Src:MaD:1 MaD:3 | -| Builtin.go:7:2:7:15 | selection of Body | Builtin.go:6:2:6:2 | definition of b | provenance | Src:MaD:1 MaD:4 | -| Builtin.go:12:2:12:2 | definition of b | Builtin.go:17:9:17:17 | type conversion | provenance | | -| Builtin.go:13:2:13:15 | selection of Body | Builtin.go:12:2:12:2 | definition of b | provenance | Src:MaD:1 MaD:2 | -| Builtin.go:13:2:13:15 | selection of Body | Builtin.go:12:2:12:2 | definition of b | provenance | Src:MaD:1 MaD:3 | -| Builtin.go:13:2:13:15 | selection of Body | Builtin.go:12:2:12:2 | definition of b | provenance | Src:MaD:1 MaD:4 | -| Builtin.go:21:2:21:2 | definition of b | Builtin.go:24:10:24:18 | type conversion | provenance | | -| Builtin.go:22:2:22:15 | selection of Body | Builtin.go:21:2:21:2 | definition of b | provenance | Src:MaD:1 MaD:2 | -| Builtin.go:22:2:22:15 | selection of Body | Builtin.go:21:2:21:2 | definition of b | provenance | Src:MaD:1 MaD:3 | -| Builtin.go:22:2:22:15 | selection of Body | Builtin.go:21:2:21:2 | definition of b | provenance | Src:MaD:1 MaD:4 | +| Builtin.go:7:2:7:15 | selection of Body | Builtin.go:7:22:7:22 | b [postupdate] | provenance | Src:MaD:1 MaD:2 | +| Builtin.go:7:2:7:15 | selection of Body | Builtin.go:7:22:7:22 | b [postupdate] | provenance | Src:MaD:1 MaD:3 | +| Builtin.go:7:2:7:15 | selection of Body | Builtin.go:7:22:7:22 | b [postupdate] | provenance | Src:MaD:1 MaD:4 | +| Builtin.go:7:22:7:22 | b [postupdate] | Builtin.go:8:9:8:17 | type conversion | provenance | | +| Builtin.go:13:2:13:15 | selection of Body | Builtin.go:13:22:13:22 | b [postupdate] | provenance | Src:MaD:1 MaD:2 | +| Builtin.go:13:2:13:15 | selection of Body | Builtin.go:13:22:13:22 | b [postupdate] | provenance | Src:MaD:1 MaD:3 | +| Builtin.go:13:2:13:15 | selection of Body | Builtin.go:13:22:13:22 | b [postupdate] | provenance | Src:MaD:1 MaD:4 | +| Builtin.go:13:22:13:22 | b [postupdate] | Builtin.go:17:9:17:17 | type conversion | provenance | | +| Builtin.go:22:2:22:15 | selection of Body | Builtin.go:22:22:22:22 | b [postupdate] | provenance | Src:MaD:1 MaD:2 | +| Builtin.go:22:2:22:15 | selection of Body | Builtin.go:22:22:22:22 | b [postupdate] | provenance | Src:MaD:1 MaD:3 | +| Builtin.go:22:2:22:15 | selection of Body | Builtin.go:22:22:22:22 | b [postupdate] | provenance | Src:MaD:1 MaD:4 | +| Builtin.go:22:22:22:22 | b [postupdate] | Builtin.go:24:10:24:18 | type conversion | provenance | | nodes -| Builtin.go:6:2:6:2 | definition of b | semmle.label | definition of b | | Builtin.go:7:2:7:15 | selection of Body | semmle.label | selection of Body | +| Builtin.go:7:22:7:22 | b [postupdate] | semmle.label | b [postupdate] | | Builtin.go:8:9:8:17 | type conversion | semmle.label | type conversion | -| Builtin.go:12:2:12:2 | definition of b | semmle.label | definition of b | | Builtin.go:13:2:13:15 | selection of Body | semmle.label | selection of Body | +| Builtin.go:13:22:13:22 | b [postupdate] | semmle.label | b [postupdate] | | Builtin.go:17:9:17:17 | type conversion | semmle.label | type conversion | -| Builtin.go:21:2:21:2 | definition of b | semmle.label | definition of b | | Builtin.go:22:2:22:15 | selection of Body | semmle.label | selection of Body | +| Builtin.go:22:22:22:22 | b [postupdate] | semmle.label | b [postupdate] | | Builtin.go:24:10:24:18 | type conversion | semmle.label | type conversion | subpaths #select diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected index a6f313198d1..f99ee92a492 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected @@ -1,6 +1,5 @@ invalidModelRow #select -| test.go:10:6:10:8 | definition of arg | qltest-arg | | test.go:39:8:39:15 | call to Src1 | qltest | | test.go:40:8:40:15 | call to Src2 | qltest | | test.go:40:8:40:15 | call to Src2 | qltest-w-subtypes | @@ -8,6 +7,7 @@ invalidModelRow | test.go:42:2:42:21 | ... = ...[0] | qltest | | test.go:42:2:42:21 | ... = ...[1] | qltest-w-subtypes | | test.go:43:2:43:22 | ... = ...[1] | qltest-w-subtypes | +| test.go:44:11:44:13 | arg [postupdate] | qltest-arg | | test.go:59:9:59:16 | call to Src1 | qltest | | test.go:102:46:102:53 | call to Src1 | qltest | | test.go:112:35:112:42 | call to Src1 | qltest | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/steps.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/steps.expected index eaf00bde26f..97a1cc49261 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/steps.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/steps.expected @@ -2,18 +2,18 @@ invalidModelRow #select | test.go:17:23:17:25 | arg | test.go:17:10:17:26 | call to StepArgRes | | test.go:18:27:18:29 | arg | test.go:18:2:18:30 | ... = ...[1] | -| test.go:19:15:19:17 | arg | test.go:11:6:11:9 | definition of arg1 | -| test.go:21:16:21:18 | arg | test.go:13:6:13:6 | definition of t | +| test.go:19:15:19:17 | arg | test.go:19:20:19:23 | arg1 [postupdate] | +| test.go:21:16:21:18 | arg | test.go:21:2:21:2 | t [postupdate] | | test.go:22:10:22:10 | t | test.go:22:10:22:24 | call to StepQualRes | -| test.go:23:2:23:2 | t | test.go:10:6:10:8 | definition of arg | +| test.go:23:2:23:2 | t | test.go:23:16:23:18 | arg [postupdate] | | test.go:24:32:24:34 | arg | test.go:24:10:24:35 | call to StepArgResNoQual | | test.go:61:25:61:27 | src | test.go:61:12:61:28 | call to StepArgRes | | test.go:64:29:64:31 | src | test.go:64:2:64:32 | ... := ...[1] | -| test.go:68:15:68:17 | src | test.go:67:6:67:11 | definition of taint3 | -| test.go:76:21:76:23 | src | test.go:75:6:75:11 | definition of taint4 | +| test.go:68:15:68:17 | src | test.go:68:20:68:25 | taint3 [postupdate] | +| test.go:76:21:76:23 | src | test.go:76:2:76:7 | taint4 [postupdate] | | test.go:79:13:79:25 | type assertion | test.go:79:12:79:40 | call to StepQualRes | -| test.go:83:3:83:15 | type assertion | test.go:82:6:82:11 | definition of taint6 | +| test.go:83:3:83:15 | type assertion | test.go:83:30:83:35 | taint6 [postupdate] | | test.go:86:34:86:36 | src | test.go:86:12:86:37 | call to StepArgResNoQual | | test.go:149:10:149:27 | []type{args} | test.go:149:10:149:27 | call to append | | test.go:149:17:149:21 | slice | test.go:149:10:149:27 | call to append | -| test.go:155:15:155:20 | slice1 | test.go:154:2:154:7 | definition of slice2 | +| test.go:155:15:155:20 | slice1 | test.go:155:7:155:12 | slice2 [postupdate] | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected index a85e8689960..009238baa4d 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected @@ -1,6 +1,5 @@ invalidModelRow #select -| test.go:10:6:10:8 | definition of arg | qltest-arg | | test.go:39:8:39:15 | call to Src1 | qltest | | test.go:40:8:40:15 | call to Src2 | qltest | | test.go:40:8:40:15 | call to Src2 | qltest-w-subtypes | @@ -8,6 +7,7 @@ invalidModelRow | test.go:42:2:42:21 | ... = ...[0] | qltest | | test.go:42:2:42:21 | ... = ...[1] | qltest-w-subtypes | | test.go:43:2:43:22 | ... = ...[1] | qltest-w-subtypes | +| test.go:44:11:44:13 | arg [postupdate] | qltest-arg | | test.go:59:9:59:16 | call to Src1 | qltest | | test.go:102:46:102:53 | call to Src1 | qltest | | test.go:112:35:112:42 | call to Src1 | qltest | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/steps.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/steps.expected index e53ed76ad00..eb52daa4253 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/steps.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/steps.expected @@ -2,17 +2,17 @@ invalidModelRow #select | test.go:17:23:17:25 | arg | test.go:17:10:17:26 | call to StepArgRes | | test.go:18:27:18:29 | arg | test.go:18:2:18:30 | ... = ...[1] | -| test.go:19:15:19:17 | arg | test.go:11:6:11:9 | definition of arg1 | -| test.go:21:16:21:18 | arg | test.go:13:6:13:6 | definition of t | +| test.go:19:15:19:17 | arg | test.go:19:20:19:23 | arg1 [postupdate] | +| test.go:21:16:21:18 | arg | test.go:21:2:21:2 | t [postupdate] | | test.go:22:10:22:10 | t | test.go:22:10:22:24 | call to StepQualRes | -| test.go:23:2:23:2 | t | test.go:10:6:10:8 | definition of arg | +| test.go:23:2:23:2 | t | test.go:23:16:23:18 | arg [postupdate] | | test.go:24:32:24:34 | arg | test.go:24:10:24:35 | call to StepArgResNoQual | | test.go:61:25:61:27 | src | test.go:61:12:61:28 | call to StepArgRes | | test.go:64:29:64:31 | src | test.go:64:2:64:32 | ... := ...[1] | -| test.go:68:15:68:17 | src | test.go:67:6:67:11 | definition of taint3 | -| test.go:76:21:76:23 | src | test.go:75:6:75:11 | definition of taint4 | +| test.go:68:15:68:17 | src | test.go:68:20:68:25 | taint3 [postupdate] | +| test.go:76:21:76:23 | src | test.go:76:2:76:7 | taint4 [postupdate] | | test.go:79:13:79:25 | type assertion | test.go:79:12:79:40 | call to StepQualRes | -| test.go:83:3:83:15 | type assertion | test.go:82:6:82:11 | definition of taint6 | +| test.go:83:3:83:15 | type assertion | test.go:83:30:83:35 | taint6 [postupdate] | | test.go:86:34:86:36 | src | test.go:86:12:86:37 | call to StepArgResNoQual | | test.go:202:14:202:19 | srcInt | test.go:202:10:202:26 | call to max | | test.go:202:22:202:22 | 0 | test.go:202:10:202:26 | call to max | 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 6fadcdaabe6..11b73b0915d 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 @@ -1,13 +1,13 @@ | main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[0] | | main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[1] | -| main.go:38:13:38:13 | 1 | main.go:38:7:38:20 | slice literal | -| main.go:38:16:38:16 | 2 | main.go:38:7:38:20 | slice literal | -| main.go:38:19:38:19 | 3 | main.go:38:7:38:20 | slice literal | +| main.go:38:13:38:13 | 1 | main.go:38:7:38:20 | slice literal [postupdate] | +| main.go:38:16:38:16 | 2 | main.go:38:7:38:20 | slice literal [postupdate] | +| main.go:38:19:38:19 | 3 | main.go:38:7:38:20 | slice literal [postupdate] | | 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: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:42:10:42:11 | s4 | main.go:42:7:42:7 | s [postupdate] | | 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] | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.expected index f9b4b8106f1..b0c0a58b339 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.expected @@ -1,3 +1,3 @@ -| file://:0:0:0:0 | NewEncoder | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:9:6:9:6 | definition of w | -| file://:0:0:0:0 | ReadFrom | tst.go:10:23:10:28 | reader | tst.go:9:2:9:12 | definition of bytesBuffer | -| file://:0:0:0:0 | Reset | reset.go:12:15:12:20 | source | reset.go:11:6:11:11 | definition of reader | +| file://:0:0:0:0 | NewEncoder | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:10:25:10:25 | w [postupdate] | +| file://:0:0:0:0 | ReadFrom | tst.go:10:23:10:28 | reader | tst.go:10:2:10:12 | bytesBuffer [postupdate] | +| file://:0:0:0:0 | Reset | reset.go:12:15:12:20 | source | reset.go:12:2:12:7 | reader [postupdate] | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionOutput_getExitNode.expected b/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionOutput_getExitNode.expected index e8addfb217e..eebf68d92d4 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionOutput_getExitNode.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionOutput_getExitNode.expected @@ -1,13 +1,13 @@ -| parameter 0 | reset.go:12:2:12:21 | call to Reset | reset.go:9:2:9:7 | definition of source | -| parameter 0 | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:9:6:9:6 | definition of w | -| parameter 0 | tst2.go:10:9:10:39 | call to Encode | tst2.go:8:12:8:15 | definition of data | -| parameter 0 | tst.go:10:2:10:29 | call to ReadFrom | tst.go:8:12:8:17 | definition of reader | -| parameter 0 | tst.go:16:2:16:12 | call to test5 | tst.go:15:12:15:12 | definition of x | -| parameter 1 | tst.go:16:2:16:12 | call to test5 | tst.go:15:15:15:15 | definition of y | -| receiver | main.go:53:14:53:21 | call to bump | main.go:52:2:52:2 | definition of c | -| receiver | reset.go:12:2:12:21 | call to Reset | reset.go:11:6:11:11 | definition of reader | -| receiver | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:9:10:26 | call to NewEncoder | -| receiver | tst.go:10:2:10:29 | call to ReadFrom | tst.go:9:2:9:12 | definition of bytesBuffer | +| parameter 0 | reset.go:12:2:12:21 | call to Reset | reset.go:12:15:12:20 | source [postupdate] | +| parameter 0 | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:10:25:10:25 | w [postupdate] | +| parameter 0 | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:35:10:38 | data [postupdate] | +| parameter 0 | tst.go:10:2:10:29 | call to ReadFrom | tst.go:10:23:10:28 | reader [postupdate] | +| parameter 0 | tst.go:16:2:16:12 | call to test5 | tst.go:16:8:16:8 | x [postupdate] | +| parameter 1 | tst.go:16:2:16:12 | call to test5 | tst.go:16:11:16:11 | y [postupdate] | +| receiver | main.go:53:14:53:21 | call to bump | main.go:53:14:53:14 | c [postupdate] | +| receiver | reset.go:12:2:12:21 | call to Reset | reset.go:12:2:12:7 | reader [postupdate] | +| receiver | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:9:10:26 | call to NewEncoder [postupdate] | +| receiver | tst.go:10:2:10:29 | call to ReadFrom | tst.go:10:2:10:12 | bytesBuffer [postupdate] | | result | main.go:51:2:51:14 | call to op | main.go:51:2:51:14 | call to op | | result | main.go:53:2:53:22 | call to op2 | main.go:53:2:53:22 | call to op2 | | result | main.go:53:14:53:21 | call to bump | main.go:53:14:53:21 | call to bump | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/test_gogf_gf_database_gdb.go b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/test_gogf_gf_database_gdb.go index 436c9dab677..45e6a3aefa1 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/test_gogf_gf_database_gdb.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/test_gogf_gf_database_gdb.go @@ -30,9 +30,9 @@ func gogf_Core(g gdb.Core) { g.GetStruct(&v7, "SELECT user from users") // $ source sink(v7) // $ hasTaintFlow="v7" - var v8 []User // $ source - g.GetStructs(v8, "SELECT user from users") - sink(v8) // $ hasTaintFlow="v8" + var v8 []User + g.GetStructs(v8, "SELECT user from users") // $ source + sink(v8) // $ hasTaintFlow="v8" v9, _ := g.GetValue("SELECT user from users") // $ source sink(v9) // $ hasTaintFlow="v9" @@ -132,9 +132,9 @@ func gogf_TX(g gdb.TX) { g.GetStruct(&v4, "SELECT user from users") // $ source sink(v4) // $ hasTaintFlow="v4" - var v5 []User // $ source - g.GetStructs(v5, "SELECT user from users") - sink(v5) // $ hasTaintFlow="v5" + var v5 []User + g.GetStructs(v5, "SELECT user from users") // $ source + sink(v5) // $ hasTaintFlow="v5" v6, _ := g.GetValue("SELECT user from users") // $ source sink(v6) // $ hasTaintFlow="v6" diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected index aa0345f221e..be8ae2ec2fa 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected @@ -1,7 +1,7 @@ #select -| test.go:35:13:35:30 | type conversion | test.go:33:6:33:10 | definition of bound | test.go:35:13:35:30 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:33:6:33:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:36:13:36:27 | type conversion | test.go:33:6:33:10 | definition of bound | test.go:36:13:36:27 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:33:6:33:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:37:13:37:29 | type conversion | test.go:33:6:33:10 | definition of bound | test.go:37:13:37:29 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:33:6:33:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:35:13:35:30 | type conversion | test.go:34:13:34:17 | bound [postupdate] | test.go:35:13:35:30 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:34:13:34:17 | bound [postupdate] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:36:13:36:27 | type conversion | test.go:34:13:34:17 | bound [postupdate] | test.go:36:13:36:27 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:34:13:34:17 | bound [postupdate] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:37:13:37:29 | type conversion | test.go:34:13:34:17 | bound [postupdate] | test.go:37:13:37:29 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:34:13:34:17 | bound [postupdate] | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:42:13:42:43 | type conversion | test.go:42:20:42:42 | call to Cookie | test.go:42:13:42:43 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:42:20:42:42 | call to Cookie | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:47:13:47:52 | type conversion | test.go:47:20:47:31 | call to Data | test.go:47:13:47:52 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:47:20:47:31 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:52:13:52:53 | type conversion | test.go:52:20:52:43 | call to GetData | test.go:52:13:52:53 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:52:20:52:43 | call to GetData | user-provided value | test.go:0:0:0:0 | test.go | | @@ -30,7 +30,7 @@ | test.go:232:14:232:22 | type conversion | test.go:231:7:231:28 | call to GetString | test.go:232:14:232:22 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:231:7:231:28 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:235:14:235:26 | type conversion | test.go:234:8:234:35 | call to GetStrings | test.go:235:14:235:26 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:234:8:234:35 | call to GetStrings | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:238:14:238:27 | type conversion | test.go:237:9:237:17 | call to Input | test.go:238:14:238:27 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:237:9:237:17 | call to Input | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:242:14:242:30 | type conversion | test.go:240:6:240:8 | definition of str | test.go:242:14:242:30 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:240:6:240:8 | definition of str | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:242:14:242:30 | type conversion | test.go:241:14:241:16 | str [postupdate] | test.go:242:14:242:30 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:241:14:241:16 | str [postupdate] | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:249:21:249:29 | untrusted | test.go:246:15:246:36 | call to GetString | test.go:249:21:249:29 | untrusted | Cross-site scripting vulnerability due to $@. | test.go:246:15:246:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:259:16:259:45 | type conversion | test.go:259:23:259:44 | call to GetCookie | test.go:259:16:259:45 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:259:23:259:44 | call to GetCookie | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:264:16:264:37 | call to GetCookie | test.go:264:16:264:37 | call to GetCookie | test.go:264:16:264:37 | call to GetCookie | Cross-site scripting vulnerability due to $@. | test.go:264:16:264:37 | call to GetCookie | user-provided value | test.go:0:0:0:0 | test.go | | @@ -53,9 +53,9 @@ | test.go:311:21:311:48 | type assertion | test.go:309:15:309:36 | call to GetString | test.go:311:21:311:48 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:309:15:309:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:312:21:312:52 | type assertion | test.go:309:15:309:36 | call to GetString | test.go:312:21:312:52 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:309:15:309:36 | call to GetString | user-provided value | test.go:0:0:0:0 | test.go | | edges -| test.go:33:6:33:10 | definition of bound | test.go:35:13:35:30 | type conversion | provenance | Src:MaD:1 | -| test.go:33:6:33:10 | definition of bound | test.go:36:13:36:27 | type conversion | provenance | Src:MaD:1 | -| test.go:33:6:33:10 | definition of bound | test.go:37:13:37:29 | type conversion | provenance | Src:MaD:1 | +| test.go:34:13:34:17 | bound [postupdate] | test.go:35:13:35:30 | type conversion | provenance | Src:MaD:1 | +| test.go:34:13:34:17 | bound [postupdate] | test.go:36:13:36:27 | type conversion | provenance | Src:MaD:1 | +| test.go:34:13:34:17 | bound [postupdate] | test.go:37:13:37:29 | type conversion | provenance | Src:MaD:1 | | test.go:42:20:42:42 | call to Cookie | test.go:42:13:42:43 | type conversion | provenance | Src:MaD:2 | | test.go:47:20:47:31 | call to Data | test.go:47:13:47:52 | type conversion | provenance | Src:MaD:3 | | test.go:52:20:52:43 | call to GetData | test.go:52:13:52:53 | type conversion | provenance | Src:MaD:4 | @@ -87,8 +87,8 @@ edges | test.go:204:36:204:53 | type assertion | test.go:204:21:204:54 | call to Str2html | provenance | MaD:39 | | test.go:205:21:205:58 | call to Substr | test.go:205:14:205:59 | type conversion | provenance | | | test.go:205:34:205:51 | type assertion | test.go:205:21:205:58 | call to Substr | provenance | MaD:40 | -| test.go:207:6:207:6 | definition of s | test.go:209:14:209:28 | type conversion | provenance | | -| test.go:208:18:208:33 | selection of Form | test.go:207:6:207:6 | definition of s | provenance | Src:MaD:21 MaD:38 | +| test.go:208:18:208:33 | selection of Form | test.go:208:36:208:36 | s [postupdate] | provenance | Src:MaD:21 MaD:38 | +| test.go:208:36:208:36 | s [postupdate] | test.go:209:14:209:28 | type conversion | provenance | | | test.go:223:2:223:34 | ... := ...[0] | test.go:225:31:225:31 | f | provenance | Src:MaD:15 | | test.go:223:2:223:34 | ... := ...[1] | test.go:224:14:224:32 | type conversion | provenance | Src:MaD:15 | | test.go:225:2:225:32 | ... := ...[0] | test.go:226:14:226:20 | content | provenance | | @@ -97,7 +97,7 @@ edges | test.go:231:7:231:28 | call to GetString | test.go:232:14:232:22 | type conversion | provenance | Src:MaD:17 | | test.go:234:8:234:35 | call to GetStrings | test.go:235:14:235:26 | type conversion | provenance | Src:MaD:18 | | test.go:237:9:237:17 | call to Input | test.go:238:14:238:27 | type conversion | provenance | Src:MaD:19 | -| test.go:240:6:240:8 | definition of str | test.go:242:14:242:30 | type conversion | provenance | Src:MaD:20 | +| test.go:241:14:241:16 | str [postupdate] | test.go:242:14:242:30 | type conversion | provenance | Src:MaD:20 | | test.go:246:15:246:36 | call to GetString | test.go:249:21:249:29 | untrusted | provenance | Src:MaD:17 | | test.go:259:23:259:44 | call to GetCookie | test.go:259:16:259:45 | type conversion | provenance | Src:MaD:14 | | test.go:270:62:270:83 | call to GetCookie | test.go:270:55:270:84 | type conversion | provenance | Src:MaD:14 | @@ -116,8 +116,8 @@ edges | test.go:275:2:275:40 | ... := ...[0] | test.go:301:39:301:50 | genericFiles | provenance | Src:MaD:16 | | test.go:275:2:275:40 | ... := ...[0] | test.go:302:40:302:51 | genericFiles | provenance | Src:MaD:16 | | test.go:275:2:275:40 | ... := ...[0] | test.go:303:39:303:50 | genericFiles | provenance | Src:MaD:16 | -| test.go:276:2:276:13 | definition of genericFiles [array] | test.go:297:51:297:62 | genericFiles [array] | provenance | | -| test.go:278:21:278:28 | index expression | test.go:276:2:276:13 | definition of genericFiles [array] | provenance | | +| test.go:278:3:278:14 | genericFiles [postupdate] [array] | test.go:297:51:297:62 | genericFiles [array] | provenance | | +| test.go:278:21:278:28 | index expression | test.go:278:3:278:14 | genericFiles [postupdate] [array] | provenance | | | test.go:283:44:283:60 | selection of Filename | test.go:283:21:283:61 | call to GetDisplayString | provenance | FunctionModel | | test.go:284:21:284:53 | call to SliceChunk | test.go:284:21:284:92 | selection of Filename | provenance | | | test.go:284:38:284:49 | genericFiles | test.go:284:21:284:53 | call to SliceChunk | provenance | MaD:22 | @@ -146,10 +146,10 @@ edges | test.go:302:40:302:51 | genericFiles | test.go:302:21:302:52 | call to SliceShuffle | provenance | MaD:30 | | test.go:303:21:303:51 | call to SliceUnique | test.go:303:21:303:87 | selection of Filename | provenance | | | test.go:303:39:303:50 | genericFiles | test.go:303:21:303:51 | call to SliceUnique | provenance | MaD:31 | -| test.go:308:2:308:5 | definition of bMap | test.go:311:21:311:24 | bMap | provenance | | -| test.go:308:2:308:5 | definition of bMap | test.go:312:21:312:24 | bMap | provenance | | | test.go:309:15:309:36 | call to GetString | test.go:310:22:310:30 | untrusted | provenance | Src:MaD:17 | -| test.go:310:22:310:30 | untrusted | test.go:308:2:308:5 | definition of bMap | provenance | MaD:34 | +| test.go:310:2:310:5 | bMap [postupdate] | test.go:311:21:311:24 | bMap | provenance | | +| test.go:310:2:310:5 | bMap [postupdate] | test.go:312:21:312:24 | bMap | provenance | | +| test.go:310:22:310:30 | untrusted | test.go:310:2:310:5 | bMap [postupdate] | provenance | MaD:34 | | test.go:311:21:311:24 | bMap | test.go:311:21:311:39 | call to Get | provenance | MaD:32 | | test.go:311:21:311:39 | call to Get | test.go:311:21:311:48 | type assertion | provenance | | | test.go:312:21:312:24 | bMap | test.go:312:21:312:32 | call to Items | provenance | MaD:33 | @@ -197,7 +197,7 @@ models | 40 | Summary: group:beego; ; false; Substr; ; ; Argument[0]; ReturnValue; taint; manual | | 41 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual | nodes -| test.go:33:6:33:10 | definition of bound | semmle.label | definition of bound | +| test.go:34:13:34:17 | bound [postupdate] | semmle.label | bound [postupdate] | | test.go:35:13:35:30 | type conversion | semmle.label | type conversion | | test.go:36:13:36:27 | type conversion | semmle.label | type conversion | | test.go:37:13:37:29 | type conversion | semmle.label | type conversion | @@ -249,8 +249,8 @@ nodes | test.go:205:14:205:59 | type conversion | semmle.label | type conversion | | test.go:205:21:205:58 | call to Substr | semmle.label | call to Substr | | test.go:205:34:205:51 | type assertion | semmle.label | type assertion | -| test.go:207:6:207:6 | definition of s | semmle.label | definition of s | | test.go:208:18:208:33 | selection of Form | semmle.label | selection of Form | +| test.go:208:36:208:36 | s [postupdate] | semmle.label | s [postupdate] | | test.go:209:14:209:28 | type conversion | semmle.label | type conversion | | test.go:223:2:223:34 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:223:2:223:34 | ... := ...[1] | semmle.label | ... := ...[1] | @@ -266,7 +266,7 @@ nodes | test.go:235:14:235:26 | type conversion | semmle.label | type conversion | | test.go:237:9:237:17 | call to Input | semmle.label | call to Input | | test.go:238:14:238:27 | type conversion | semmle.label | type conversion | -| test.go:240:6:240:8 | definition of str | semmle.label | definition of str | +| test.go:241:14:241:16 | str [postupdate] | semmle.label | str [postupdate] | | test.go:242:14:242:30 | type conversion | semmle.label | type conversion | | test.go:246:15:246:36 | call to GetString | semmle.label | call to GetString | | test.go:249:21:249:29 | untrusted | semmle.label | untrusted | @@ -277,7 +277,7 @@ nodes | test.go:270:55:270:84 | type conversion | semmle.label | type conversion | | test.go:270:62:270:83 | call to GetCookie | semmle.label | call to GetCookie | | test.go:275:2:275:40 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:276:2:276:13 | definition of genericFiles [array] | semmle.label | definition of genericFiles [array] | +| test.go:278:3:278:14 | genericFiles [postupdate] [array] | semmle.label | genericFiles [postupdate] [array] | | test.go:278:21:278:28 | index expression | semmle.label | index expression | | test.go:283:21:283:61 | call to GetDisplayString | semmle.label | call to GetDisplayString | | test.go:283:44:283:60 | selection of Filename | semmle.label | selection of Filename | @@ -321,8 +321,8 @@ nodes | test.go:303:21:303:51 | call to SliceUnique | semmle.label | call to SliceUnique | | test.go:303:21:303:87 | selection of Filename | semmle.label | selection of Filename | | test.go:303:39:303:50 | genericFiles | semmle.label | genericFiles | -| test.go:308:2:308:5 | definition of bMap | semmle.label | definition of bMap | | test.go:309:15:309:36 | call to GetString | semmle.label | call to GetString | +| test.go:310:2:310:5 | bMap [postupdate] | semmle.label | bMap [postupdate] | | test.go:310:22:310:30 | untrusted | semmle.label | untrusted | | test.go:311:21:311:24 | bMap | semmle.label | bMap | | test.go:311:21:311:39 | call to Get | semmle.label | call to Get | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected index 98b536aac65..2324a9679ad 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected @@ -10,8 +10,8 @@ edges | test.go:215:15:215:26 | call to Data | test.go:216:18:216:26 | untrusted | provenance | Src:MaD:6 Sink:MaD:2 | | test.go:215:15:215:26 | call to Data | test.go:217:10:217:18 | untrusted | provenance | Src:MaD:6 Sink:MaD:5 | | test.go:215:15:215:26 | call to Data | test.go:218:35:218:43 | untrusted | provenance | Src:MaD:6 Sink:MaD:3 | -| test.go:324:17:324:37 | selection of RequestBody | test.go:324:40:324:43 | &... | provenance | Src:MaD:7 MaD:8 | -| test.go:324:40:324:43 | &... | test.go:326:35:326:43 | untrusted | provenance | Sink:MaD:3 | +| test.go:324:17:324:37 | selection of RequestBody | test.go:324:40:324:43 | &... [postupdate] | provenance | Src:MaD:7 MaD:8 | +| test.go:324:40:324:43 | &... [postupdate] | test.go:326:35:326:43 | untrusted | provenance | Sink:MaD:3 | | test.go:332:15:332:26 | call to Data | test.go:334:23:334:31 | untrusted | provenance | Src:MaD:6 Sink:MaD:1 | | test.go:340:15:340:26 | call to Data | test.go:342:53:342:61 | untrusted | provenance | Src:MaD:6 Sink:MaD:4 | | test.go:340:15:340:26 | call to Data | test.go:344:23:344:31 | untrusted | provenance | Src:MaD:6 Sink:MaD:1 | @@ -30,7 +30,7 @@ nodes | test.go:217:10:217:18 | untrusted | semmle.label | untrusted | | test.go:218:35:218:43 | untrusted | semmle.label | untrusted | | test.go:324:17:324:37 | selection of RequestBody | semmle.label | selection of RequestBody | -| test.go:324:40:324:43 | &... | semmle.label | &... | +| test.go:324:40:324:43 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:326:35:326:43 | untrusted | semmle.label | untrusted | | test.go:332:15:332:26 | call to Data | semmle.label | call to Data | | test.go:334:23:334:31 | untrusted | semmle.label | untrusted | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected index f766a1a2db6..87c68cdc50b 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected @@ -1,8 +1,8 @@ #select -| test.go:81:13:81:29 | type conversion | test.go:80:13:80:16 | &... | test.go:81:13:81:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:80:13:80:16 | &... | stored value | -| test.go:82:13:82:43 | type conversion | test.go:80:13:80:16 | &... | test.go:82:13:82:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:80:13:80:16 | &... | stored value | -| test.go:86:13:86:30 | type conversion | test.go:85:22:85:26 | &... | test.go:86:13:86:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:85:22:85:26 | &... | stored value | -| test.go:90:13:90:30 | type conversion | test.go:89:21:89:25 | &... | test.go:90:13:90:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:89:21:89:25 | &... | stored value | +| test.go:81:13:81:29 | type conversion | test.go:80:13:80:16 | &... [postupdate] | test.go:81:13:81:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:80:13:80:16 | &... [postupdate] | stored value | +| test.go:82:13:82:43 | type conversion | test.go:80:13:80:16 | &... [postupdate] | test.go:82:13:82:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:80:13:80:16 | &... [postupdate] | stored value | +| test.go:86:13:86:30 | type conversion | test.go:85:22:85:26 | &... [postupdate] | test.go:86:13:86:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:85:22:85:26 | &... [postupdate] | stored value | +| test.go:90:13:90:30 | type conversion | test.go:89:21:89:25 | &... [postupdate] | test.go:90:13:90:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:89:21:89:25 | &... [postupdate] | stored value | | test.go:95:13:95:37 | type conversion | test.go:95:20:95:36 | call to Value | test.go:95:13:95:37 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:95:20:95:36 | call to Value | stored value | | test.go:96:13:96:49 | type conversion | test.go:96:20:96:39 | call to RawValue | test.go:96:13:96:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:96:20:96:39 | call to RawValue | stored value | | test.go:97:13:97:38 | type conversion | test.go:97:20:97:37 | call to String | test.go:97:13:97:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:97:20:97:37 | call to String | stored value | @@ -12,25 +12,25 @@ | test.go:101:13:101:38 | type conversion | test.go:101:20:101:37 | call to Value | test.go:101:13:101:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:101:20:101:37 | call to Value | stored value | | test.go:102:13:102:50 | type conversion | test.go:102:20:102:40 | call to RawValue | test.go:102:13:102:50 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:102:20:102:40 | call to RawValue | stored value | | test.go:103:13:103:39 | type conversion | test.go:103:20:103:38 | call to String | test.go:103:13:103:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:103:20:103:38 | call to String | stored value | -| test.go:110:13:110:33 | type conversion | test.go:109:9:109:13 | &... | test.go:110:13:110:33 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:109:9:109:13 | &... | stored value | -| test.go:114:13:114:29 | type conversion | test.go:113:9:113:12 | &... | test.go:114:13:114:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:113:9:113:12 | &... | stored value | -| test.go:118:13:118:48 | type conversion | test.go:117:12:117:19 | &... | test.go:118:13:118:48 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:117:12:117:19 | &... | stored value | -| test.go:122:13:122:43 | type conversion | test.go:121:16:121:24 | &... | test.go:122:13:122:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:121:16:121:24 | &... | stored value | -| test.go:126:13:126:39 | type conversion | test.go:125:16:125:23 | &... | test.go:126:13:126:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:125:16:125:23 | &... | stored value | -| test.go:130:13:130:47 | type conversion | test.go:129:15:129:24 | &... | test.go:130:13:130:47 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:129:15:129:24 | &... | stored value | -| test.go:134:13:134:38 | type conversion | test.go:133:18:133:30 | &... | test.go:134:13:134:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:133:18:133:30 | &... | stored value | -| test.go:141:13:141:48 | type conversion | test.go:140:12:140:19 | &... | test.go:141:13:141:48 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:140:12:140:19 | &... | stored value | -| test.go:145:13:145:43 | type conversion | test.go:144:16:144:24 | &... | test.go:145:13:145:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:144:16:144:24 | &... | stored value | -| test.go:149:13:149:39 | type conversion | test.go:148:16:148:23 | &... | test.go:149:13:149:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:148:16:148:23 | &... | stored value | -| test.go:153:13:153:47 | type conversion | test.go:152:15:152:24 | &... | test.go:153:13:153:47 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:152:15:152:24 | &... | stored value | -| test.go:157:13:157:38 | type conversion | test.go:156:18:156:30 | &... | test.go:157:13:157:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:156:18:156:30 | &... | stored value | -| test.go:161:13:161:28 | type conversion | test.go:160:14:160:22 | &... | test.go:161:13:161:28 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:160:14:160:22 | &... | stored value | -| test.go:165:13:165:32 | type conversion | test.go:164:15:164:24 | &... | test.go:165:13:165:32 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:164:15:164:24 | &... | stored value | +| test.go:110:13:110:33 | type conversion | test.go:109:9:109:13 | &... [postupdate] | test.go:110:13:110:33 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:109:9:109:13 | &... [postupdate] | stored value | +| test.go:114:13:114:29 | type conversion | test.go:113:9:113:12 | &... [postupdate] | test.go:114:13:114:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:113:9:113:12 | &... [postupdate] | stored value | +| test.go:118:13:118:48 | type conversion | test.go:117:12:117:19 | &... [postupdate] | test.go:118:13:118:48 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:117:12:117:19 | &... [postupdate] | stored value | +| test.go:122:13:122:43 | type conversion | test.go:121:16:121:24 | &... [postupdate] | test.go:122:13:122:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:121:16:121:24 | &... [postupdate] | stored value | +| test.go:126:13:126:39 | type conversion | test.go:125:16:125:23 | &... [postupdate] | test.go:126:13:126:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:125:16:125:23 | &... [postupdate] | stored value | +| test.go:130:13:130:47 | type conversion | test.go:129:15:129:24 | &... [postupdate] | test.go:130:13:130:47 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:129:15:129:24 | &... [postupdate] | stored value | +| test.go:134:13:134:38 | type conversion | test.go:133:18:133:30 | &... [postupdate] | test.go:134:13:134:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:133:18:133:30 | &... [postupdate] | stored value | +| test.go:141:13:141:48 | type conversion | test.go:140:12:140:19 | &... [postupdate] | test.go:141:13:141:48 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:140:12:140:19 | &... [postupdate] | stored value | +| test.go:145:13:145:43 | type conversion | test.go:144:16:144:24 | &... [postupdate] | test.go:145:13:145:43 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:144:16:144:24 | &... [postupdate] | stored value | +| test.go:149:13:149:39 | type conversion | test.go:148:16:148:23 | &... [postupdate] | test.go:149:13:149:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:148:16:148:23 | &... [postupdate] | stored value | +| test.go:153:13:153:47 | type conversion | test.go:152:15:152:24 | &... [postupdate] | test.go:153:13:153:47 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:152:15:152:24 | &... [postupdate] | stored value | +| test.go:157:13:157:38 | type conversion | test.go:156:18:156:30 | &... [postupdate] | test.go:157:13:157:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:156:18:156:30 | &... [postupdate] | stored value | +| test.go:161:13:161:28 | type conversion | test.go:160:14:160:22 | &... [postupdate] | test.go:161:13:161:28 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:160:14:160:22 | &... [postupdate] | stored value | +| test.go:165:13:165:32 | type conversion | test.go:164:15:164:24 | &... [postupdate] | test.go:165:13:165:32 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:164:15:164:24 | &... [postupdate] | stored value | edges -| test.go:80:13:80:16 | &... | test.go:81:13:81:29 | type conversion | provenance | Src:MaD:1 | -| test.go:80:13:80:16 | &... | test.go:82:13:82:43 | type conversion | provenance | Src:MaD:1 | -| test.go:85:22:85:26 | &... | test.go:86:13:86:30 | type conversion | provenance | Src:MaD:2 | -| test.go:89:21:89:25 | &... | test.go:90:13:90:30 | type conversion | provenance | Src:MaD:3 | +| test.go:80:13:80:16 | &... [postupdate] | test.go:81:13:81:29 | type conversion | provenance | Src:MaD:1 | +| test.go:80:13:80:16 | &... [postupdate] | test.go:82:13:82:43 | type conversion | provenance | Src:MaD:1 | +| test.go:85:22:85:26 | &... [postupdate] | test.go:86:13:86:30 | type conversion | provenance | Src:MaD:2 | +| test.go:89:21:89:25 | &... [postupdate] | test.go:90:13:90:30 | type conversion | provenance | Src:MaD:3 | | test.go:95:20:95:36 | call to Value | test.go:95:13:95:37 | type conversion | provenance | | | test.go:96:20:96:39 | call to RawValue | test.go:96:13:96:49 | type conversion | provenance | | | test.go:97:20:97:37 | call to String | test.go:97:13:97:38 | type conversion | provenance | | @@ -40,31 +40,31 @@ edges | test.go:101:20:101:37 | call to Value | test.go:101:13:101:38 | type conversion | provenance | | | test.go:102:20:102:40 | call to RawValue | test.go:102:13:102:50 | type conversion | provenance | | | test.go:103:20:103:38 | call to String | test.go:103:13:103:39 | type conversion | provenance | | -| test.go:109:9:109:13 | &... | test.go:110:13:110:33 | type conversion | provenance | | -| test.go:113:9:113:12 | &... | test.go:114:13:114:29 | type conversion | provenance | | -| test.go:117:12:117:19 | &... | test.go:118:13:118:48 | type conversion | provenance | | -| test.go:121:16:121:24 | &... | test.go:122:13:122:43 | type conversion | provenance | | -| test.go:125:16:125:23 | &... | test.go:126:13:126:39 | type conversion | provenance | | -| test.go:129:15:129:24 | &... | test.go:130:13:130:47 | type conversion | provenance | | -| test.go:133:18:133:30 | &... | test.go:134:13:134:38 | type conversion | provenance | | -| test.go:140:12:140:19 | &... | test.go:141:13:141:48 | type conversion | provenance | | -| test.go:144:16:144:24 | &... | test.go:145:13:145:43 | type conversion | provenance | | -| test.go:148:16:148:23 | &... | test.go:149:13:149:39 | type conversion | provenance | | -| test.go:152:15:152:24 | &... | test.go:153:13:153:47 | type conversion | provenance | | -| test.go:156:18:156:30 | &... | test.go:157:13:157:38 | type conversion | provenance | | -| test.go:160:14:160:22 | &... | test.go:161:13:161:28 | type conversion | provenance | | -| test.go:164:15:164:24 | &... | test.go:165:13:165:32 | type conversion | provenance | | +| test.go:109:9:109:13 | &... [postupdate] | test.go:110:13:110:33 | type conversion | provenance | | +| test.go:113:9:113:12 | &... [postupdate] | test.go:114:13:114:29 | type conversion | provenance | | +| test.go:117:12:117:19 | &... [postupdate] | test.go:118:13:118:48 | type conversion | provenance | | +| test.go:121:16:121:24 | &... [postupdate] | test.go:122:13:122:43 | type conversion | provenance | | +| test.go:125:16:125:23 | &... [postupdate] | test.go:126:13:126:39 | type conversion | provenance | | +| test.go:129:15:129:24 | &... [postupdate] | test.go:130:13:130:47 | type conversion | provenance | | +| test.go:133:18:133:30 | &... [postupdate] | test.go:134:13:134:38 | type conversion | provenance | | +| test.go:140:12:140:19 | &... [postupdate] | test.go:141:13:141:48 | type conversion | provenance | | +| test.go:144:16:144:24 | &... [postupdate] | test.go:145:13:145:43 | type conversion | provenance | | +| test.go:148:16:148:23 | &... [postupdate] | test.go:149:13:149:39 | type conversion | provenance | | +| test.go:152:15:152:24 | &... [postupdate] | test.go:153:13:153:47 | type conversion | provenance | | +| test.go:156:18:156:30 | &... [postupdate] | test.go:157:13:157:38 | type conversion | provenance | | +| test.go:160:14:160:22 | &... [postupdate] | test.go:161:13:161:28 | type conversion | provenance | | +| test.go:164:15:164:24 | &... [postupdate] | test.go:165:13:165:32 | type conversion | provenance | | models | 1 | Source: group:beego-orm; Ormer; true; Read; ; ; Argument[0]; database; manual | | 2 | Source: group:beego-orm; Ormer; true; ReadForUpdate; ; ; Argument[0]; database; manual | | 3 | Source: group:beego-orm; Ormer; true; ReadOrCreate; ; ; Argument[0]; database; manual | nodes -| test.go:80:13:80:16 | &... | semmle.label | &... | +| test.go:80:13:80:16 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:81:13:81:29 | type conversion | semmle.label | type conversion | | test.go:82:13:82:43 | type conversion | semmle.label | type conversion | -| test.go:85:22:85:26 | &... | semmle.label | &... | +| test.go:85:22:85:26 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:86:13:86:30 | type conversion | semmle.label | type conversion | -| test.go:89:21:89:25 | &... | semmle.label | &... | +| test.go:89:21:89:25 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:90:13:90:30 | type conversion | semmle.label | type conversion | | test.go:95:13:95:37 | type conversion | semmle.label | type conversion | | test.go:95:20:95:36 | call to Value | semmle.label | call to Value | @@ -84,32 +84,32 @@ nodes | test.go:102:20:102:40 | call to RawValue | semmle.label | call to RawValue | | test.go:103:13:103:39 | type conversion | semmle.label | type conversion | | test.go:103:20:103:38 | call to String | semmle.label | call to String | -| test.go:109:9:109:13 | &... | semmle.label | &... | +| test.go:109:9:109:13 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:110:13:110:33 | type conversion | semmle.label | type conversion | -| test.go:113:9:113:12 | &... | semmle.label | &... | +| test.go:113:9:113:12 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:114:13:114:29 | type conversion | semmle.label | type conversion | -| test.go:117:12:117:19 | &... | semmle.label | &... | +| test.go:117:12:117:19 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:118:13:118:48 | type conversion | semmle.label | type conversion | -| test.go:121:16:121:24 | &... | semmle.label | &... | +| test.go:121:16:121:24 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:122:13:122:43 | type conversion | semmle.label | type conversion | -| test.go:125:16:125:23 | &... | semmle.label | &... | +| test.go:125:16:125:23 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:126:13:126:39 | type conversion | semmle.label | type conversion | -| test.go:129:15:129:24 | &... | semmle.label | &... | +| test.go:129:15:129:24 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:130:13:130:47 | type conversion | semmle.label | type conversion | -| test.go:133:18:133:30 | &... | semmle.label | &... | +| test.go:133:18:133:30 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:134:13:134:38 | type conversion | semmle.label | type conversion | -| test.go:140:12:140:19 | &... | semmle.label | &... | +| test.go:140:12:140:19 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:141:13:141:48 | type conversion | semmle.label | type conversion | -| test.go:144:16:144:24 | &... | semmle.label | &... | +| test.go:144:16:144:24 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:145:13:145:43 | type conversion | semmle.label | type conversion | -| test.go:148:16:148:23 | &... | semmle.label | &... | +| test.go:148:16:148:23 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:149:13:149:39 | type conversion | semmle.label | type conversion | -| test.go:152:15:152:24 | &... | semmle.label | &... | +| test.go:152:15:152:24 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:153:13:153:47 | type conversion | semmle.label | type conversion | -| test.go:156:18:156:30 | &... | semmle.label | &... | +| test.go:156:18:156:30 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:157:13:157:38 | type conversion | semmle.label | type conversion | -| test.go:160:14:160:22 | &... | semmle.label | &... | +| test.go:160:14:160:22 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:161:13:161:28 | type conversion | semmle.label | type conversion | -| test.go:164:15:164:24 | &... | semmle.label | &... | +| test.go:164:15:164:24 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:165:13:165:32 | type conversion | semmle.label | type conversion | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected index bebd53c1ac5..0fa6b12603a 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected @@ -5,9 +5,10 @@ edges | test.go:172:11:172:32 | call to Param | test.go:173:20:173:24 | param | provenance | Src:MaD:2 Sink:MaD:1 | | test.go:178:11:178:32 | call to Param | test.go:185:24:185:29 | param2 | provenance | Src:MaD:2 | | test.go:185:24:185:29 | param2 | test.go:185:20:185:29 | ...+... | provenance | Config Sink:MaD:1 | -| test.go:193:9:193:26 | star expression | test.go:193:10:193:26 | selection of URL | provenance | Config | +| test.go:193:9:193:26 | star expression | test.go:193:10:193:26 | selection of URL [postupdate] | provenance | Config | | test.go:193:9:193:26 | star expression | test.go:196:21:196:23 | url | provenance | | | test.go:193:10:193:26 | selection of URL | test.go:193:9:193:26 | star expression | provenance | Src:MaD:3 Config | +| test.go:193:10:193:26 | selection of URL [postupdate] | test.go:193:9:193:26 | star expression | provenance | Config | | test.go:196:21:196:23 | url | test.go:196:21:196:32 | call to String | provenance | Config Sink:MaD:1 | models | 1 | Sink: github.com/labstack/echo; Context; true; Redirect; ; ; Argument[1]; url-redirection; manual | @@ -21,6 +22,7 @@ nodes | test.go:185:24:185:29 | param2 | semmle.label | param2 | | test.go:193:9:193:26 | star expression | semmle.label | star expression | | test.go:193:10:193:26 | selection of URL | semmle.label | selection of URL | +| test.go:193:10:193:26 | selection of URL [postupdate] | semmle.label | selection of URL [postupdate] | | test.go:196:21:196:23 | url | semmle.label | url | | test.go:196:21:196:32 | call to String | semmle.label | call to String | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected index 61b8706f4e0..4e885d284d4 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected @@ -11,7 +11,7 @@ | test.go:77:20:77:25 | buffer | test.go:72:2:72:31 | ... := ...[0] | test.go:77:20:77:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:72:2:72:31 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:83:16:83:24 | selection of Value | test.go:82:2:82:32 | ... := ...[0] | test.go:83:16:83:24 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:82:2:82:32 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:89:16:89:31 | selection of Value | test.go:88:13:88:25 | call to Cookies | test.go:89:16:89:31 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:88:13:88:25 | call to Cookies | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:100:16:100:21 | selection of s | test.go:99:11:99:15 | &... | test.go:100:16:100:21 | selection of s | Cross-site scripting vulnerability due to $@. | test.go:99:11:99:15 | &... | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:100:16:100:21 | selection of s | test.go:99:11:99:15 | &... [postupdate] | test.go:100:16:100:21 | selection of s | Cross-site scripting vulnerability due to $@. | test.go:99:11:99:15 | &... [postupdate] | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:114:16:114:42 | type assertion | test.go:113:21:113:42 | call to Param | test.go:114:16:114:42 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:113:21:113:42 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:125:16:125:20 | param | test.go:124:11:124:32 | call to Param | test.go:125:16:125:20 | param | Cross-site scripting vulnerability due to $@. | test.go:124:11:124:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:131:20:131:32 | type conversion | test.go:130:11:130:32 | call to Param | test.go:131:20:131:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:130:11:130:32 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | | @@ -29,23 +29,23 @@ edges | test.go:57:2:57:46 | ... := ...[0] | test.go:58:13:58:22 | fileHeader | provenance | Src:MaD:4 | | test.go:58:2:58:29 | ... := ...[0] | test.go:60:2:60:5 | file | provenance | | | test.go:58:13:58:22 | fileHeader | test.go:58:2:58:29 | ... := ...[0] | provenance | MaD:17 | -| test.go:59:2:59:7 | definition of buffer | test.go:61:20:61:25 | buffer | provenance | | -| test.go:60:2:60:5 | file | test.go:59:2:59:7 | definition of buffer | provenance | MaD:15 | -| test.go:60:2:60:5 | file | test.go:59:2:59:7 | definition of buffer | provenance | MaD:16 | -| test.go:60:2:60:5 | file | test.go:59:2:59:7 | definition of buffer | provenance | MaD:18 | +| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:15 | +| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:16 | +| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:18 | +| test.go:60:12:60:17 | buffer [postupdate] | test.go:61:20:61:25 | buffer | provenance | | | test.go:66:2:66:31 | ... := ...[0] | test.go:67:16:67:41 | index expression | provenance | Src:MaD:7 | | test.go:72:2:72:31 | ... := ...[0] | test.go:74:13:74:22 | fileHeader | provenance | Src:MaD:7 | | test.go:74:2:74:29 | ... := ...[0] | test.go:76:2:76:5 | file | provenance | | | test.go:74:13:74:22 | fileHeader | test.go:74:2:74:29 | ... := ...[0] | provenance | MaD:17 | -| test.go:75:2:75:7 | definition of buffer | test.go:77:20:77:25 | buffer | provenance | | -| test.go:76:2:76:5 | file | test.go:75:2:75:7 | definition of buffer | provenance | MaD:15 | -| test.go:76:2:76:5 | file | test.go:75:2:75:7 | definition of buffer | provenance | MaD:16 | -| test.go:76:2:76:5 | file | test.go:75:2:75:7 | definition of buffer | provenance | MaD:18 | +| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:15 | +| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:16 | +| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:18 | +| test.go:76:12:76:17 | buffer [postupdate] | test.go:77:20:77:25 | buffer | provenance | | | test.go:82:2:82:32 | ... := ...[0] | test.go:83:16:83:24 | selection of Value | provenance | Src:MaD:2 | | test.go:88:13:88:25 | call to Cookies | test.go:89:16:89:31 | selection of Value | provenance | Src:MaD:3 | -| test.go:99:11:99:15 | &... | test.go:100:16:100:21 | selection of s | provenance | Src:MaD:1 | -| test.go:112:17:112:19 | definition of ctx | test.go:114:16:114:18 | ctx | provenance | | -| test.go:113:21:113:42 | call to Param | test.go:112:17:112:19 | definition of ctx | provenance | Src:MaD:8 MaD:14 | +| test.go:99:11:99:15 | &... [postupdate] | test.go:100:16:100:21 | selection of s | provenance | Src:MaD:1 | +| test.go:113:2:113:4 | ctx [postupdate] | test.go:114:16:114:18 | ctx | provenance | | +| test.go:113:21:113:42 | call to Param | test.go:113:2:113:4 | ctx [postupdate] | provenance | Src:MaD:8 MaD:14 | | test.go:114:16:114:18 | ctx | test.go:114:16:114:33 | call to Get | provenance | MaD:13 | | test.go:114:16:114:33 | call to Get | test.go:114:16:114:42 | type assertion | provenance | | | test.go:124:11:124:32 | call to Param | test.go:125:16:125:20 | param | provenance | Src:MaD:8 | @@ -93,24 +93,24 @@ nodes | test.go:57:2:57:46 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:58:2:58:29 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:58:13:58:22 | fileHeader | semmle.label | fileHeader | -| test.go:59:2:59:7 | definition of buffer | semmle.label | definition of buffer | | test.go:60:2:60:5 | file | semmle.label | file | +| test.go:60:12:60:17 | buffer [postupdate] | semmle.label | buffer [postupdate] | | test.go:61:20:61:25 | buffer | semmle.label | buffer | | test.go:66:2:66:31 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:67:16:67:41 | index expression | semmle.label | index expression | | test.go:72:2:72:31 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:74:2:74:29 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:74:13:74:22 | fileHeader | semmle.label | fileHeader | -| test.go:75:2:75:7 | definition of buffer | semmle.label | definition of buffer | | test.go:76:2:76:5 | file | semmle.label | file | +| test.go:76:12:76:17 | buffer [postupdate] | semmle.label | buffer [postupdate] | | test.go:77:20:77:25 | buffer | semmle.label | buffer | | test.go:82:2:82:32 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:83:16:83:24 | selection of Value | semmle.label | selection of Value | | test.go:88:13:88:25 | call to Cookies | semmle.label | call to Cookies | | test.go:89:16:89:31 | selection of Value | semmle.label | selection of Value | -| test.go:99:11:99:15 | &... | semmle.label | &... | +| test.go:99:11:99:15 | &... [postupdate] | semmle.label | &... [postupdate] | | test.go:100:16:100:21 | selection of s | semmle.label | selection of s | -| test.go:112:17:112:19 | definition of ctx | semmle.label | definition of ctx | +| test.go:113:2:113:4 | ctx [postupdate] | semmle.label | ctx [postupdate] | | test.go:113:21:113:42 | call to Param | semmle.label | call to Param | | test.go:114:16:114:18 | ctx | semmle.label | ctx | | test.go:114:16:114:33 | call to Get | semmle.label | call to Get | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.expected b/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.expected index 0e79c3135b0..5dfd597c10a 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Encoding/jsoniter.expected @@ -9,28 +9,28 @@ edges | jsoniter.go:23:20:23:38 | call to getUntrustedBytes | jsoniter.go:31:21:31:34 | untrustedInput | provenance | | | jsoniter.go:24:21:24:40 | call to getUntrustedString | jsoniter.go:35:27:35:41 | untrustedString | provenance | | | jsoniter.go:24:21:24:40 | call to getUntrustedString | jsoniter.go:39:31:39:45 | untrustedString | provenance | | -| jsoniter.go:27:17:27:30 | untrustedInput | jsoniter.go:27:33:27:37 | &... | provenance | MaD:4 | -| jsoniter.go:27:33:27:37 | &... | jsoniter.go:28:15:28:24 | selection of field | provenance | Sink:MaD:1 | -| jsoniter.go:31:21:31:34 | untrustedInput | jsoniter.go:31:37:31:42 | &... | provenance | MaD:2 | -| jsoniter.go:31:37:31:42 | &... | jsoniter.go:32:15:32:25 | selection of field | provenance | Sink:MaD:1 | -| jsoniter.go:35:27:35:41 | untrustedString | jsoniter.go:35:44:35:49 | &... | provenance | MaD:5 | -| jsoniter.go:35:44:35:49 | &... | jsoniter.go:36:15:36:25 | selection of field | provenance | Sink:MaD:1 | -| jsoniter.go:39:31:39:45 | untrustedString | jsoniter.go:39:48:39:53 | &... | provenance | MaD:3 | -| jsoniter.go:39:48:39:53 | &... | jsoniter.go:40:15:40:25 | selection of field | provenance | Sink:MaD:1 | +| jsoniter.go:27:17:27:30 | untrustedInput | jsoniter.go:27:33:27:37 | &... [postupdate] | provenance | MaD:4 | +| jsoniter.go:27:33:27:37 | &... [postupdate] | jsoniter.go:28:15:28:24 | selection of field | provenance | Sink:MaD:1 | +| jsoniter.go:31:21:31:34 | untrustedInput | jsoniter.go:31:37:31:42 | &... [postupdate] | provenance | MaD:2 | +| jsoniter.go:31:37:31:42 | &... [postupdate] | jsoniter.go:32:15:32:25 | selection of field | provenance | Sink:MaD:1 | +| jsoniter.go:35:27:35:41 | untrustedString | jsoniter.go:35:44:35:49 | &... [postupdate] | provenance | MaD:5 | +| jsoniter.go:35:44:35:49 | &... [postupdate] | jsoniter.go:36:15:36:25 | selection of field | provenance | Sink:MaD:1 | +| jsoniter.go:39:31:39:45 | untrustedString | jsoniter.go:39:48:39:53 | &... [postupdate] | provenance | MaD:3 | +| jsoniter.go:39:48:39:53 | &... [postupdate] | jsoniter.go:40:15:40:25 | selection of field | provenance | Sink:MaD:1 | nodes | jsoniter.go:23:20:23:38 | call to getUntrustedBytes | semmle.label | call to getUntrustedBytes | | jsoniter.go:24:21:24:40 | call to getUntrustedString | semmle.label | call to getUntrustedString | | jsoniter.go:27:17:27:30 | untrustedInput | semmle.label | untrustedInput | -| jsoniter.go:27:33:27:37 | &... | semmle.label | &... | +| jsoniter.go:27:33:27:37 | &... [postupdate] | semmle.label | &... [postupdate] | | jsoniter.go:28:15:28:24 | selection of field | semmle.label | selection of field | | jsoniter.go:31:21:31:34 | untrustedInput | semmle.label | untrustedInput | -| jsoniter.go:31:37:31:42 | &... | semmle.label | &... | +| jsoniter.go:31:37:31:42 | &... [postupdate] | semmle.label | &... [postupdate] | | jsoniter.go:32:15:32:25 | selection of field | semmle.label | selection of field | | jsoniter.go:35:27:35:41 | untrustedString | semmle.label | untrustedString | -| jsoniter.go:35:44:35:49 | &... | semmle.label | &... | +| jsoniter.go:35:44:35:49 | &... [postupdate] | semmle.label | &... [postupdate] | | jsoniter.go:36:15:36:25 | selection of field | semmle.label | selection of field | | jsoniter.go:39:31:39:45 | untrustedString | semmle.label | untrustedString | -| jsoniter.go:39:48:39:53 | &... | semmle.label | &... | +| jsoniter.go:39:48:39:53 | &... [postupdate] | semmle.label | &... [postupdate] | | jsoniter.go:40:15:40:25 | selection of field | semmle.label | selection of field | subpaths invalidModelRow diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Gin/Gin.expected b/go/ql/test/library-tests/semmle/go/frameworks/Gin/Gin.expected index 719a6a26147..071bf34cd7e 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Gin/Gin.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Gin/Gin.expected @@ -31,39 +31,39 @@ | Gin.go:158:10:158:19 | selection of Params | | Gin.go:162:13:162:22 | selection of Params | | Gin.go:168:12:168:21 | selection of Params | -| Gin.go:178:16:178:22 | &... | -| Gin.go:182:7:182:19 | definition of personPointer | -| Gin.go:188:15:188:21 | &... | -| Gin.go:192:7:192:19 | definition of personPointer | -| Gin.go:198:16:198:22 | &... | -| Gin.go:202:7:202:19 | definition of personPointer | -| Gin.go:208:15:208:21 | &... | -| Gin.go:212:7:212:19 | definition of personPointer | -| Gin.go:218:17:218:23 | &... | -| Gin.go:222:7:222:19 | definition of personPointer | -| Gin.go:228:20:228:26 | &... | -| Gin.go:232:7:232:19 | definition of personPointer | -| Gin.go:238:16:238:22 | &... | -| Gin.go:242:7:242:19 | definition of personPointer | -| Gin.go:248:12:248:18 | &... | -| Gin.go:252:7:252:19 | definition of personPointer | -| Gin.go:258:18:258:24 | &... | -| Gin.go:262:7:262:19 | definition of personPointer | -| Gin.go:268:26:268:32 | &... | -| Gin.go:272:7:272:19 | definition of personPointer | -| Gin.go:278:22:278:28 | &... | -| Gin.go:282:7:282:19 | definition of personPointer | -| Gin.go:288:23:288:29 | &... | -| Gin.go:292:7:292:19 | definition of personPointer | -| Gin.go:298:21:298:27 | &... | -| Gin.go:302:7:302:19 | definition of personPointer | -| Gin.go:308:22:308:28 | &... | -| Gin.go:312:7:312:19 | definition of personPointer | -| Gin.go:318:21:318:27 | &... | -| Gin.go:322:7:322:19 | definition of personPointer | -| Gin.go:328:22:328:28 | &... | -| Gin.go:332:7:332:19 | definition of personPointer | -| Gin.go:338:18:338:24 | &... | -| Gin.go:342:7:342:19 | definition of personPointer | -| Gin.go:348:24:348:30 | &... | -| Gin.go:352:7:352:19 | definition of personPointer | +| Gin.go:178:16:178:22 | &... [postupdate] | +| Gin.go:183:16:183:28 | personPointer [postupdate] | +| Gin.go:188:15:188:21 | &... [postupdate] | +| Gin.go:193:15:193:27 | personPointer [postupdate] | +| Gin.go:198:16:198:22 | &... [postupdate] | +| Gin.go:203:16:203:28 | personPointer [postupdate] | +| Gin.go:208:15:208:21 | &... [postupdate] | +| Gin.go:213:15:213:27 | personPointer [postupdate] | +| Gin.go:218:17:218:23 | &... [postupdate] | +| Gin.go:223:17:223:29 | personPointer [postupdate] | +| Gin.go:228:20:228:26 | &... [postupdate] | +| Gin.go:233:20:233:32 | personPointer [postupdate] | +| Gin.go:238:16:238:22 | &... [postupdate] | +| Gin.go:243:16:243:28 | personPointer [postupdate] | +| Gin.go:248:12:248:18 | &... [postupdate] | +| Gin.go:253:12:253:24 | personPointer [postupdate] | +| Gin.go:258:18:258:24 | &... [postupdate] | +| Gin.go:263:18:263:30 | personPointer [postupdate] | +| Gin.go:268:26:268:32 | &... [postupdate] | +| Gin.go:273:26:273:38 | personPointer [postupdate] | +| Gin.go:278:22:278:28 | &... [postupdate] | +| Gin.go:283:22:283:34 | personPointer [postupdate] | +| Gin.go:288:23:288:29 | &... [postupdate] | +| Gin.go:293:23:293:35 | personPointer [postupdate] | +| Gin.go:298:21:298:27 | &... [postupdate] | +| Gin.go:303:21:303:33 | personPointer [postupdate] | +| Gin.go:308:22:308:28 | &... [postupdate] | +| Gin.go:313:22:313:34 | personPointer [postupdate] | +| Gin.go:318:21:318:27 | &... [postupdate] | +| Gin.go:323:21:323:33 | personPointer [postupdate] | +| Gin.go:328:22:328:28 | &... [postupdate] | +| Gin.go:333:22:333:34 | personPointer [postupdate] | +| Gin.go:338:18:338:24 | &... [postupdate] | +| Gin.go:343:18:343:30 | personPointer [postupdate] | +| Gin.go:348:24:348:30 | &... [postupdate] | +| Gin.go:353:24:353:36 | personPointer [postupdate] | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Gorestful/gorestful.expected b/go/ql/test/library-tests/semmle/go/frameworks/Gorestful/gorestful.expected index 4cdacabe873..0af67462f7c 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Gorestful/gorestful.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Gorestful/gorestful.expected @@ -8,11 +8,11 @@ edges | gorestful.go:15:15:15:44 | call to QueryParameters | gorestful.go:15:15:15:47 | index expression | provenance | Src:MaD:4 Sink:MaD:1 | | gorestful.go:17:2:17:39 | ... := ...[0] | gorestful.go:18:15:18:17 | val | provenance | Src:MaD:2 Sink:MaD:1 | | gorestful.go:21:15:21:38 | call to PathParameters | gorestful.go:21:15:21:45 | index expression | provenance | Src:MaD:3 Sink:MaD:1 | -| gorestful.go:23:21:23:24 | &... | gorestful.go:24:15:24:21 | selection of cmd | provenance | Src:MaD:5 Sink:MaD:1 | +| gorestful.go:23:21:23:24 | &... [postupdate] | gorestful.go:24:15:24:21 | selection of cmd | provenance | Src:MaD:5 Sink:MaD:1 | | gorestful_v2.go:15:15:15:44 | call to QueryParameters | gorestful_v2.go:15:15:15:47 | index expression | provenance | Src:MaD:4 Sink:MaD:1 | | gorestful_v2.go:17:2:17:39 | ... := ...[0] | gorestful_v2.go:18:15:18:17 | val | provenance | Src:MaD:2 Sink:MaD:1 | | gorestful_v2.go:21:15:21:38 | call to PathParameters | gorestful_v2.go:21:15:21:45 | index expression | provenance | Src:MaD:3 Sink:MaD:1 | -| gorestful_v2.go:23:21:23:24 | &... | gorestful_v2.go:24:15:24:21 | selection of cmd | provenance | Src:MaD:5 Sink:MaD:1 | +| gorestful_v2.go:23:21:23:24 | &... [postupdate] | gorestful_v2.go:24:15:24:21 | selection of cmd | provenance | Src:MaD:5 Sink:MaD:1 | nodes | gorestful.go:15:15:15:44 | call to QueryParameters | semmle.label | call to QueryParameters | | gorestful.go:15:15:15:47 | index expression | semmle.label | index expression | @@ -23,7 +23,7 @@ nodes | gorestful.go:20:15:20:42 | call to PathParameter | semmle.label | call to PathParameter | | gorestful.go:21:15:21:38 | call to PathParameters | semmle.label | call to PathParameters | | gorestful.go:21:15:21:45 | index expression | semmle.label | index expression | -| gorestful.go:23:21:23:24 | &... | semmle.label | &... | +| gorestful.go:23:21:23:24 | &... [postupdate] | semmle.label | &... [postupdate] | | gorestful.go:24:15:24:21 | selection of cmd | semmle.label | selection of cmd | | gorestful_v2.go:15:15:15:44 | call to QueryParameters | semmle.label | call to QueryParameters | | gorestful_v2.go:15:15:15:47 | index expression | semmle.label | index expression | @@ -34,7 +34,7 @@ nodes | gorestful_v2.go:20:15:20:42 | call to PathParameter | semmle.label | call to PathParameter | | gorestful_v2.go:21:15:21:38 | call to PathParameters | semmle.label | call to PathParameters | | gorestful_v2.go:21:15:21:45 | index expression | semmle.label | index expression | -| gorestful_v2.go:23:21:23:24 | &... | semmle.label | &... | +| gorestful_v2.go:23:21:23:24 | &... [postupdate] | semmle.label | &... [postupdate] | | gorestful_v2.go:24:15:24:21 | selection of cmd | semmle.label | selection of cmd | subpaths invalidModelRow @@ -45,11 +45,11 @@ invalidModelRow | gorestful.go:19:15:19:44 | call to HeaderParameter | gorestful.go:19:15:19:44 | call to HeaderParameter | gorestful.go:19:15:19:44 | call to HeaderParameter | This command depends on $@. | gorestful.go:19:15:19:44 | call to HeaderParameter | a user-provided value | | gorestful.go:20:15:20:42 | call to PathParameter | gorestful.go:20:15:20:42 | call to PathParameter | gorestful.go:20:15:20:42 | call to PathParameter | This command depends on $@. | gorestful.go:20:15:20:42 | call to PathParameter | a user-provided value | | gorestful.go:21:15:21:45 | index expression | gorestful.go:21:15:21:38 | call to PathParameters | gorestful.go:21:15:21:45 | index expression | This command depends on $@. | gorestful.go:21:15:21:38 | call to PathParameters | a user-provided value | -| gorestful.go:24:15:24:21 | selection of cmd | gorestful.go:23:21:23:24 | &... | gorestful.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful.go:23:21:23:24 | &... | a user-provided value | +| gorestful.go:24:15:24:21 | selection of cmd | gorestful.go:23:21:23:24 | &... [postupdate] | gorestful.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful.go:23:21:23:24 | &... [postupdate] | a user-provided value | | gorestful_v2.go:15:15:15:47 | index expression | gorestful_v2.go:15:15:15:44 | call to QueryParameters | gorestful_v2.go:15:15:15:47 | index expression | This command depends on $@. | gorestful_v2.go:15:15:15:44 | call to QueryParameters | a user-provided value | | gorestful_v2.go:16:15:16:43 | call to QueryParameter | gorestful_v2.go:16:15:16:43 | call to QueryParameter | gorestful_v2.go:16:15:16:43 | call to QueryParameter | This command depends on $@. | gorestful_v2.go:16:15:16:43 | call to QueryParameter | a user-provided value | | gorestful_v2.go:18:15:18:17 | val | gorestful_v2.go:17:2:17:39 | ... := ...[0] | gorestful_v2.go:18:15:18:17 | val | This command depends on $@. | gorestful_v2.go:17:2:17:39 | ... := ...[0] | a user-provided value | | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | This command depends on $@. | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | a user-provided value | | gorestful_v2.go:20:15:20:42 | call to PathParameter | gorestful_v2.go:20:15:20:42 | call to PathParameter | gorestful_v2.go:20:15:20:42 | call to PathParameter | This command depends on $@. | gorestful_v2.go:20:15:20:42 | call to PathParameter | a user-provided value | | gorestful_v2.go:21:15:21:45 | index expression | gorestful_v2.go:21:15:21:38 | call to PathParameters | gorestful_v2.go:21:15:21:45 | index expression | This command depends on $@. | gorestful_v2.go:21:15:21:38 | call to PathParameters | a user-provided value | -| gorestful_v2.go:24:15:24:21 | selection of cmd | gorestful_v2.go:23:21:23:24 | &... | gorestful_v2.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful_v2.go:23:21:23:24 | &... | a user-provided value | +| gorestful_v2.go:24:15:24:21 | selection of cmd | gorestful_v2.go:23:21:23:24 | &... [postupdate] | gorestful_v2.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful_v2.go:23:21:23:24 | &... [postupdate] | a user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected index 6e20fd5699c..d3f52f4f9c6 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected @@ -1,10 +1,11 @@ #select | EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value | edges -| EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:27 | selection of Params | provenance | Config | +| EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | provenance | Config | | EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Config | | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:27 | implicit dereference | provenance | Src:MaD:2 Config | | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Src:MaD:2 Config | +| EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | EndToEnd.go:94:20:94:27 | implicit dereference | provenance | Config | | EndToEnd.go:94:20:94:32 | selection of Form | EndToEnd.go:94:20:94:49 | call to Get | provenance | Config Sink:MaD:1 | models | 1 | Sink: group:revel; Controller; true; Redirect; ; ; Argument[0]; url-redirection; manual | @@ -12,6 +13,7 @@ models nodes | EndToEnd.go:94:20:94:27 | implicit dereference | semmle.label | implicit dereference | | EndToEnd.go:94:20:94:27 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | semmle.label | selection of Params [postupdate] | | EndToEnd.go:94:20:94:32 | selection of Form | semmle.label | selection of Form | | EndToEnd.go:94:20:94:49 | call to Get | semmle.label | call to Get | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected index 9d45f1e2996..9ea4016a7e4 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected @@ -5,10 +5,10 @@ | examples/booking/app/init.go:36:44:36:53 | selection of Path | examples/booking/app/init.go:36:44:36:48 | selection of URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:36:44:36:48 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | | | examples/booking/app/init.go:40:49:40:58 | selection of Path | examples/booking/app/init.go:40:49:40:53 | selection of URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:40:49:40:53 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | | edges -| EndToEnd.go:35:2:35:4 | definition of buf | EndToEnd.go:37:24:37:26 | buf | provenance | | +| EndToEnd.go:36:2:36:4 | buf [postupdate] | EndToEnd.go:37:24:37:26 | buf | provenance | | | EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:36:18:36:30 | selection of Form | provenance | Src:MaD:1 | | EndToEnd.go:36:18:36:30 | selection of Form | EndToEnd.go:36:18:36:47 | call to Get | provenance | MaD:4 | -| EndToEnd.go:36:18:36:47 | call to Get | EndToEnd.go:35:2:35:4 | definition of buf | provenance | MaD:3 | +| EndToEnd.go:36:18:36:47 | call to Get | EndToEnd.go:36:2:36:4 | buf [postupdate] | provenance | MaD:3 | | EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:34 | selection of Form | provenance | Src:MaD:1 | | EndToEnd.go:69:22:69:34 | selection of Form | EndToEnd.go:69:22:69:51 | call to Get | provenance | MaD:4 | | Revel.go:70:22:70:29 | selection of Params | Revel.go:70:22:70:35 | selection of Query | provenance | Src:MaD:1 | @@ -20,7 +20,7 @@ models | 3 | Summary: io; StringWriter; true; WriteString; ; ; Argument[0]; Argument[receiver]; taint; manual | | 4 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | nodes -| EndToEnd.go:35:2:35:4 | definition of buf | semmle.label | definition of buf | +| EndToEnd.go:36:2:36:4 | buf [postupdate] | semmle.label | buf [postupdate] | | EndToEnd.go:36:18:36:25 | selection of Params | semmle.label | selection of Params | | EndToEnd.go:36:18:36:30 | selection of Form | semmle.label | selection of Form | | EndToEnd.go:36:18:36:47 | call to Get | semmle.label | call to Get | 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 b7c6f703cf5..8209afc7b50 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 @@ -8,64 +8,76 @@ invalidModelRow | crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | ... := ...[1] | | crypto.go:11:42:11:51 | ciphertext | crypto.go:11:2:11:57 | ... := ...[0] | | 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:23:16:27 | &... | io.go:15:7:15:10 | definition of buf1 | +| io.go:16:3:16:3 | definition of w | io.go:16:23:16:27 | &... [postupdate] | +| io.go:16:3:16:3 | definition of w | io.go:16:30:16:34 | &... [postupdate] | +| io.go:16:23:16:27 | &... | io.go:16:24:16:27 | buf1 [postupdate] | +| io.go:16:23:16:27 | &... [postupdate] | io.go:16:24:16:27 | buf1 [postupdate] | | 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:24:16:27 | buf1 [postupdate] | io.go:16:23:16:27 | &... | +| io.go:16:30:16:34 | &... | io.go:16:31:16:34 | buf2 [postupdate] | +| io.go:16:30:16:34 | &... [postupdate] | io.go:16:31:16:34 | buf2 [postupdate] | | 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:16:31:16:34 | buf2 [postupdate] | io.go:16:30:16:34 | &... | +| io.go:18:14:18:19 | reader | io.go:18:11:18:11 | w [postupdate] | | io.go:22:31:22:43 | "some string" | io.go:22:13:22:44 | call to NewReader | -| io.go:25:19:25:23 | &... | io.go:23:7:23:10 | definition of buf1 | +| io.go:25:19:25:23 | &... | io.go:25:20:25:23 | buf1 [postupdate] | +| io.go:25:19:25:23 | &... [postupdate] | io.go:25:20:25:23 | buf1 [postupdate] | | io.go:25:20:25:23 | buf1 | io.go:25:19:25:23 | &... | -| io.go:27:21:27:26 | reader | io.go:25:3:25:4 | definition of w2 | +| io.go:25:20:25:23 | buf1 [postupdate] | io.go:25:19:25:23 | &... | +| io.go:27:21:27:26 | reader | io.go:27:17:27:18 | w2 [postupdate] | | io.go:31:31:31:43 | "some string" | io.go:31:13:31:44 | call to NewReader | -| io.go:33:19:33:23 | &... | io.go:32:7:32:10 | definition of buf1 | +| io.go:33:19:33:23 | &... | io.go:33:20:33:23 | buf1 [postupdate] | +| io.go:33:19:33:23 | &... [postupdate] | io.go:33:20:33:23 | buf1 [postupdate] | | io.go:33:20:33:23 | buf1 | io.go:33:19:33:23 | &... | -| io.go:35:16:35:21 | reader | io.go:33:3:33:4 | definition of w2 | +| io.go:33:20:33:23 | buf1 [postupdate] | io.go:33:19:33:23 | &... | +| io.go:35:16:35:21 | reader | io.go:35:12:35:13 | w2 [postupdate] | | io.go:39:6:39:6 | definition of w | io.go:39:3:39:19 | ... := ...[0] | | 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:43:16:43:16 | r | io.go:42:3:42:5 | definition of buf | +| io.go:40:17:40:31 | "some string\\n" | io.go:40:14:40:14 | w [postupdate] | +| io.go:43:16:43:16 | r | io.go:43:3:43:5 | buf [postupdate] | | io.go:44:13:44:15 | buf | io.go:44:13:44:24 | call to String | | 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:50:18:50:23 | reader | io.go:50:26:50:28 | buf [postupdate] | | io.go:54:31:54:43 | "some string" | io.go:54:13:54:44 | call to NewReader | -| io.go:56:15:56:20 | reader | io.go:55:3:55:5 | definition of buf | -| io.go:61:18:61:21 | &... | io.go:60:7:60:9 | definition of buf | +| io.go:56:15:56:20 | reader | io.go:56:23:56:25 | buf [postupdate] | +| io.go:61:18:61:21 | &... | io.go:61:19:61:21 | buf [postupdate] | +| io.go:61:18:61:21 | &... [postupdate] | io.go:61:19:61:21 | buf [postupdate] | | io.go:61:19:61:21 | buf | io.go:61:18:61:21 | &... | -| io.go:62:21:62:26 | "test" | io.go:61:3:61:3 | definition of w | +| io.go:61:19:61:21 | buf [postupdate] | io.go:61:18:61:21 | &... | +| io.go:62:21:62:26 | "test" | io.go:62:18:62:18 | w [postupdate] | | io.go:65:31:65:43 | "some string" | io.go:65:13:65:44 | call to NewReader | -| io.go:67:3:67:8 | reader | io.go:66:3:66:5 | definition of buf | +| io.go:67:3:67:8 | reader | io.go:67:15:67:17 | buf [postupdate] | | io.go:70:31:70:43 | "some string" | io.go:70:13:70:44 | call to NewReader | -| io.go:72:3:72:8 | reader | io.go:71:3:71:5 | definition of buf | +| io.go:72:3:72:8 | reader | io.go:72:17:72:19 | buf [postupdate] | | io.go:76:31:76:43 | "some string" | io.go:76:13:76:44 | call to NewReader | | io.go:77:24:77:29 | reader | io.go:77:9:77:33 | call to LimitReader | -| io.go:78:22:78:23 | lr | io.go:78:11:78:19 | selection of Stdout | +| io.go:78:22:78:23 | lr | io.go:78:11:78:19 | selection of Stdout [postupdate] | | 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: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 | call to MultiReader | | 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:86:22:86:22 | r | io.go:86:11:86:19 | selection of Stdout [postupdate] | | io.go:89:26:89:38 | "some string" | io.go:89:8:89:39 | call to NewReader | | io.go:91:23:91:23 | r | io.go:91:10:91:30 | call to TeeReader | -| io.go:91:23:91:23 | r | io.go:91:26:91:29 | &... | -| io.go:91:26:91:29 | &... | io.go:90:7:90:9 | definition of buf | +| io.go:91:23:91:23 | r | io.go:91:26:91:29 | &... [postupdate] | +| io.go:91:26:91:29 | &... | io.go:91:27:91:29 | buf [postupdate] | +| io.go:91:26:91:29 | &... [postupdate] | io.go:91:27:91:29 | buf [postupdate] | | io.go:91:27:91:29 | buf | io.go:91:26:91:29 | &... | -| io.go:93:22:93:24 | tee | io.go:93:11:93:19 | selection of Stdout | +| io.go:91:27:91:29 | buf [postupdate] | io.go:91:26:91:29 | &... | +| io.go:93:22:93:24 | tee | io.go:93:11:93:19 | selection of Stdout [postupdate] | | io.go:96:26:96:38 | "some string" | io.go:96:8:96:39 | call to NewReader | | io.go:97:28:97:28 | r | io.go:97:8:97:36 | call to NewSectionReader | -| io.go:98:22:98:22 | s | io.go:98:11:98:19 | selection of Stdout | +| io.go:98:22:98:22 | s | io.go:98:11:98:19 | selection of Stdout [postupdate] | | io.go:101:26:101:38 | "some string" | io.go:101:8:101:39 | call to NewReader | -| io.go:102:3:102:3 | r | io.go:102:13:102:21 | selection of Stdout | +| io.go:102:3:102:3 | r | io.go:102:13:102:21 | selection of Stdout [postupdate] | | io.go:108:30:108:42 | "some string" | io.go:108:12:108:43 | call to NewReader | | io.go:109:12:109:33 | call to ReadAll | io.go:109:2:109:33 | ... := ...[0] | | io.go:109:12:109:33 | call to ReadAll | io.go:109:2:109:33 | ... := ...[1] | | io.go:109:27:109:32 | reader | io.go:109:2:109:33 | ... := ...[0] | -| io.go:110:18:110:20 | buf | io.go:110:2:110:10 | selection of Stdout | +| io.go:110:18:110:20 | buf | io.go:110:2:110:10 | selection of Stdout [postupdate] | | main.go:11:12:11:26 | call to Marshal | main.go:11:2:11:26 | ... := ...[0] | | main.go:11:12:11:26 | call to Marshal | main.go:11:2:11:26 | ... := ...[1] | | main.go:11:25:11:25 | v | main.go:11:2:11:26 | ... := ...[0] | @@ -74,21 +86,23 @@ invalidModelRow | main.go:13:33:13:33 | v | main.go:13:2:13:52 | ... := ...[0] | | main.go:13:36:13:45 | "/*JSON*/" | main.go:13:2:13:52 | ... := ...[0] | | main.go:13:48:13:51 | " " | main.go:13:2:13:52 | ... := ...[0] | -| main.go:14:25:14:25 | b | main.go:14:9:14:41 | slice literal | -| main.go:14:28:14:30 | err | main.go:14:9:14:41 | slice literal | -| main.go:14:33:14:34 | b2 | main.go:14:9:14:41 | slice literal | -| main.go:14:37:14:40 | err2 | main.go:14:9:14:41 | slice literal | +| main.go:14:25:14:25 | b | main.go:14:9:14:41 | slice literal [postupdate] | +| main.go:14:28:14:30 | err | main.go:14:9:14:41 | slice literal [postupdate] | +| main.go:14:33:14:34 | b2 | main.go:14:9:14:41 | slice literal [postupdate] | +| main.go:14:37:14:40 | err2 | main.go:14:9:14:41 | slice literal [postupdate] | | main.go:19:18:19:42 | call to DecodeString | main.go:19:2:19:42 | ... := ...[0] | | main.go:19:18:19:42 | call to DecodeString | main.go:19:2:19:42 | ... := ...[1] | | main.go:19:35:19:41 | encoded | main.go:19:2:19:42 | ... := ...[0] | -| main.go:23:25:23:31 | decoded | main.go:23:9:23:48 | slice literal | -| main.go:23:34:23:36 | err | main.go:23:9:23:48 | slice literal | -| main.go:23:39:23:47 | reEncoded | main.go:23:9:23:48 | slice literal | -| main.go:28:2:28:4 | implicit dereference | main.go:26:15:26:17 | definition of req | +| main.go:23:25:23:31 | decoded | main.go:23:9:23:48 | slice literal [postupdate] | +| main.go:23:34:23:36 | err | main.go:23:9:23:48 | slice literal [postupdate] | +| main.go:23:39:23:47 | reEncoded | main.go:23:9:23:48 | slice literal [postupdate] | +| main.go:28:2:28:4 | implicit dereference | main.go:28:2:28:4 | req [postupdate] | | main.go:28:2:28:4 | implicit dereference | main.go:28:2:28:9 | selection of Body | | main.go:28:2:28:4 | req | main.go:28:2:28:4 | implicit dereference | -| main.go:28:2:28:9 | selection of Body | main.go:27:2:27:2 | definition of b | -| main.go:34:2:34:4 | implicit dereference | main.go:32:16:32:18 | definition of req | +| main.go:28:2:28:4 | req [postupdate] | main.go:28:2:28:4 | implicit dereference | +| main.go:28:2:28:9 | selection of Body | main.go:28:16:28:16 | b [postupdate] | +| main.go:34:2:34:4 | implicit dereference | main.go:34:2:34:4 | req [postupdate] | | main.go:34:2:34:4 | implicit dereference | main.go:34:2:34:9 | selection of Body | | main.go:34:2:34:4 | req | main.go:34:2:34:4 | implicit dereference | -| main.go:34:2:34:9 | selection of Body | main.go:33:2:33:2 | definition of b | +| main.go:34:2:34:4 | req [postupdate] | main.go:34:2:34:4 | implicit dereference | +| main.go:34:2:34:9 | selection of Body | main.go:34:16:34:16 | b [postupdate] | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/WebSocket/Read.expected b/go/ql/test/library-tests/semmle/go/frameworks/WebSocket/Read.expected index 4bfef26418a..4c4bd0743d2 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/WebSocket/Read.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/WebSocket/Read.expected @@ -1,8 +1,8 @@ -| WebSocketReadWrite.go:31:7:31:10 | definition of xnet | -| WebSocketReadWrite.go:35:3:35:7 | definition of xnet2 | +| WebSocketReadWrite.go:32:11:32:14 | xnet [postupdate] | +| WebSocketReadWrite.go:36:21:36:25 | xnet2 [postupdate] | | WebSocketReadWrite.go:41:3:41:40 | ... := ...[1] | | WebSocketReadWrite.go:44:3:44:48 | ... := ...[1] | -| WebSocketReadWrite.go:51:7:51:16 | definition of gorillaMsg | -| WebSocketReadWrite.go:55:3:55:10 | definition of gorilla2 | +| WebSocketReadWrite.go:52:26:52:35 | gorillaMsg [postupdate] | +| WebSocketReadWrite.go:56:17:56:24 | gorilla2 [postupdate] | | WebSocketReadWrite.go:61:3:61:38 | ... := ...[1] | | WebSocketReadWrite.go:67:3:67:36 | ... := ...[0] | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/WebSocket/RemoteFlowSources.expected b/go/ql/test/library-tests/semmle/go/frameworks/WebSocket/RemoteFlowSources.expected index 0124cf73218..e0c1603ff2e 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/WebSocket/RemoteFlowSources.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/WebSocket/RemoteFlowSources.expected @@ -1,9 +1,9 @@ | WebSocketReadWrite.go:27:9:27:16 | selection of Header | -| WebSocketReadWrite.go:31:7:31:10 | definition of xnet | -| WebSocketReadWrite.go:35:3:35:7 | definition of xnet2 | +| WebSocketReadWrite.go:32:11:32:14 | xnet [postupdate] | +| WebSocketReadWrite.go:36:21:36:25 | xnet2 [postupdate] | | WebSocketReadWrite.go:41:3:41:40 | ... := ...[1] | | WebSocketReadWrite.go:44:3:44:48 | ... := ...[1] | -| WebSocketReadWrite.go:51:7:51:16 | definition of gorillaMsg | -| WebSocketReadWrite.go:55:3:55:10 | definition of gorilla2 | +| WebSocketReadWrite.go:52:26:52:35 | gorillaMsg [postupdate] | +| WebSocketReadWrite.go:56:17:56:24 | gorilla2 [postupdate] | | WebSocketReadWrite.go:61:3:61:38 | ... := ...[1] | | WebSocketReadWrite.go:67:3:67:36 | ... := ...[0] | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected index b94733d5054..17c74de5555 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected @@ -44,28 +44,20 @@ edges | test.go:39:23:39:77 | call to NewTokenizerFragment | test.go:40:15:40:31 | tokenizerFragment | provenance | | | test.go:39:49:39:60 | selection of Body | test.go:39:23:39:77 | call to NewTokenizerFragment | provenance | Src:MaD:1 MaD:4 | | test.go:40:15:40:31 | tokenizerFragment | test.go:40:15:40:42 | call to Buffered | provenance | MaD:12 | -| test.go:42:6:42:14 | definition of cleanNode | test.go:45:22:45:31 | &... | provenance | | -| test.go:42:6:42:14 | definition of cleanNode | test.go:45:22:45:31 | &... | provenance | | -| test.go:42:6:42:14 | definition of cleanNode | test.go:45:23:45:31 | cleanNode | provenance | | | test.go:43:2:43:43 | ... := ...[0] | test.go:44:24:44:34 | taintedNode | provenance | | | test.go:43:31:43:42 | selection of Body | test.go:43:2:43:43 | ... := ...[0] | provenance | Src:MaD:1 MaD:5 | -| test.go:44:24:44:34 | taintedNode | test.go:42:6:42:14 | definition of cleanNode | provenance | MaD:10 | -| test.go:45:22:45:31 | &... | test.go:45:23:45:31 | cleanNode | provenance | | +| test.go:44:2:44:10 | cleanNode [postupdate] | test.go:45:22:45:31 | &... | provenance | | +| test.go:44:2:44:10 | cleanNode [postupdate] | test.go:45:23:45:31 | cleanNode | provenance | | +| test.go:44:24:44:34 | taintedNode | test.go:44:2:44:10 | cleanNode [postupdate] | provenance | MaD:10 | | test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | provenance | | -| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | provenance | | -| test.go:45:22:45:31 | &... [pointer] | test.go:45:23:45:31 | cleanNode | provenance | | | test.go:45:23:45:31 | cleanNode | test.go:45:22:45:31 | &... | provenance | | | test.go:45:23:45:31 | cleanNode | test.go:45:22:45:31 | &... [pointer] | provenance | | -| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... | provenance | | -| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... | provenance | | -| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:23:50:32 | cleanNode2 | provenance | | | test.go:48:2:48:44 | ... := ...[0] | test.go:49:26:49:37 | taintedNode2 | provenance | | | test.go:48:32:48:43 | selection of Body | test.go:48:2:48:44 | ... := ...[0] | provenance | Src:MaD:1 MaD:5 | -| test.go:49:26:49:37 | taintedNode2 | test.go:47:6:47:15 | definition of cleanNode2 | provenance | MaD:11 | -| test.go:50:22:50:32 | &... | test.go:50:23:50:32 | cleanNode2 | provenance | | +| test.go:49:2:49:11 | cleanNode2 [postupdate] | test.go:50:22:50:32 | &... | provenance | | +| test.go:49:2:49:11 | cleanNode2 [postupdate] | test.go:50:23:50:32 | cleanNode2 | provenance | | +| test.go:49:26:49:37 | taintedNode2 | test.go:49:2:49:11 | cleanNode2 [postupdate] | provenance | MaD:11 | | test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | provenance | | -| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | provenance | | -| test.go:50:22:50:32 | &... [pointer] | test.go:50:23:50:32 | cleanNode2 | provenance | | | test.go:50:23:50:32 | cleanNode2 | test.go:50:22:50:32 | &... | provenance | | | test.go:50:23:50:32 | cleanNode2 | test.go:50:22:50:32 | &... [pointer] | provenance | | models @@ -125,20 +117,18 @@ nodes | test.go:39:49:39:60 | selection of Body | semmle.label | selection of Body | | test.go:40:15:40:31 | tokenizerFragment | semmle.label | tokenizerFragment | | test.go:40:15:40:42 | call to Buffered | semmle.label | call to Buffered | -| test.go:42:6:42:14 | definition of cleanNode | semmle.label | definition of cleanNode | | test.go:43:2:43:43 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:43:31:43:42 | selection of Body | semmle.label | selection of Body | +| test.go:44:2:44:10 | cleanNode [postupdate] | semmle.label | cleanNode [postupdate] | | test.go:44:24:44:34 | taintedNode | semmle.label | taintedNode | | test.go:45:22:45:31 | &... | semmle.label | &... | -| test.go:45:22:45:31 | &... | semmle.label | &... | | test.go:45:22:45:31 | &... [pointer] | semmle.label | &... [pointer] | | test.go:45:23:45:31 | cleanNode | semmle.label | cleanNode | -| test.go:47:6:47:15 | definition of cleanNode2 | semmle.label | definition of cleanNode2 | | test.go:48:2:48:44 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:48:32:48:43 | selection of Body | semmle.label | selection of Body | +| test.go:49:2:49:11 | cleanNode2 [postupdate] | semmle.label | cleanNode2 [postupdate] | | test.go:49:26:49:37 | taintedNode2 | semmle.label | taintedNode2 | | test.go:50:22:50:32 | &... | semmle.label | &... | -| test.go:50:22:50:32 | &... | semmle.label | &... | | test.go:50:22:50:32 | &... [pointer] | semmle.label | &... [pointer] | | test.go:50:23:50:32 | cleanNode2 | semmle.label | cleanNode2 | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/yaml.go b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/yaml.go index 9861acf33e6..fb8f7ea4bfa 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/yaml.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/yaml.go @@ -13,30 +13,30 @@ func main() { var inb []byte out, _ = yaml1.Marshal(in) // $ marshaler="yaml: in -> ... = ...[0]" ttfnmodelstep="in -> ... = ...[0]" - yaml1.Unmarshal(inb, out) // $ unmarshaler="yaml: inb -> definition of out" ttfnmodelstep="inb -> definition of out" + yaml1.Unmarshal(inb, out) // $ unmarshaler="yaml: inb -> out [postupdate]" ttfnmodelstep="inb -> out [postupdate]" out, _ = yaml2.Marshal(in) // $ marshaler="yaml: in -> ... = ...[0]" ttfnmodelstep="in -> ... = ...[0]" - yaml2.Unmarshal(inb, out) // $ unmarshaler="yaml: inb -> definition of out" ttfnmodelstep="inb -> definition of out" - yaml2.UnmarshalStrict(inb, out) // $ unmarshaler="yaml: inb -> definition of out" ttfnmodelstep="inb -> definition of out" + yaml2.Unmarshal(inb, out) // $ unmarshaler="yaml: inb -> out [postupdate]" ttfnmodelstep="inb -> out [postupdate]" + yaml2.UnmarshalStrict(inb, out) // $ unmarshaler="yaml: inb -> out [postupdate]" ttfnmodelstep="inb -> out [postupdate]" var r io.Reader d := yaml2.NewDecoder(r) // $ ttfnmodelstep="r -> call to NewDecoder" - d.Decode(out) // $ ttfnmodelstep="d -> definition of out" + d.Decode(out) // $ ttfnmodelstep="d -> out [postupdate]" var w io.Writer - e := yaml2.NewEncoder(w) // $ ttfnmodelstep="definition of e -> definition of w" - e.Encode(in) // $ ttfnmodelstep="in -> definition of e" + e := yaml2.NewEncoder(w) // $ ttfnmodelstep="definition of e -> w [postupdate]" + e.Encode(in) // $ ttfnmodelstep="in -> e [postupdate]" out, _ = yaml3.Marshal(in) // $ marshaler="yaml: in -> ... = ...[0]" ttfnmodelstep="in -> ... = ...[0]" - yaml3.Unmarshal(inb, out) // $ unmarshaler="yaml: inb -> definition of out" ttfnmodelstep="inb -> definition of out" + yaml3.Unmarshal(inb, out) // $ unmarshaler="yaml: inb -> out [postupdate]" ttfnmodelstep="inb -> out [postupdate]" d1 := yaml3.NewDecoder(r) // $ ttfnmodelstep="r -> call to NewDecoder" - d1.Decode(out) // $ ttfnmodelstep="d1 -> definition of out" + d1.Decode(out) // $ ttfnmodelstep="d1 -> out [postupdate]" - e1 := yaml3.NewEncoder(w) // $ ttfnmodelstep="definition of e1 -> definition of w" - e1.Encode(in) // $ ttfnmodelstep="in -> definition of e1" + e1 := yaml3.NewEncoder(w) // $ ttfnmodelstep="definition of e1 -> w [postupdate]" + e1.Encode(in) // $ ttfnmodelstep="in -> e1 [postupdate]" var n1 yaml3.Node - n1.Decode(out) // $ ttfnmodelstep="n1 -> definition of out" - n1.Encode(in) // $ ttfnmodelstep="in -> definition of n1" + n1.Decode(out) // $ ttfnmodelstep="n1 -> out [postupdate]" + n1.Encode(in) // $ ttfnmodelstep="in -> n1 [postupdate]" } 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 78dde84a947..22dec49d484 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -56,8 +56,8 @@ edges | SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:80:23:80:29 | tainted | provenance | Config | | 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:9:2:9:8 | definition of tainted | provenance | | -| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:13:25:13:31 | tainted | SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | provenance | | +| SanitizingDoubleDash.go:13:15:13:32 | array literal [postupdate] [array] | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:13:25:13:31 | tainted | SanitizingDoubleDash.go:13:15:13:32 | array literal [postupdate] [array] | provenance | | | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | SanitizingDoubleDash.go:14:23:14:33 | slice element node | provenance | | | SanitizingDoubleDash.go:14:23:14:33 | slice element node | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | | | SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | SanitizingDoubleDash.go:39:14:39:44 | call to append | provenance | MaD:5 | @@ -65,8 +65,8 @@ edges | SanitizingDoubleDash.go:39:14:39:44 | call to append | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:39:14:39:44 | call to append [array] | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:39:31:39:37 | tainted | SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | provenance | | -| SanitizingDoubleDash.go:52:15:52:31 | slice literal [array] | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:52:24:52:30 | tainted | SanitizingDoubleDash.go:52:15:52:31 | slice literal [array] | provenance | | +| SanitizingDoubleDash.go:52:15:52:31 | slice literal [postupdate] [array] | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:52:24:52:30 | tainted | SanitizingDoubleDash.go:52:15:52:31 | slice literal [postupdate] [array] | provenance | | | SanitizingDoubleDash.go:52:24:52:30 | tainted | SanitizingDoubleDash.go:53:21:53:28 | arrayLit | provenance | | | 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 | | @@ -99,16 +99,16 @@ edges | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:142:31:142:37 | tainted | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:148:30:148:36 | tainted | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:152:24:152:30 | tainted | provenance | | -| SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:95:25:95:31 | tainted | SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | provenance | | +| SanitizingDoubleDash.go:95:15:95:32 | array literal [postupdate] [array] | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:95:25:95:31 | tainted | SanitizingDoubleDash.go:95:15:95:32 | array literal [postupdate] [array] | provenance | | | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | SanitizingDoubleDash.go:96:24:96:34 | slice element node | provenance | | | SanitizingDoubleDash.go:96:24:96:34 | slice element node | SanitizingDoubleDash.go:96:24:96:34 | slice expression | provenance | | -| SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:100:31:100:37 | tainted | SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | provenance | | +| SanitizingDoubleDash.go:100:15:100:38 | array literal [postupdate] [array] | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:100:31:100:37 | tainted | SanitizingDoubleDash.go:100:15:100:38 | array literal [postupdate] [array] | provenance | | | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | SanitizingDoubleDash.go:101:24:101:34 | slice element node | provenance | | | SanitizingDoubleDash.go:101:24:101:34 | slice element node | SanitizingDoubleDash.go:101:24:101:34 | slice expression | provenance | | -| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | provenance | | -| SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | provenance | | +| SanitizingDoubleDash.go:105:15:105:37 | slice literal [postupdate] [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | provenance | | +| SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [postupdate] [array] | provenance | | | SanitizingDoubleDash.go:111:14:111:44 | []type{args} [array] | SanitizingDoubleDash.go:111:14:111:44 | call to append | provenance | MaD:5 | | SanitizingDoubleDash.go:111:14:111:44 | []type{args} [array] | SanitizingDoubleDash.go:111:14:111:44 | call to append [array] | provenance | MaD:5 | | SanitizingDoubleDash.go:111:14:111:44 | call to append | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | provenance | | @@ -124,8 +124,8 @@ edges | SanitizingDoubleDash.go:123:14:123:38 | call to append | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:123:14:123:38 | call to append [array] | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:123:31:123:37 | tainted | SanitizingDoubleDash.go:123:14:123:38 | []type{args} [array] | provenance | | -| SanitizingDoubleDash.go:128:15:128:31 | slice literal [array] | SanitizingDoubleDash.go:129:21:129:28 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:128:24:128:30 | tainted | SanitizingDoubleDash.go:128:15:128:31 | slice literal [array] | provenance | | +| SanitizingDoubleDash.go:128:15:128:31 | slice literal [postupdate] [array] | SanitizingDoubleDash.go:129:21:129:28 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:128:24:128:30 | tainted | SanitizingDoubleDash.go:128:15:128:31 | slice literal [postupdate] [array] | provenance | | | 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 | @@ -184,7 +184,7 @@ nodes | SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | semmle.label | definition of tainted | | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | semmle.label | selection of URL | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | semmle.label | call to Query | -| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | semmle.label | array literal [array] | +| SanitizingDoubleDash.go:13:15:13:32 | array literal [postupdate] [array] | semmle.label | array literal [postupdate] [array] | | SanitizingDoubleDash.go:13:25:13:31 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | semmle.label | arrayLit [array] | | SanitizingDoubleDash.go:14:23:14:33 | slice element node | semmle.label | slice element node | @@ -194,7 +194,7 @@ nodes | SanitizingDoubleDash.go:39:14:39:44 | call to append [array] | semmle.label | call to append [array] | | SanitizingDoubleDash.go:39:31:39:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | semmle.label | arrayLit | -| SanitizingDoubleDash.go:52:15:52:31 | slice literal [array] | semmle.label | slice literal [array] | +| SanitizingDoubleDash.go:52:15:52:31 | slice literal [postupdate] [array] | semmle.label | slice literal [postupdate] [array] | | SanitizingDoubleDash.go:52:24:52:30 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:53:14:53:35 | call to append | semmle.label | call to append | | SanitizingDoubleDash.go:53:14:53:35 | call to append [array] | semmle.label | call to append [array] | @@ -213,17 +213,17 @@ nodes | SanitizingDoubleDash.go:80:23:80:29 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | semmle.label | selection of URL | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | semmle.label | call to Query | -| SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | semmle.label | array literal [array] | +| SanitizingDoubleDash.go:95:15:95:32 | array literal [postupdate] [array] | semmle.label | array literal [postupdate] [array] | | SanitizingDoubleDash.go:95:25:95:31 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | semmle.label | arrayLit [array] | | SanitizingDoubleDash.go:96:24:96:34 | slice element node | semmle.label | slice element node | | SanitizingDoubleDash.go:96:24:96:34 | slice expression | semmle.label | slice expression | -| SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | semmle.label | array literal [array] | +| SanitizingDoubleDash.go:100:15:100:38 | array literal [postupdate] [array] | semmle.label | array literal [postupdate] [array] | | SanitizingDoubleDash.go:100:31:100:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | semmle.label | arrayLit [array] | | SanitizingDoubleDash.go:101:24:101:34 | slice element node | semmle.label | slice element node | | SanitizingDoubleDash.go:101:24:101:34 | slice expression | semmle.label | slice expression | -| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | semmle.label | slice literal [array] | +| SanitizingDoubleDash.go:105:15:105:37 | slice literal [postupdate] [array] | semmle.label | slice literal [postupdate] [array] | | SanitizingDoubleDash.go:105:30:105:36 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:111:14:111:44 | []type{args} [array] | semmle.label | []type{args} [array] | @@ -241,7 +241,7 @@ nodes | SanitizingDoubleDash.go:123:14:123:38 | call to append [array] | semmle.label | call to append [array] | | SanitizingDoubleDash.go:123:31:123:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | semmle.label | arrayLit | -| SanitizingDoubleDash.go:128:15:128:31 | slice literal [array] | semmle.label | slice literal [array] | +| SanitizingDoubleDash.go:128:15:128:31 | slice literal [postupdate] [array] | semmle.label | slice literal [postupdate] [array] | | SanitizingDoubleDash.go:128:24:128:30 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:129:14:129:35 | call to append | semmle.label | call to append | | SanitizingDoubleDash.go:129:14:129:35 | call to append [array] | semmle.label | call to append [array] | diff --git a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected index c274067926a..809f5c20976 100644 --- a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected +++ b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected @@ -2,14 +2,14 @@ | StoredCommand.go:14:22:14:28 | cmdName | StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:14:22:14:28 | cmdName | This command depends on a $@. | StoredCommand.go:11:2:11:27 | ... := ...[0] | stored value | edges | StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:13:2:13:5 | rows | provenance | Src:MaD:2 | -| StoredCommand.go:13:2:13:5 | rows | StoredCommand.go:13:12:13:19 | &... | provenance | FunctionModel | -| StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:14:22:14:28 | cmdName | provenance | Sink:MaD:1 | +| StoredCommand.go:13:2:13:5 | rows | StoredCommand.go:13:12:13:19 | &... [postupdate] | provenance | FunctionModel | +| StoredCommand.go:13:12:13:19 | &... [postupdate] | StoredCommand.go:14:22:14:28 | cmdName | provenance | Sink:MaD:1 | models | 1 | Sink: os/exec; ; false; Command; ; ; Argument[0]; command-injection; manual | | 2 | Source: database/sql; DB; true; Query; ; ; ReturnValue[0]; database; manual | nodes | StoredCommand.go:11:2:11:27 | ... := ...[0] | semmle.label | ... := ...[0] | | StoredCommand.go:13:2:13:5 | rows | semmle.label | rows | -| StoredCommand.go:13:12:13:19 | &... | semmle.label | &... | +| StoredCommand.go:13:12:13:19 | &... [postupdate] | semmle.label | &... [postupdate] | | StoredCommand.go:14:22:14:28 | cmdName | semmle.label | cmdName | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index 91b39e0e2a0..0e1265b5c1e 100644 --- a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -13,11 +13,11 @@ | reflectedxsstest.go:54:11:54:21 | type conversion | reflectedxsstest.go:51:14:51:18 | selection of URL | reflectedxsstest.go:54:11:54:21 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:51:14:51:18 | selection of URL | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | | tst.go:18:12:18:39 | type conversion | tst.go:14:15:14:20 | selection of Form | tst.go:18:12:18:39 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:14:15:14:20 | selection of Form | user-provided value | tst.go:0:0:0:0 | tst.go | | | tst.go:53:12:53:26 | type conversion | tst.go:48:14:48:19 | selection of Form | tst.go:53:12:53:26 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:48:14:48:19 | selection of Form | user-provided value | tst.go:0:0:0:0 | tst.go | | -| websocketXss.go:32:24:32:27 | xnet | websocketXss.go:30:7:30:10 | definition of xnet | websocketXss.go:32:24:32:27 | xnet | Cross-site scripting vulnerability due to $@. | websocketXss.go:30:7:30:10 | definition of xnet | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | -| websocketXss.go:36:24:36:28 | xnet2 | websocketXss.go:34:3:34:7 | definition of xnet2 | websocketXss.go:36:24:36:28 | xnet2 | Cross-site scripting vulnerability due to $@. | websocketXss.go:34:3:34:7 | definition of xnet2 | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:32:24:32:27 | xnet | websocketXss.go:31:11:31:14 | xnet [postupdate] | websocketXss.go:32:24:32:27 | xnet | Cross-site scripting vulnerability due to $@. | websocketXss.go:31:11:31:14 | xnet [postupdate] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:36:24:36:28 | xnet2 | websocketXss.go:35:21:35:25 | xnet2 [postupdate] | websocketXss.go:36:24:36:28 | xnet2 | Cross-site scripting vulnerability due to $@. | websocketXss.go:35:21:35:25 | xnet2 [postupdate] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | | websocketXss.go:41:24:41:29 | nhooyr | websocketXss.go:40:3:40:40 | ... := ...[1] | websocketXss.go:41:24:41:29 | nhooyr | Cross-site scripting vulnerability due to $@. | websocketXss.go:40:3:40:40 | ... := ...[1] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | -| websocketXss.go:48:24:48:33 | gorillaMsg | websocketXss.go:46:7:46:16 | definition of gorillaMsg | websocketXss.go:48:24:48:33 | gorillaMsg | Cross-site scripting vulnerability due to $@. | websocketXss.go:46:7:46:16 | definition of gorillaMsg | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | -| websocketXss.go:52:24:52:31 | gorilla2 | websocketXss.go:50:3:50:10 | definition of gorilla2 | websocketXss.go:52:24:52:31 | gorilla2 | Cross-site scripting vulnerability due to $@. | websocketXss.go:50:3:50:10 | definition of gorilla2 | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:48:24:48:33 | gorillaMsg | websocketXss.go:47:26:47:35 | gorillaMsg [postupdate] | websocketXss.go:48:24:48:33 | gorillaMsg | Cross-site scripting vulnerability due to $@. | websocketXss.go:47:26:47:35 | gorillaMsg [postupdate] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | +| websocketXss.go:52:24:52:31 | gorilla2 | websocketXss.go:51:17:51:24 | gorilla2 [postupdate] | websocketXss.go:52:24:52:31 | gorilla2 | Cross-site scripting vulnerability due to $@. | websocketXss.go:51:17:51:24 | gorilla2 [postupdate] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | | websocketXss.go:55:24:55:31 | gorilla3 | websocketXss.go:54:3:54:38 | ... := ...[1] | websocketXss.go:55:24:55:31 | gorilla3 | Cross-site scripting vulnerability due to $@. | websocketXss.go:54:3:54:38 | ... := ...[1] | user-provided value | websocketXss.go:0:0:0:0 | websocketXss.go | | edges | ReflectedXss.go:11:15:11:20 | selection of Form | ReflectedXss.go:11:15:11:36 | call to Get | provenance | Src:MaD:6 MaD:18 | @@ -48,8 +48,8 @@ edges | reflectedxsstest.go:39:16:39:21 | reader | reflectedxsstest.go:39:2:39:32 | ... := ...[0] | provenance | MaD:16 | | reflectedxsstest.go:40:14:40:17 | part | reflectedxsstest.go:40:14:40:28 | call to FileName | provenance | MaD:15 | | reflectedxsstest.go:40:14:40:28 | call to FileName | reflectedxsstest.go:44:46:44:53 | partName | provenance | | -| reflectedxsstest.go:41:2:41:10 | definition of byteSlice | reflectedxsstest.go:45:10:45:18 | byteSlice | provenance | | -| reflectedxsstest.go:42:2:42:5 | part | reflectedxsstest.go:41:2:41:10 | definition of byteSlice | provenance | MaD:14 | +| reflectedxsstest.go:42:2:42:5 | part | reflectedxsstest.go:42:12:42:20 | byteSlice [postupdate] | provenance | MaD:14 | +| reflectedxsstest.go:42:12:42:20 | byteSlice [postupdate] | reflectedxsstest.go:45:10:45:18 | byteSlice | provenance | | | reflectedxsstest.go:44:17:44:54 | []type{args} [array] | reflectedxsstest.go:44:17:44:54 | call to Sprintf | provenance | MaD:12 | | reflectedxsstest.go:44:17:44:54 | call to Sprintf | reflectedxsstest.go:44:10:44:55 | type conversion | provenance | | | reflectedxsstest.go:44:46:44:53 | partName | reflectedxsstest.go:44:17:44:54 | []type{args} [array] | provenance | | @@ -62,11 +62,11 @@ edges | tst.go:18:32:18:32 | a | tst.go:18:19:18:38 | call to Join | provenance | MaD:19 | | tst.go:48:14:48:19 | selection of Form | tst.go:48:14:48:34 | call to Get | provenance | Src:MaD:6 MaD:18 | | tst.go:48:14:48:34 | call to Get | tst.go:53:12:53:26 | type conversion | provenance | | -| websocketXss.go:30:7:30:10 | definition of xnet | websocketXss.go:32:24:32:27 | xnet | provenance | Src:MaD:5 | -| websocketXss.go:34:3:34:7 | definition of xnet2 | websocketXss.go:36:24:36:28 | xnet2 | provenance | Src:MaD:4 | +| websocketXss.go:31:11:31:14 | xnet [postupdate] | websocketXss.go:32:24:32:27 | xnet | provenance | Src:MaD:5 | +| websocketXss.go:35:21:35:25 | xnet2 [postupdate] | websocketXss.go:36:24:36:28 | xnet2 | provenance | Src:MaD:4 | | websocketXss.go:40:3:40:40 | ... := ...[1] | websocketXss.go:41:24:41:29 | nhooyr | provenance | Src:MaD:11 | -| websocketXss.go:46:7:46:16 | definition of gorillaMsg | websocketXss.go:48:24:48:33 | gorillaMsg | provenance | Src:MaD:1 | -| websocketXss.go:50:3:50:10 | definition of gorilla2 | websocketXss.go:52:24:52:31 | gorilla2 | provenance | Src:MaD:2 | +| websocketXss.go:47:26:47:35 | gorillaMsg [postupdate] | websocketXss.go:48:24:48:33 | gorillaMsg | provenance | Src:MaD:1 | +| websocketXss.go:51:17:51:24 | gorilla2 [postupdate] | websocketXss.go:52:24:52:31 | gorilla2 | provenance | Src:MaD:2 | | websocketXss.go:54:3:54:38 | ... := ...[1] | websocketXss.go:55:24:55:31 | gorilla3 | provenance | Src:MaD:3 | models | 1 | Source: github.com/gorilla/websocket; ; false; ReadJSON; ; ; Argument[1]; remote; manual | @@ -123,8 +123,8 @@ nodes | reflectedxsstest.go:39:16:39:21 | reader | semmle.label | reader | | reflectedxsstest.go:40:14:40:17 | part | semmle.label | part | | reflectedxsstest.go:40:14:40:28 | call to FileName | semmle.label | call to FileName | -| reflectedxsstest.go:41:2:41:10 | definition of byteSlice | semmle.label | definition of byteSlice | | reflectedxsstest.go:42:2:42:5 | part | semmle.label | part | +| reflectedxsstest.go:42:12:42:20 | byteSlice [postupdate] | semmle.label | byteSlice [postupdate] | | reflectedxsstest.go:44:10:44:55 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:44:17:44:54 | []type{args} [array] | semmle.label | []type{args} [array] | | reflectedxsstest.go:44:17:44:54 | call to Sprintf | semmle.label | call to Sprintf | @@ -141,16 +141,25 @@ nodes | tst.go:48:14:48:19 | selection of Form | semmle.label | selection of Form | | tst.go:48:14:48:34 | call to Get | semmle.label | call to Get | | tst.go:53:12:53:26 | type conversion | semmle.label | type conversion | -| websocketXss.go:30:7:30:10 | definition of xnet | semmle.label | definition of xnet | +| websocketXss.go:31:11:31:14 | xnet [postupdate] | semmle.label | xnet [postupdate] | | websocketXss.go:32:24:32:27 | xnet | semmle.label | xnet | -| websocketXss.go:34:3:34:7 | definition of xnet2 | semmle.label | definition of xnet2 | +| websocketXss.go:35:21:35:25 | xnet2 [postupdate] | semmle.label | xnet2 [postupdate] | | websocketXss.go:36:24:36:28 | xnet2 | semmle.label | xnet2 | | websocketXss.go:40:3:40:40 | ... := ...[1] | semmle.label | ... := ...[1] | | websocketXss.go:41:24:41:29 | nhooyr | semmle.label | nhooyr | -| websocketXss.go:46:7:46:16 | definition of gorillaMsg | semmle.label | definition of gorillaMsg | +| websocketXss.go:47:26:47:35 | gorillaMsg [postupdate] | semmle.label | gorillaMsg [postupdate] | | websocketXss.go:48:24:48:33 | gorillaMsg | semmle.label | gorillaMsg | -| websocketXss.go:50:3:50:10 | definition of gorilla2 | semmle.label | definition of gorilla2 | +| websocketXss.go:51:17:51:24 | gorilla2 [postupdate] | semmle.label | gorilla2 [postupdate] | | websocketXss.go:52:24:52:31 | gorilla2 | semmle.label | gorilla2 | | websocketXss.go:54:3:54:38 | ... := ...[1] | semmle.label | ... := ...[1] | | websocketXss.go:55:24:55:31 | gorilla3 | semmle.label | gorilla3 | subpaths +testFailures +| websocketXss.go:30:32:30:60 | comment | Missing result: Source[go/reflected-xss] | +| websocketXss.go:31:11:31:14 | xnet [postupdate] | Unexpected result: Source | +| websocketXss.go:34:30:34:58 | comment | Missing result: Source[go/reflected-xss] | +| websocketXss.go:35:21:35:25 | xnet2 [postupdate] | Unexpected result: Source | +| websocketXss.go:46:38:46:66 | comment | Missing result: Source[go/reflected-xss] | +| websocketXss.go:47:26:47:35 | gorillaMsg [postupdate] | Unexpected result: Source | +| websocketXss.go:50:33:50:61 | comment | Missing result: Source[go/reflected-xss] | +| websocketXss.go:51:17:51:24 | gorilla2 [postupdate] | Unexpected result: Source | diff --git a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected index 4e2958c767e..41ec62706d0 100644 --- a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -3,15 +3,15 @@ | stored.go:61:22:61:25 | path | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | Stored cross-site scripting vulnerability due to $@. | stored.go:59:30:59:33 | definition of path | stored value | edges | stored.go:18:3:18:28 | ... := ...[0] | stored.go:25:14:25:17 | rows | provenance | Src:MaD:1 | -| stored.go:25:14:25:17 | rows | stored.go:25:29:25:33 | &... | provenance | FunctionModel | -| stored.go:25:29:25:33 | &... | stored.go:30:22:30:25 | name | provenance | | +| stored.go:25:14:25:17 | rows | stored.go:25:29:25:33 | &... [postupdate] | provenance | FunctionModel | +| stored.go:25:29:25:33 | &... [postupdate] | stored.go:30:22:30:25 | name | provenance | | | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | provenance | | models | 1 | Source: database/sql; DB; true; Query; ; ; ReturnValue[0]; database; manual | nodes | stored.go:18:3:18:28 | ... := ...[0] | semmle.label | ... := ...[0] | | stored.go:25:14:25:17 | rows | semmle.label | rows | -| stored.go:25:29:25:33 | &... | semmle.label | &... | +| stored.go:25:29:25:33 | &... [postupdate] | semmle.label | &... [postupdate] | | stored.go:30:22:30:25 | name | semmle.label | name | | stored.go:59:30:59:33 | definition of path | semmle.label | definition of path | | stored.go:61:22:61:25 | path | semmle.label | path | 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 40be0e8df69..ef5f3a1f7b9 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 @@ -12,9 +12,9 @@ edges | 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 expression | sample.go:26:25:26:30 | call to Guid | provenance | | -| sample.go:33:2:33:6 | definition of nonce | sample.go:37:35:37:39 | nonce | provenance | | | sample.go:34:12:34:40 | call to New | sample.go:35:14:35:19 | random | provenance | | -| sample.go:35:14:35:19 | random | sample.go:33:2:33:6 | definition of nonce | provenance | MaD:2 | +| sample.go:35:14:35:19 | random | sample.go:35:22:35:26 | nonce [postupdate] | provenance | MaD:2 | +| sample.go:35:22:35:26 | nonce [postupdate] | sample.go:37:35:37:39 | nonce | provenance | | | sample.go:55:17:55:42 | call to Intn | sample.go:56:29:56:38 | randNumber | provenance | | | sample.go:56:11:56:40 | type conversion | sample.go:58:32:58:43 | type conversion | provenance | | | sample.go:56:18:56:39 | index expression | sample.go:56:11:56:40 | type conversion | provenance | | @@ -31,9 +31,9 @@ nodes | sample.go:15:49:15:61 | call to Uint32 | semmle.label | call to Uint32 | | sample.go:16:9:16:15 | slice expression | semmle.label | slice expression | | 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 | | sample.go:35:14:35:19 | random | semmle.label | random | +| sample.go:35:22:35:26 | nonce [postupdate] | semmle.label | nonce [postupdate] | | sample.go:37:35:37:39 | nonce | semmle.label | nonce | | sample.go:43:17:43:39 | call to Intn | semmle.label | call to Intn | | sample.go:44:17:44:39 | call to Intn | semmle.label | call to Intn | diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index 65d24e8b45b..b091d0343d8 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -29,43 +29,34 @@ edges | stdlib.go:93:13:93:32 | call to Get | stdlib.go:94:3:94:8 | target | provenance | | | stdlib.go:94:3:94:8 | target | stdlib.go:94:3:94:25 | ... += ... | provenance | Config | | stdlib.go:94:3:94:25 | ... += ... | stdlib.go:96:23:96:28 | target | provenance | Sink:MaD:1 | -| stdlib.go:111:54:111:54 | definition of r [pointer, URL, pointer] | stdlib.go:115:6:115:6 | r [pointer, URL, pointer] | provenance | | -| stdlib.go:111:54:111:54 | definition of r [pointer, URL] | stdlib.go:115:6:115:6 | r [pointer, URL] | provenance | | -| stdlib.go:115:6:115:6 | r [pointer, URL, pointer] | stdlib.go:116:4:116:4 | r [pointer, URL, pointer] | provenance | | -| stdlib.go:115:6:115:6 | r [pointer, URL] | stdlib.go:116:4:116:4 | r [pointer, URL] | provenance | | -| stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | stdlib.go:111:54:111:54 | definition of r [pointer, URL, pointer] | provenance | | -| stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | stdlib.go:116:4:116:8 | selection of URL [pointer] | provenance | | -| stdlib.go:116:4:116:4 | implicit dereference [URL] | stdlib.go:111:54:111:54 | definition of r [pointer, URL] | provenance | | -| stdlib.go:116:4:116:4 | implicit dereference [URL] | stdlib.go:116:4:116:8 | selection of URL | provenance | | -| stdlib.go:116:4:116:4 | r [pointer, URL, pointer] | stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | provenance | | -| stdlib.go:116:4:116:4 | r [pointer, URL] | stdlib.go:116:4:116:4 | implicit dereference [URL] | provenance | | -| stdlib.go:116:4:116:4 | r [pointer, URL] | stdlib.go:117:24:117:24 | r [pointer, URL] | provenance | | -| stdlib.go:116:4:116:8 | implicit dereference | stdlib.go:116:4:116:8 | selection of URL | provenance | Config | -| stdlib.go:116:4:116:8 | implicit dereference | stdlib.go:116:4:116:8 | selection of URL [pointer] | provenance | | -| stdlib.go:116:4:116:8 | selection of URL | stdlib.go:116:4:116:4 | implicit dereference [URL] | provenance | Src:MaD:4 | +| stdlib.go:116:4:116:4 | implicit dereference [postupdate] [URL] | stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | provenance | | +| stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | stdlib.go:117:24:117:24 | r [pointer, URL] | provenance | | +| stdlib.go:116:4:116:8 | implicit dereference | stdlib.go:116:4:116:8 | selection of URL [postupdate] | provenance | Config | | stdlib.go:116:4:116:8 | selection of URL | stdlib.go:116:4:116:8 | implicit dereference | provenance | Src:MaD:4 Config | -| stdlib.go:116:4:116:8 | selection of URL [pointer] | stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | provenance | | -| stdlib.go:116:4:116:8 | selection of URL [pointer] | stdlib.go:116:4:116:8 | implicit dereference | provenance | | +| stdlib.go:116:4:116:8 | selection of URL [postupdate] | stdlib.go:116:4:116:4 | implicit dereference [postupdate] [URL] | provenance | | +| stdlib.go:116:4:116:8 | selection of URL [postupdate] | stdlib.go:116:4:116:8 | implicit dereference | provenance | Config | | stdlib.go:117:24:117:24 | implicit dereference [URL] | stdlib.go:117:24:117:28 | selection of URL | provenance | | | stdlib.go:117:24:117:24 | r [pointer, URL] | stdlib.go:117:24:117:24 | implicit dereference [URL] | provenance | | | stdlib.go:117:24:117:28 | selection of URL | stdlib.go:117:24:117:37 | call to String | provenance | Src:MaD:4 Config Sink:MaD:1 | | stdlib.go:150:13:150:18 | selection of Form | stdlib.go:150:13:150:32 | call to Get | provenance | Src:MaD:2 Config | | stdlib.go:150:13:150:32 | call to Get | stdlib.go:156:23:156:28 | target | provenance | Sink:MaD:1 | -| stdlib.go:163:10:163:15 | star expression | stdlib.go:163:11:163:15 | selection of URL | provenance | Config | +| stdlib.go:163:10:163:15 | star expression | stdlib.go:163:11:163:15 | selection of URL [postupdate] | provenance | Config | | stdlib.go:163:10:163:15 | star expression | stdlib.go:166:24:166:26 | url | provenance | | | stdlib.go:163:11:163:15 | selection of URL | stdlib.go:163:10:163:15 | star expression | provenance | Src:MaD:4 Config | +| stdlib.go:163:11:163:15 | selection of URL [postupdate] | stdlib.go:163:10:163:15 | star expression | provenance | Config | | stdlib.go:166:24:166:26 | url | stdlib.go:166:24:166:35 | call to String | provenance | Config Sink:MaD:1 | | stdlib.go:177:35:177:39 | selection of URL | stdlib.go:177:35:177:52 | call to RequestURI | provenance | Src:MaD:4 Config | | stdlib.go:177:35:177:52 | call to RequestURI | stdlib.go:177:24:177:52 | ...+... | provenance | Config Sink:MaD:1 | | stdlib.go:186:13:186:33 | call to FormValue | stdlib.go:188:23:188:28 | target | provenance | Src:MaD:3 Sink:MaD:1 | -| stdlib.go:194:3:194:8 | definition of target | stdlib.go:196:23:196:28 | target | provenance | | -| stdlib.go:194:3:194:57 | ... := ...[0] | stdlib.go:194:3:194:8 | definition of target | provenance | | +| stdlib.go:194:3:194:57 | ... := ...[0] | stdlib.go:196:23:196:28 | target | provenance | | | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:194:3:194:57 | ... := ...[0] | provenance | Src:MaD:3 Config | -| stdlib.go:196:23:196:28 | implicit dereference | stdlib.go:194:3:194:8 | definition of target | provenance | Config | +| stdlib.go:196:23:196:28 | implicit dereference | stdlib.go:196:23:196:28 | target [postupdate] | provenance | Config | | stdlib.go:196:23:196:28 | implicit dereference | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 | | stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config | | stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 | | stdlib.go:196:23:196:28 | target | stdlib.go:198:23:198:28 | target | provenance | | +| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config | +| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:198:23:198:28 | target | provenance | | | stdlib.go:198:23:198:28 | target | stdlib.go:198:23:198:42 | call to EscapedPath | provenance | Config Sink:MaD:1 | models | 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual | @@ -98,17 +89,11 @@ nodes | stdlib.go:94:3:94:8 | target | semmle.label | target | | stdlib.go:94:3:94:25 | ... += ... | semmle.label | ... += ... | | stdlib.go:96:23:96:28 | target | semmle.label | target | -| stdlib.go:111:54:111:54 | definition of r [pointer, URL, pointer] | semmle.label | definition of r [pointer, URL, pointer] | -| stdlib.go:111:54:111:54 | definition of r [pointer, URL] | semmle.label | definition of r [pointer, URL] | -| stdlib.go:115:6:115:6 | r [pointer, URL, pointer] | semmle.label | r [pointer, URL, pointer] | -| stdlib.go:115:6:115:6 | r [pointer, URL] | semmle.label | r [pointer, URL] | -| stdlib.go:116:4:116:4 | implicit dereference [URL, pointer] | semmle.label | implicit dereference [URL, pointer] | -| stdlib.go:116:4:116:4 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | -| stdlib.go:116:4:116:4 | r [pointer, URL, pointer] | semmle.label | r [pointer, URL, pointer] | -| stdlib.go:116:4:116:4 | r [pointer, URL] | semmle.label | r [pointer, URL] | +| stdlib.go:116:4:116:4 | implicit dereference [postupdate] [URL] | semmle.label | implicit dereference [postupdate] [URL] | +| stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | semmle.label | r [postupdate] [pointer, URL] | | stdlib.go:116:4:116:8 | implicit dereference | semmle.label | implicit dereference | | stdlib.go:116:4:116:8 | selection of URL | semmle.label | selection of URL | -| stdlib.go:116:4:116:8 | selection of URL [pointer] | semmle.label | selection of URL [pointer] | +| stdlib.go:116:4:116:8 | selection of URL [postupdate] | semmle.label | selection of URL [postupdate] | | stdlib.go:117:24:117:24 | implicit dereference [URL] | semmle.label | implicit dereference [URL] | | stdlib.go:117:24:117:24 | r [pointer, URL] | semmle.label | r [pointer, URL] | | stdlib.go:117:24:117:28 | selection of URL | semmle.label | selection of URL | @@ -118,6 +103,7 @@ nodes | stdlib.go:156:23:156:28 | target | semmle.label | target | | stdlib.go:163:10:163:15 | star expression | semmle.label | star expression | | stdlib.go:163:11:163:15 | selection of URL | semmle.label | selection of URL | +| stdlib.go:163:11:163:15 | selection of URL [postupdate] | semmle.label | selection of URL [postupdate] | | stdlib.go:166:24:166:26 | url | semmle.label | url | | stdlib.go:166:24:166:35 | call to String | semmle.label | call to String | | stdlib.go:177:24:177:52 | ...+... | semmle.label | ...+... | @@ -125,11 +111,11 @@ nodes | stdlib.go:177:35:177:52 | call to RequestURI | semmle.label | call to RequestURI | | stdlib.go:186:13:186:33 | call to FormValue | semmle.label | call to FormValue | | stdlib.go:188:23:188:28 | target | semmle.label | target | -| stdlib.go:194:3:194:8 | definition of target | semmle.label | definition of target | | stdlib.go:194:3:194:57 | ... := ...[0] | semmle.label | ... := ...[0] | | stdlib.go:194:36:194:56 | call to FormValue | semmle.label | call to FormValue | | stdlib.go:196:23:196:28 | implicit dereference | semmle.label | implicit dereference | | stdlib.go:196:23:196:28 | target | semmle.label | target | +| stdlib.go:196:23:196:28 | target [postupdate] | semmle.label | target [postupdate] | | stdlib.go:196:23:196:33 | selection of Path | semmle.label | selection of Path | | stdlib.go:198:23:198:28 | target | semmle.label | target | | stdlib.go:198:23:198:42 | call to EscapedPath | semmle.label | call to EscapedPath | diff --git a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 1fa5431811b..188abc9c7f9 100644 --- a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -37,12 +37,7 @@ edges | tst.go:10:13:10:35 | call to FormValue | tst.go:38:11:38:29 | ...+... | provenance | Src:MaD:1 | | tst.go:10:13:10:35 | call to FormValue | tst.go:40:11:40:40 | ...+... | provenance | Src:MaD:1 | | tst.go:10:13:10:35 | call to FormValue | tst.go:47:11:47:18 | tainted2 | provenance | Src:MaD:1 | -| tst.go:46:2:46:2 | definition of u [pointer] | tst.go:47:2:47:2 | u [pointer] | provenance | | -| tst.go:47:2:47:2 | implicit dereference | tst.go:46:2:46:2 | definition of u [pointer] | provenance | | -| tst.go:47:2:47:2 | implicit dereference | tst.go:47:2:47:2 | u | provenance | | -| tst.go:47:2:47:2 | u | tst.go:47:2:47:2 | implicit dereference | provenance | | | tst.go:47:2:47:2 | u | tst.go:48:11:48:11 | u | provenance | | -| tst.go:47:2:47:2 | u [pointer] | tst.go:47:2:47:2 | implicit dereference | provenance | | | tst.go:47:11:47:18 | tainted2 | tst.go:47:2:47:2 | u | provenance | Config | | tst.go:47:11:47:18 | tainted2 | tst.go:48:11:48:11 | u | provenance | Config | | tst.go:48:11:48:11 | u | tst.go:48:11:48:20 | call to String | provenance | MaD:3 | @@ -75,10 +70,7 @@ nodes | tst.go:36:18:36:24 | tainted | semmle.label | tainted | | tst.go:38:11:38:29 | ...+... | semmle.label | ...+... | | tst.go:40:11:40:40 | ...+... | semmle.label | ...+... | -| tst.go:46:2:46:2 | definition of u [pointer] | semmle.label | definition of u [pointer] | -| tst.go:47:2:47:2 | implicit dereference | semmle.label | implicit dereference | | tst.go:47:2:47:2 | u | semmle.label | u | -| tst.go:47:2:47:2 | u [pointer] | semmle.label | u [pointer] | | tst.go:47:11:47:18 | tainted2 | semmle.label | tainted2 | | tst.go:48:11:48:11 | u | semmle.label | u | | tst.go:48:11:48:20 | call to String | semmle.label | call to String | From ac71f9cd8e861176f5f2e057c6ca775274333cf1 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 16 Sep 2025 16:42:47 +0100 Subject: [PATCH 31/70] Expected change in test output These sources are now modeled using models-as-data, which (probably correctly) uses the post-update node as the source. But the deprecated QL models still exist, so we get two test results for each of these calls. --- .../semmle/go/frameworks/Fasthttp/fasthttp.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go index c25c9d01058..061f50355d5 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go @@ -169,10 +169,10 @@ func fasthttpServer() { fmt.Println(body1, body2, body3, body4) requestCtx.Request.BodyStream() // $ RemoteFlowSource="call to BodyStream" - requestCtx.Request.ReadBody(&bufio.Reader{}, 100, 1000) // $ RemoteFlowSource="&..." - requestCtx.Request.ReadLimitBody(&bufio.Reader{}, 100) // $ RemoteFlowSource="&..." - requestCtx.Request.ContinueReadBodyStream(&bufio.Reader{}, 100, true) // $ RemoteFlowSource="&..." - requestCtx.Request.ContinueReadBody(&bufio.Reader{}, 100) // $ RemoteFlowSource="&..." + requestCtx.Request.ReadBody(&bufio.Reader{}, 100, 1000) // $ RemoteFlowSource="&..." RemoteFlowSource="&... [postupdate]" + requestCtx.Request.ReadLimitBody(&bufio.Reader{}, 100) // $ RemoteFlowSource="&..." RemoteFlowSource="&... [postupdate]" + requestCtx.Request.ContinueReadBodyStream(&bufio.Reader{}, 100, true) // $ RemoteFlowSource="&..." RemoteFlowSource="&... [postupdate]" + requestCtx.Request.ContinueReadBody(&bufio.Reader{}, 100) // $ RemoteFlowSource="&..." RemoteFlowSource="&... [postupdate]" // Response methods // Xss Sinks Related method From 3229630598724aa70de5417c2f5d323827ea7edf Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 16 Sep 2025 21:57:40 +0100 Subject: [PATCH 32/70] Make store step to send stmt's channel use post-update node --- .../semmle/go/dataflow/internal/ContainerFlow.qll | 6 ++++-- .../semmle/go/dataflow/ChannelField/test.expected | 14 +++----------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll b/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll index 9f07693b7ea..8a17ed1a78f 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll @@ -36,8 +36,10 @@ predicate containerStoreStep(Node node1, Node node2, Content c) { ) or c instanceof CollectionContent and - exists(SendStmt send | - send.getChannel() = node2.(ExprNode).asExpr() and send.getValue() = node1.(ExprNode).asExpr() + exists(SendStmt send, Node channelExprNode | + send.getChannel() = channelExprNode.(ExprNode).asExpr() and + node2.(PostUpdateNode).getPreUpdateNode() = channelExprNode and + send.getValue() = node1.(ExprNode).asExpr() ) or c instanceof MapKeyContent and diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ChannelField/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/ChannelField/test.expected index 547c7b25da1..6936b333cf1 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ChannelField/test.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ChannelField/test.expected @@ -1,22 +1,14 @@ invalidModelRow edges | test.go:9:9:9:11 | selection of c [collection] | test.go:9:7:9:11 | <-... | provenance | | -| test.go:13:16:13:16 | definition of s [pointer, c, collection] | test.go:16:2:16:2 | s [pointer, c, collection] | provenance | | | test.go:15:10:15:17 | call to source | test.go:16:9:16:12 | data | provenance | | -| test.go:16:2:16:2 | implicit dereference [c, collection] | test.go:13:16:13:16 | definition of s [pointer, c, collection] | provenance | | -| test.go:16:2:16:2 | implicit dereference [c, collection] | test.go:16:2:16:4 | selection of c [collection] | provenance | | -| test.go:16:2:16:2 | s [pointer, c, collection] | test.go:16:2:16:2 | implicit dereference [c, collection] | provenance | | -| test.go:16:2:16:4 | selection of c [collection] | test.go:9:9:9:11 | selection of c [collection] | provenance | | -| test.go:16:2:16:4 | selection of c [collection] | test.go:16:2:16:2 | implicit dereference [c, collection] | provenance | | -| test.go:16:9:16:12 | data | test.go:16:2:16:4 | selection of c [collection] | provenance | | +| test.go:16:2:16:4 | selection of c [postupdate] [collection] | test.go:9:9:9:11 | selection of c [collection] | provenance | | +| test.go:16:9:16:12 | data | test.go:16:2:16:4 | selection of c [postupdate] [collection] | provenance | | nodes | test.go:9:7:9:11 | <-... | semmle.label | <-... | | test.go:9:9:9:11 | selection of c [collection] | semmle.label | selection of c [collection] | -| test.go:13:16:13:16 | definition of s [pointer, c, collection] | semmle.label | definition of s [pointer, c, collection] | | test.go:15:10:15:17 | call to source | semmle.label | call to source | -| test.go:16:2:16:2 | implicit dereference [c, collection] | semmle.label | implicit dereference [c, collection] | -| test.go:16:2:16:2 | s [pointer, c, collection] | semmle.label | s [pointer, c, collection] | -| test.go:16:2:16:4 | selection of c [collection] | semmle.label | selection of c [collection] | +| test.go:16:2:16:4 | selection of c [postupdate] [collection] | semmle.label | selection of c [postupdate] [collection] | | test.go:16:9:16:12 | data | semmle.label | data | subpaths #select From 8a3bd8408bd6532993a30b1470011d5a03787739 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 16 Sep 2025 22:03:22 +0100 Subject: [PATCH 33/70] Fix test expectations for Cleartext Logging One spurious alert was removed, one missing alert was added, and some source locations changed. --- .../CWE-312/CleartextLogging.expected | 79 +++++++------------ .../test/query-tests/Security/CWE-312/main.go | 4 +- .../query-tests/Security/CWE-312/overrides.go | 4 +- .../query-tests/Security/CWE-312/passwords.go | 22 +++--- .../query-tests/Security/CWE-312/protobuf.go | 4 +- 5 files changed, 45 insertions(+), 68 deletions(-) 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 90d182b144b..2b96941ce1a 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -41,7 +41,6 @@ | passwords.go:34:14:34:35 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:34:14:34:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | | 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 | | passwords.go:44:14:44:17 | obj2 | passwords.go:21:2:21:9 | definition of password | passwords.go:44:14:44:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:47:14:47:17 | obj3 | passwords.go:21:2:21:9 | definition of password | passwords.go:47:14:47:17 | obj3 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | | passwords.go:51:14:51:27 | fixed_password | passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | $@ flows to a logging call. | passwords.go:50:2:50:15 | definition of fixed_password | Sensitive data returned by an access to fixed_password | | passwords.go:89:14:89:26 | utilityObject | passwords.go:87:16:87:36 | call to make | passwords.go:89:14:89:26 | utilityObject | $@ flows to a logging call. | passwords.go:87:16:87:36 | call to make | Sensitive data returned by an access to passwordSet | | passwords.go:92:23:92:28 | secret | passwords.go:21:2:21:9 | definition of password | passwords.go:92:23:92:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | @@ -175,8 +174,8 @@ edges | main.go:80:17:80:24 | password | main.go:82:12:82:19 | password | provenance | | | main.go:80:17:80:24 | password | main.go:83:17:83:24 | password | provenance | | | main.go:80:17:80:24 | password | main.go:86:19:86:26 | password | provenance | | -| main.go:85:2:85:7 | definition of fields | main.go:87:29:87:34 | fields | provenance | Sink:MaD:2 | -| main.go:86:19:86:26 | password | main.go:85:2:85:7 | definition of fields | provenance | Config | +| main.go:86:2:86:7 | fields [postupdate] | main.go:87:29:87:34 | fields | provenance | Sink:MaD:2 | +| main.go:86:19:86:26 | password | main.go:86:2:86:7 | fields [postupdate] | provenance | Config | | main.go:86:19:86:26 | password | main.go:90:35:90:42 | password | provenance | Sink:MaD:1 | | overrides.go:8:2:8:9 | definition of password | overrides.go:9:9:9:16 | password | provenance | | | overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | provenance | | @@ -188,21 +187,19 @@ edges | passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | | | passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | provenance | Config | | passwords.go:34:28:34:35 | password | passwords.go:42:6:42:13 | password | provenance | | -| passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | | -| passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal | provenance | Config | -| passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | | -| passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal | provenance | Config | +| passwords.go:36:10:38:2 | struct literal [postupdate] | passwords.go:39:14:39:17 | obj1 | provenance | | +| passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal [postupdate] | provenance | Config | +| passwords.go:41:10:43:2 | struct literal [postupdate] | passwords.go:44:14:44:17 | obj2 | provenance | | +| passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal [postupdate] | provenance | Config | | passwords.go:42:6:42:13 | password | passwords.go:48:11:48:18 | password | provenance | | -| passwords.go:46:6:46:9 | definition of obj3 | passwords.go:47:14:47:17 | obj3 | provenance | | -| passwords.go:48:11:48:18 | password | passwords.go:46:6:46:9 | definition of obj3 | provenance | Config | | passwords.go:48:11:48:18 | password | passwords.go:92:23:92:28 | secret | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:102:33:102:40 | password | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:108:34:108:41 | password | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:113:33:113:40 | password | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:123:13:123:20 | password | provenance | | | passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | provenance | | -| passwords.go:86:19:88:2 | struct literal | passwords.go:89:14:89:26 | utilityObject | provenance | | -| passwords.go:87:16:87:36 | call to make | passwords.go:86:19:88:2 | struct literal | provenance | Config | +| passwords.go:86:19:88:2 | struct literal [postupdate] | passwords.go:89:14:89:26 | utilityObject | provenance | | +| passwords.go:87:16:87:36 | call to make | passwords.go:86:19:88:2 | struct literal [postupdate] | provenance | Config | | passwords.go:102:33:102:40 | password | passwords.go:102:15:102:40 | ...+... | provenance | Config | | passwords.go:102:33:102:40 | password | passwords.go:108:34:108:41 | password | provenance | | | passwords.go:102:33:102:40 | password | passwords.go:113:33:113:40 | password | provenance | | @@ -215,22 +212,20 @@ edges | passwords.go:116:6:116:14 | definition of password1 | passwords.go:117:28:117:36 | password1 | provenance | | | passwords.go:117:28:117:36 | password1 | passwords.go:117:28:117:45 | call to String | provenance | Config | | passwords.go:117:28:117:45 | call to String | passwords.go:117:14:117:45 | ...+... | provenance | Config | -| passwords.go:120:12:125:2 | struct literal | passwords.go:127:14:127:19 | config | provenance | | -| passwords.go:120:12:125:2 | struct literal [x] | passwords.go:128:14:128:19 | config [x] | provenance | | -| passwords.go:120:12:125:2 | struct literal [y] | passwords.go:129:14:129:19 | config [y] | provenance | | -| passwords.go:121:13:121:14 | x3 | passwords.go:120:12:125:2 | struct literal | provenance | Config | -| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal | provenance | Config | -| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [x] | provenance | | -| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal | provenance | Config | -| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [y] | provenance | | +| passwords.go:120:12:125:2 | struct literal [postupdate] | passwords.go:127:14:127:19 | config | provenance | | +| passwords.go:120:12:125:2 | struct literal [postupdate] [x] | passwords.go:128:14:128:19 | config [x] | provenance | | +| passwords.go:120:12:125:2 | struct literal [postupdate] [y] | passwords.go:129:14:129:19 | config [y] | provenance | | +| passwords.go:121:13:121:14 | x3 | passwords.go:120:12:125:2 | struct literal [postupdate] | provenance | Config | +| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [postupdate] | provenance | Config | +| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [postupdate] [x] | provenance | | +| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [postupdate] | provenance | Config | +| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [postupdate] [y] | provenance | | | passwords.go:128:14:128:19 | config [x] | passwords.go:128:14:128:21 | selection of x | provenance | | | passwords.go:129:14:129:19 | config [y] | passwords.go:129:14:129:21 | selection of y | provenance | | | protobuf.go:9:2:9:9 | definition of password | protobuf.go:12:22:12:29 | password | provenance | | -| protobuf.go:11:2:11:6 | definition of query [pointer, Description] | protobuf.go:12:2:12:6 | query [pointer, Description] | provenance | | -| protobuf.go:12:2:12:6 | implicit dereference [Description] | protobuf.go:11:2:11:6 | definition of query [pointer, Description] | provenance | | -| protobuf.go:12:2:12:6 | query [pointer, Description] | protobuf.go:12:2:12:6 | implicit dereference [Description] | provenance | | -| protobuf.go:12:2:12:6 | query [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | | -| protobuf.go:12:22:12:29 | password | protobuf.go:12:2:12:6 | implicit dereference [Description] | provenance | | +| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | provenance | | +| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | | +| protobuf.go:12:22:12:29 | password | protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | provenance | | | protobuf.go:14:14:14:18 | query [pointer, Description] | protobuf.go:14:14:14:35 | call to GetDescription | provenance | | | protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | provenance | | | 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] | provenance | | @@ -298,7 +293,7 @@ nodes | main.go:80:17:80:24 | password | semmle.label | password | | main.go:82:12:82:19 | password | semmle.label | password | | main.go:83:17:83:24 | password | semmle.label | password | -| main.go:85:2:85:7 | definition of fields | semmle.label | definition of fields | +| main.go:86:2:86:7 | fields [postupdate] | semmle.label | fields [postupdate] | | main.go:86:19:86:26 | password | semmle.label | password | | main.go:87:29:87:34 | fields | semmle.label | fields | | main.go:90:35:90:42 | password | semmle.label | password | @@ -316,18 +311,16 @@ 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:10:38:2 | struct literal | semmle.label | struct literal | +| passwords.go:36:10:38:2 | struct literal [postupdate] | semmle.label | struct literal [postupdate] | | passwords.go:37:13:37:13 | x | semmle.label | x | | passwords.go:39:14:39:17 | obj1 | semmle.label | obj1 | -| passwords.go:41:10:43:2 | struct literal | semmle.label | struct literal | +| passwords.go:41:10:43:2 | struct literal [postupdate] | semmle.label | struct literal [postupdate] | | 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:50:2:50:15 | definition of fixed_password | semmle.label | definition of fixed_password | | passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password | -| passwords.go:86:19:88:2 | struct literal | semmle.label | struct literal | +| passwords.go:86:19:88:2 | struct literal [postupdate] | semmle.label | struct literal [postupdate] | | passwords.go:87:16:87:36 | call to make | semmle.label | call to make | | passwords.go:89:14:89:26 | utilityObject | semmle.label | utilityObject | | passwords.go:92:23:92:28 | secret | semmle.label | secret | @@ -341,9 +334,9 @@ nodes | passwords.go:117:14:117:45 | ...+... | semmle.label | ...+... | | passwords.go:117:28:117:36 | password1 | semmle.label | password1 | | passwords.go:117:28:117:45 | call to String | semmle.label | call to String | -| passwords.go:120:12:125:2 | struct literal | semmle.label | struct literal | -| passwords.go:120:12:125:2 | struct literal [x] | semmle.label | struct literal [x] | -| passwords.go:120:12:125:2 | struct literal [y] | semmle.label | struct literal [y] | +| passwords.go:120:12:125:2 | struct literal [postupdate] | semmle.label | struct literal [postupdate] | +| passwords.go:120:12:125:2 | struct literal [postupdate] [x] | semmle.label | struct literal [postupdate] [x] | +| passwords.go:120:12:125:2 | struct literal [postupdate] [y] | semmle.label | struct literal [postupdate] [y] | | passwords.go:121:13:121:14 | x3 | semmle.label | x3 | | passwords.go:123:13:123:20 | password | semmle.label | password | | passwords.go:124:13:124:25 | call to getPassword | semmle.label | call to getPassword | @@ -353,9 +346,8 @@ nodes | passwords.go:129:14:129:19 | config [y] | semmle.label | config [y] | | passwords.go:129:14:129:21 | selection of y | semmle.label | selection of y | | protobuf.go:9:2:9:9 | definition of password | semmle.label | definition of password | -| protobuf.go:11:2:11:6 | definition of query [pointer, Description] | semmle.label | definition of query [pointer, Description] | -| protobuf.go:12:2:12:6 | implicit dereference [Description] | semmle.label | implicit dereference [Description] | -| protobuf.go:12:2:12:6 | query [pointer, Description] | semmle.label | query [pointer, Description] | +| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | semmle.label | implicit dereference [postupdate] [Description] | +| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | semmle.label | query [postupdate] [pointer, Description] | | protobuf.go:12:22:12:29 | password | semmle.label | password | | protobuf.go:14:14:14:18 | query [pointer, Description] | semmle.label | query [pointer, Description] | | protobuf.go:14:14:14:35 | call to GetDescription | semmle.label | call to GetDescription | @@ -365,18 +357,3 @@ nodes | protos/query/query.pb.go:119:10:119:22 | selection of Description | semmle.label | selection of Description | subpaths | 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 | -testFailures -| main.go:17:2:17:9 | definition of password | Unexpected result: Source | -| main.go:87:29:87:34 | fields | Unexpected result: Alert | -| overrides.go:8:2:8:9 | definition of password | Unexpected result: Source | -| overrides.go:9:18:9:28 | comment | Missing result: Source | -| passwords.go:21:2:21:9 | definition of password | Unexpected result: Source | -| passwords.go:30:18:30:28 | comment | Missing result: Source | -| passwords.go:42:16:42:26 | comment | Missing result: Source | -| passwords.go:48:20:48:30 | comment | Missing result: Source | -| passwords.go:50:2:50:15 | definition of fixed_password | Unexpected result: Source | -| passwords.go:91:31:91:41 | comment | Missing result: Source | -| passwords.go:116:6:116:14 | definition of password1 | Unexpected result: Source | -| passwords.go:123:28:123:38 | comment | Missing result: Source | -| protobuf.go:9:2:9:9 | definition of password | Unexpected result: Source | -| protobuf.go:12:31:12:41 | comment | Missing result: Source | diff --git a/go/ql/test/query-tests/Security/CWE-312/main.go b/go/ql/test/query-tests/Security/CWE-312/main.go index 0372fc2df14..e30a8182265 100644 --- a/go/ql/test/query-tests/Security/CWE-312/main.go +++ b/go/ql/test/query-tests/Security/CWE-312/main.go @@ -14,7 +14,7 @@ import ( var i int = rand.Int() func main() { - password := "P4ssw0rd" + password := "P4ssw0rd" // $ Source log.Print(password) // $ Alert log.Printf("%s", password) // $ Alert @@ -84,7 +84,7 @@ func main() { fields := make(logrus.Fields) fields["pass"] = password - entry := logrus.WithFields(fields) + entry := logrus.WithFields(fields) // $ Alert entry.Errorf("") entry = logrus.WithField("pass", password) // $ Alert diff --git a/go/ql/test/query-tests/Security/CWE-312/overrides.go b/go/ql/test/query-tests/Security/CWE-312/overrides.go index 98fbdad9e77..4ac9401d2c0 100644 --- a/go/ql/test/query-tests/Security/CWE-312/overrides.go +++ b/go/ql/test/query-tests/Security/CWE-312/overrides.go @@ -5,8 +5,8 @@ import "fmt" type s struct{} func (_ s) String() string { - password := "horsebatterystaplecorrect" - return password // $ Source + password := "horsebatterystaplecorrect" // $ Source + return password } func overrideTest(x s, y fmt.Stringer) { diff --git a/go/ql/test/query-tests/Security/CWE-312/passwords.go b/go/ql/test/query-tests/Security/CWE-312/passwords.go index 6be68be7265..38c977e41b8 100644 --- a/go/ql/test/query-tests/Security/CWE-312/passwords.go +++ b/go/ql/test/query-tests/Security/CWE-312/passwords.go @@ -18,7 +18,7 @@ func redact(kind, value string) string { func test() { name := "user" - password := "P@ssw0rd" + password := "P@ssw0rd" // $ Source x := "horsebatterystapleincorrect" var o passStruct @@ -27,7 +27,7 @@ func test() { log.Println(getPassword()) // $ Alert log.Println(o.getPassword()) // $ Alert - myLog(password) // $ Source + myLog(password) log.Panic(password) // $ Alert @@ -39,16 +39,16 @@ func test() { log.Println(obj1) // $ Alert obj2 := xStruct{ - x: password, // $ Source + x: password, } log.Println(obj2) // $ Alert var obj3 xStruct - log.Println(obj3) // $ SPURIOUS: Alert // caught because of the below line and def-use flow - obj3.x = password // $ Source + log.Println(obj3) + obj3.x = password - fixed_password := "cowbatterystaplecorrect" - log.Println(fixed_password) // $ Alert // Probably OK + fixed_password := "cowbatterystaplecorrect" // $ Source + log.Println(fixed_password) // $ Alert // Probably OK log.Println(IncorrectPasswordError) // OK @@ -88,7 +88,7 @@ func test() { } log.Println(utilityObject) // $ Alert - secret := password // $ Source + secret := password log.Printf("pw: %s", secret) // $ Alert log.Println("Password is: " + redact("password", password)) @@ -113,14 +113,14 @@ func test() { log.Println("Password is: " + password) // $ SPURIOUS: Alert } - var password1 stringable = stringable{"arstneio"} - log.Println(name + ", " + password1.String()) // $ Alert + var password1 stringable = stringable{"arstneio"} // $ Source + log.Println(name + ", " + password1.String()) // $ Alert x3 := "sheepbatterystaplecorrect" config := Config{ password: x3, // $ Source hostname: "tarski", - x: password, // $ Source + x: password, y: getPassword(), // $ Source } log.Println(config.hostname) // OK diff --git a/go/ql/test/query-tests/Security/CWE-312/protobuf.go b/go/ql/test/query-tests/Security/CWE-312/protobuf.go index a995f0d7cb8..3609410e2b0 100644 --- a/go/ql/test/query-tests/Security/CWE-312/protobuf.go +++ b/go/ql/test/query-tests/Security/CWE-312/protobuf.go @@ -6,10 +6,10 @@ import ( ) func testProtobuf() { - password := "P@ssw0rd" + password := "P@ssw0rd" // $ Source query := &query.Query{} - query.Description = password // $ Source + query.Description = password log.Println(query.GetDescription()) // $ Alert log.Println(query.GetId()) // OK From cf6cfe2a1e2e1ced3108d3eb3d876c528346a031 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 17 Sep 2025 16:43:07 +0100 Subject: [PATCH 34/70] Non-initializing writes should target post-update nodes --- .../go/controlflow/ControlFlowGraph.qll | 40 +++++-- go/ql/lib/semmle/go/controlflow/IR.qll | 14 ++- .../go/dataflow/internal/ContainerFlow.qll | 6 +- .../go/dataflow/internal/DataFlowPrivate.qll | 2 +- .../go/dataflow/internal/FlowSummaryImpl.qll | 11 +- .../dataflow/internal/TaintTrackingUtil.qll | 2 +- go/ql/lib/semmle/go/frameworks/GinCors.qll | 44 +++++--- go/ql/lib/semmle/go/frameworks/NoSQL.qll | 5 +- go/ql/lib/semmle/go/frameworks/Protobuf.qll | 12 +- go/ql/lib/semmle/go/frameworks/RsCors.qll | 33 ++++-- .../semmle/go/frameworks/stdlib/NetHttp.qll | 8 +- .../semmle/go/security/CleartextLogging.qll | 4 +- .../semmle/go/security/OpenUrlRedirect.qll | 6 +- .../OpenUrlRedirectCustomizations.qll | 5 +- .../lib/semmle/go/security/RequestForgery.qll | 8 +- go/ql/lib/semmle/go/security/SafeUrlFlow.qll | 15 ++- go/ql/src/RedundantCode/DeadStoreOfField.ql | 5 +- .../CWE-295/DisabledCertificateCheck.ql | 2 +- .../CWE-322/InsecureHostKeyCallback.ql | 11 +- go/ql/src/Security/CWE-327/InsecureTLS.ql | 12 +- .../Security/CWE-352/ConstantOauth2State.ql | 2 +- .../src/experimental/CWE-1004/AuthCookie.qll | 19 ++-- go/ql/src/experimental/CWE-918/SSRF.qll | 8 +- .../example-tests/snippets/typeinfo.expected | 1 + .../CWE-1004/CookieWithoutHttpOnly.expected | 105 ++++++++---------- .../dataflow/FlowSteps/LocalFlowStep.expected | 15 +++ .../FlowSteps/LocalTaintStep.expected | 6 +- .../PromotedFields/LocalFlowStep.expected | 30 +++++ .../ReadsAndWrites/writesElement.expected | 6 +- .../ReadsAndWrites/writesField.expected | 6 +- .../go/frameworks/Email/EmailData.expected | 3 + .../frameworks/GoMicro/LogInjection.expected | 18 --- .../frameworks/TaintSteps/TaintStep.expected | 14 +-- .../CWE-078/CommandInjection.expected | 36 +++--- .../Security/CWE-089/SqlInjection.expected | 57 ++++------ .../CWE-295/DisabledCertificateCheck/main.go | 21 +++- .../CWE-312/CleartextLogging.expected | 40 +++---- 37 files changed, 374 insertions(+), 258 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index 37be62f3710..58a3ae3d44e 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -118,6 +118,8 @@ module ControlFlow { /** Gets the left-hand side of this write. */ IR::WriteTarget getLhs() { result = super.getLhs() } + private predicate isInitialization() { super.isInitialization() } + /** Gets the right-hand side of this write. */ DataFlow::Node getRhs() { super.getRhs() = result.asInstruction() } @@ -134,13 +136,20 @@ module ControlFlow { * Holds if this node sets the value of field `f` on `base` (or its implicit dereference) to * `rhs`. * - * For example, for the assignment `x.width = newWidth`, `base` is either the data-flow node - * corresponding to `x` or (if `x` is a pointer) the data-flow node corresponding to the - * implicit dereference `*x`, `f` is the field referenced by `width`, and `rhs` is the data-flow - * node corresponding to `newWidth`. + * For example, for the assignment `x.width = newWidth`, `base` is the post-update node of + * either the data-flow node corresponding to `x` or (if `x` is a pointer) the data-flow node + * corresponding to the implicit dereference `*x`, `f` is the field referenced by `width`, and + * `rhs` is the data-flow node corresponding to `newWidth`. If this `WriteNode` is a struct + * initialization then there is no need for a post-update node and `base` is the struct literal + * being initialized. */ predicate writesField(DataFlow::Node base, Field f, DataFlow::Node rhs) { - this.writesFieldInsn(base.asInstruction(), f, rhs.asInstruction()) + exists(DataFlow::Node b | this.writesFieldInsn(b.asInstruction(), f, rhs.asInstruction()) | + this.isInitialization() and base = b + or + not this.isInitialization() and + b = base.(DataFlow::PostUpdateNode).getPreUpdateNode() + ) } private predicate writesFieldInsn(IR::Instruction base, Field f, IR::Instruction rhs) { @@ -158,13 +167,22 @@ module ControlFlow { * Holds if this node sets the value of element `index` on `base` (or its implicit dereference) * to `rhs`. * - * For example, for the assignment `xs[i] = v`, `base` is either the data-flow node - * corresponding to `xs` or (if `xs` is a pointer) the data-flow node corresponding to the - * implicit dereference `*xs`, `index` is the data-flow node corresponding to `i`, and `rhs` - * is the data-flow node corresponding to `base`. + * For example, for the assignment `xs[i] = v`, `base` is the post-update node of the data-flow + * node corresponding to `xs` or (if `xs` is a pointer) the implicit dereference `*xs`, `index` + * is the data-flow node corresponding to `i`, and `rhs` is the data-flow node corresponding to + * `base`. If this `WriteNode` corresponds to the initialization of an array/slice/map then + * there is no need for a post-update node and `base` is the array/slice/map literal being + * initialized. */ predicate writesElement(DataFlow::Node base, DataFlow::Node index, DataFlow::Node rhs) { - this.writesElementInsn(base.asInstruction(), index.asInstruction(), rhs.asInstruction()) + exists(DataFlow::Node b | + this.writesElementInsn(b.asInstruction(), index.asInstruction(), rhs.asInstruction()) + | + this.isInitialization() and base = b + or + not this.isInitialization() and + b = base.(DataFlow::PostUpdateNode).getPreUpdateNode() + ) } private predicate writesElementInsn( @@ -184,7 +202,7 @@ module ControlFlow { * Holds if this node sets any field or element of `base` to `rhs`. */ predicate writesComponent(DataFlow::Node base, DataFlow::Node rhs) { - this.writesComponentInstruction(base.asInstruction(), rhs.asInstruction()) + this.writesElement(base, _, rhs) or this.writesField(base, _, rhs) } /** diff --git a/go/ql/lib/semmle/go/controlflow/IR.qll b/go/ql/lib/semmle/go/controlflow/IR.qll index 1a56dfcf2dc..2b8a30437bb 100644 --- a/go/ql/lib/semmle/go/controlflow/IR.qll +++ b/go/ql/lib/semmle/go/controlflow/IR.qll @@ -430,18 +430,24 @@ module IR { */ class WriteInstruction extends Instruction { WriteTarget lhs; + Boolean initialization; WriteInstruction() { - lhs = MkLhs(this, _) + ( + lhs = MkLhs(this, _) + or + lhs = MkResultWriteTarget(this) + ) and + initialization = false or - lhs = MkLiteralElementTarget(this) - or - lhs = MkResultWriteTarget(this) + lhs = MkLiteralElementTarget(this) and initialization = true } /** Gets the target to which this instruction writes. */ WriteTarget getLhs() { result = lhs } + predicate isInitialization() { initialization = true } + /** Gets the instruction computing the value this instruction writes. */ Instruction getRhs() { none() } diff --git a/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll b/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll index 8a17ed1a78f..e978cb3e587 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll @@ -22,7 +22,7 @@ predicate containerStoreStep(Node node1, Node node2, Content c) { t instanceof SliceType ) and ( - exists(Write w | w.writesElement(node2.(PostUpdateNode).getPreUpdateNode(), _, node1)) + exists(Write w | w.writesElement(node2, _, node1)) or node1 = node2.(ImplicitVarargsSlice).getCallNode().getAnImplicitVarargsArgument() or @@ -44,11 +44,11 @@ predicate containerStoreStep(Node node1, Node node2, Content c) { or c instanceof MapKeyContent and t instanceof MapType and - exists(Write w | w.writesElement(node2.(PostUpdateNode).getPreUpdateNode(), node1, _)) + exists(Write w | w.writesElement(node2, node1, _)) or c instanceof MapValueContent and t instanceof MapType and - exists(Write w | w.writesElement(node2.(PostUpdateNode).getPreUpdateNode(), _, node1)) + exists(Write w | w.writesElement(node2, _, node1)) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 7ca942fdf59..613441f9868 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -156,7 +156,7 @@ predicate storeStep(Node node1, ContentSet cs, Node node2) { // which in turn flows into the pointer content of `p` exists(Write w, Field f, DataFlow::Node base, DataFlow::Node rhs | w.writesField(base, f, rhs) | node1 = rhs and - node2.(PostUpdateNode).getPreUpdateNode() = base and + node2 = base and c = any(DataFlow::FieldContent fc | fc.getField() = f) or node1 = base and diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 496870286e9..a7dfbab15c2 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -437,13 +437,20 @@ module SourceSinkInterpretationInput implements mid.asCallable() = getNodeEnclosingCallable(ret) ) or - exists(SourceOrSinkElement e, DataFlow::Write fw, DataFlow::Node base, Field f | + exists( + SourceOrSinkElement e, DataFlow::Write fw, DataFlow::Node base, DataFlow::Node qual, Field f + | e = mid.asElement() and f = e.asFieldEntity() | c = "" and fw.writesField(base, f, node.asNode()) and - pragma[only_bind_into](e) = getElementWithQualifier(f, base) + pragma[only_bind_into](e) = getElementWithQualifier(f, qual) and + ( + qual = base.(PostUpdateNode).getPreUpdateNode() + or + not base instanceof PostUpdateNode and qual = base + ) ) or // A package-scope (or universe-scope) variable diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 05cb663f7be..ff5b4f74e77 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -144,7 +144,7 @@ predicate referenceStep(DataFlow::Node pred, DataFlow::Node succ) { * `succ`. */ predicate elementWriteStep(DataFlow::Node pred, DataFlow::Node succ) { - any(DataFlow::Write w).writesElement(succ.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, pred) + any(DataFlow::Write w).writesElement(succ, _, pred) or FlowSummaryImpl::Private::Steps::summaryStoreStep(pred.(DataFlowPrivate::FlowSummaryNode) .getSummaryNode(), any(DataFlow::ArrayContent ac).asContentSet(), diff --git a/go/ql/lib/semmle/go/frameworks/GinCors.qll b/go/ql/lib/semmle/go/frameworks/GinCors.qll index 582ea368073..a26ab2eaa12 100644 --- a/go/ql/lib/semmle/go/frameworks/GinCors.qll +++ b/go/ql/lib/semmle/go/frameworks/GinCors.qll @@ -25,10 +25,15 @@ module GinCors { DataFlow::Node base; AllowCredentialsWrite() { - exists(Field f, Write w | + exists(Field f, Write w, DataFlow::Node n | f.hasQualifiedName(packagePath(), "Config", "AllowCredentials") and - w.writesField(base, f, this) and - this.getType() instanceof BoolType + w.writesField(n, f, this) and + this.getType() instanceof BoolType and + ( + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) ) } @@ -59,10 +64,15 @@ module GinCors { DataFlow::Node base; AllowOriginsWrite() { - exists(Field f, Write w | + exists(Field f, Write w, DataFlow::Node n | f.hasQualifiedName(packagePath(), "Config", "AllowOrigins") and - w.writesField(base, f, this) and - this.asExpr() instanceof SliceLit + w.writesField(n, f, this) and + this.asExpr() instanceof SliceLit and + ( + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) ) } @@ -93,10 +103,15 @@ module GinCors { DataFlow::Node base; AllowAllOriginsWrite() { - exists(Field f, Write w | + exists(Field f, Write w, DataFlow::Node n | f.hasQualifiedName(packagePath(), "Config", "AllowAllOrigins") and - w.writesField(base, f, this) and - this.getType() instanceof BoolType + w.writesField(n, f, this) and + this.getType() instanceof BoolType and + ( + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) ) } @@ -109,14 +124,9 @@ module GinCors { * Get config variable holding header values */ override GinConfig getConfig() { - exists(GinConfig gc | - ( - gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() = - base.asInstruction() or - gc.getV().getAUse() = base - ) and - result = gc - ) + result.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() = + base.asInstruction() or + result.getV().getAUse() = base } } diff --git a/go/ql/lib/semmle/go/frameworks/NoSQL.qll b/go/ql/lib/semmle/go/frameworks/NoSQL.qll index 36932149628..5fa155395fc 100644 --- a/go/ql/lib/semmle/go/frameworks/NoSQL.qll +++ b/go/ql/lib/semmle/go/frameworks/NoSQL.qll @@ -38,9 +38,8 @@ module NoSql { */ predicate isAdditionalMongoTaintStep(DataFlow::Node pred, DataFlow::Node succ) { // Taint an entry if the `Value` is tainted - exists(Write w, DataFlow::Node base, Field f | w.writesField(base, f, pred) | - base = succ.(DataFlow::PostUpdateNode).getPreUpdateNode() and - base.getType().hasQualifiedName(package("go.mongodb.org/mongo-driver", "bson/primitive"), "E") and + exists(Write w, Field f | w.writesField(succ, f, pred) | + succ.getType().hasQualifiedName(package("go.mongodb.org/mongo-driver", "bson/primitive"), "E") and f.getName() = "Value" ) } diff --git a/go/ql/lib/semmle/go/frameworks/Protobuf.qll b/go/ql/lib/semmle/go/frameworks/Protobuf.qll index 550f9917560..4103815e7d2 100644 --- a/go/ql/lib/semmle/go/frameworks/Protobuf.qll +++ b/go/ql/lib/semmle/go/frameworks/Protobuf.qll @@ -64,11 +64,10 @@ module Protobuf { */ private class MarshalStateStep extends TaintTracking::AdditionalTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { - exists(DataFlow::PostUpdateNode marshalInput, DataFlow::CallNode marshalStateCall | + exists(DataFlow::Node marshalInput, DataFlow::CallNode marshalStateCall | marshalStateCall = marshalStateMethod().getACall() and // pred -> marshalInput.Message - any(DataFlow::Write w) - .writesField(marshalInput.getPreUpdateNode(), inputMessageField(), pred) and + any(DataFlow::Write w).writesField(marshalInput, inputMessageField(), pred) and // marshalInput -> marshalStateCall marshalStateCall.getArgument(0) = globalValueNumber(marshalInput).getANode() and // marshalStateCall -> succ @@ -142,10 +141,13 @@ module Protobuf { private class WriteMessageFieldStep extends TaintTracking::AdditionalTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { [succ.getType(), succ.getType().getPointerType()] instanceof MessageType and - exists(DataFlow::ReadNode base | + exists(DataFlow::Node n, DataFlow::ReadNode base | succ.(DataFlow::PostUpdateNode).getPreUpdateNode() = getUnderlyingNode(base) | - any(DataFlow::Write w).writesComponent(base, pred) + any(DataFlow::Write w).writesComponent(n, pred) and + // The below line only works because `base`'s type, `DataFlow::ReadNode`, + // is incompatible with `DataFlow::PostUpdateNode`. + base = [n, n.(DataFlow::PostUpdateNode).getPreUpdateNode()] ) } } diff --git a/go/ql/lib/semmle/go/frameworks/RsCors.qll b/go/ql/lib/semmle/go/frameworks/RsCors.qll index b9cee2aa459..aa49df3c432 100644 --- a/go/ql/lib/semmle/go/frameworks/RsCors.qll +++ b/go/ql/lib/semmle/go/frameworks/RsCors.qll @@ -52,10 +52,15 @@ module RsCors { DataFlow::Node base; AllowCredentialsWrite() { - exists(Field f, Write w | + exists(Field f, Write w, DataFlow::Node n | f.hasQualifiedName(packagePath(), "Options", "AllowCredentials") and - w.writesField(base, f, this) and - this.getType() instanceof BoolType + w.writesField(n, f, this) and + this.getType() instanceof BoolType and + ( + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) ) } @@ -80,10 +85,15 @@ module RsCors { DataFlow::Node base; AllowOriginsWrite() { - exists(Field f, Write w | + exists(Field f, Write w, DataFlow::Node n | f.hasQualifiedName(packagePath(), "Options", "AllowedOrigins") and - w.writesField(base, f, this) and - this.asExpr() instanceof SliceLit + w.writesField(n, f, this) and + this.asExpr() instanceof SliceLit and + ( + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) ) } @@ -111,10 +121,15 @@ module RsCors { DataFlow::Node base; AllowAllOriginsWrite() { - exists(Field f, Write w | + exists(Field f, Write w, DataFlow::Node n | f.hasQualifiedName(packagePath(), "Options", "AllowAllOrigins") and - w.writesField(base, f, this) and - this.getType() instanceof BoolType + w.writesField(n, f, this) and + this.getType() instanceof BoolType and + ( + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) ) } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll index 9a917f05ff5..0ba122006e6 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll @@ -52,7 +52,13 @@ module NetHttp { MapWrite() { this.getType().hasQualifiedName("net/http", "Header") and - any(Write write).writesElement(this, index, rhs) + exists(Write write, DataFlow::Node base | + write.writesElement(base, index, rhs) and + // The following line works because `Http::HeaderWrite::Range` extends + // `DataFlow::ExprNode`, which is incompatible with + // `DataFlow::PostUpdateNode`. + this = [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] + ) } override DataFlow::Node getName() { result = index } diff --git a/go/ql/lib/semmle/go/security/CleartextLogging.qll b/go/ql/lib/semmle/go/security/CleartextLogging.qll index 5218d03d908..5254b3e3a29 100644 --- a/go/ql/lib/semmle/go/security/CleartextLogging.qll +++ b/go/ql/lib/semmle/go/security/CleartextLogging.qll @@ -35,9 +35,7 @@ module CleartextLogging { 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) - ) + exists(Write write | write.writesField(trg, _, 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. diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll index 1d2d7a1c60b..e2495055fdc 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll @@ -33,8 +33,8 @@ module OpenUrlRedirect { any(AdditionalStep s).hasTaintStep(pred, succ) or // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() + exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | + w.writesField(succ, f, pred) ) or // propagate out of most URL fields, but not `ForceQuery` and `Scheme` @@ -49,7 +49,7 @@ module OpenUrlRedirect { predicate isBarrierOut(DataFlow::Node node) { // block propagation of this unsafe value when its host is overwritten exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(node.getASuccessor(), f, _) + w.writesField(node.(DataFlow::PostUpdateNode).getPreUpdateNode(), f, _) ) or hostnameSanitizingPrefixEdge(node, _) diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index c278bdf58c5..48d027d49fa 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -90,9 +90,10 @@ module OpenUrlRedirect { */ class PathAssignmentBarrier extends Barrier, Read { PathAssignmentBarrier() { - exists(Write w, SsaWithFields var | + exists(Write w, DataFlow::Node base, SsaWithFields var | hasHostnameSanitizingSubstring(w.getRhs()) and - w.writesField(var.getAUse(), any(Field f | f.getName() = "Path"), _) and + w.writesField(base, any(Field f | f.getName() = "Path"), _) and + [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = var.getAUse() and useIsDominated(var, w, this) ) } diff --git a/go/ql/lib/semmle/go/security/RequestForgery.qll b/go/ql/lib/semmle/go/security/RequestForgery.qll index 176b67403e6..8508d0dda96 100644 --- a/go/ql/lib/semmle/go/security/RequestForgery.qll +++ b/go/ql/lib/semmle/go/security/RequestForgery.qll @@ -27,8 +27,12 @@ module RequestForgery { predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() + exists(Write w, DataFlow::Node base, Field f, SsaWithFields v | + f.hasQualifiedName("net/url", "URL", "Host") + | + w.writesField(base, f, pred) and + [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = v.getAUse() and + succ = v.getAUse() ) } diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll index 1fc39072dfb..e53214955d5 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll @@ -23,17 +23,20 @@ module SafeUrlFlow { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, node1) and node2 = v.getAUse() + exists(Write w, DataFlow::Node base, Field f, SsaWithFields v | + f.hasQualifiedName("net/url", "URL", "Host") + | + w.writesField(base, f, node1) and + [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = v.getAUse() and + node2 = v.getAUse() ) } predicate isBarrierOut(DataFlow::Node node) { // block propagation of this safe value when its host is overwritten - exists(Write w, DataFlow::Node b, Field f | - f.hasQualifiedName("net/url", "URL", "Host") and - b = node.getASuccessor() and - w.writesField(b, f, _) + exists(Write w, DataFlow::Node base, Field f | f.hasQualifiedName("net/url", "URL", "Host") | + w.writesField(base, f, _) and + [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = node.getASuccessor() ) or node instanceof SanitizerEdge diff --git a/go/ql/src/RedundantCode/DeadStoreOfField.ql b/go/ql/src/RedundantCode/DeadStoreOfField.ql index be3a77d3ac7..3f757cd8b54 100644 --- a/go/ql/src/RedundantCode/DeadStoreOfField.ql +++ b/go/ql/src/RedundantCode/DeadStoreOfField.ql @@ -86,10 +86,11 @@ Type getTypeEmbeddedViaPointer(Type t) { result = getEmbeddedType*(getEmbeddedType(getEmbeddedType*(t), true)) } -from Write w, LocalVariable v, Field f +from Write w, DataFlow::Node base, LocalVariable v, Field f where // `w` writes `f` on `v` - w.writesField(v.getARead(), f, _) and + w.writesField(base, f, _) and + [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = v.getARead() and // but `f` is never read on `v` not exists(Read r | r.readsField(v.getARead(), f)) and // exclude pointer-typed `v`; there may be reads through an alias diff --git a/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql b/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql index ae83fbce8bc..bc05c8cf4aa 100644 --- a/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql +++ b/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql @@ -34,7 +34,7 @@ predicate becomesPartOf(DataFlow::Node part, DataFlow::Node whole) { or whole.(DataFlow::AddressOperationNode).getOperand() = part or - exists(Write w | w.writesField(whole.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, part)) + exists(Write w | w.writesField(whole, _, part)) } /** diff --git a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql index 5fef1900713..e88b7bf0f95 100644 --- a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql +++ b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql @@ -98,8 +98,15 @@ predicate hostCheckReachesSink(Flow::PathNode sink) { Flow::flowPath(source, otherSink) and Config::writeIsSink(sink.getNode(), sinkWrite) and Config::writeIsSink(otherSink.getNode(), otherSinkWrite) and - sinkWrite.writesField(sinkAccessPath.getAUse(), _, sink.getNode()) and - otherSinkWrite.writesField(otherSinkAccessPath.getAUse(), _, otherSink.getNode()) and + exists(DataFlow::Node base1 | + sinkWrite.writesField(base1, _, sink.getNode()) and + [base1, base1.(DataFlow::PostUpdateNode).getPreUpdateNode()] = sinkAccessPath.getAUse() + ) and + exists(DataFlow::Node base2 | + otherSinkWrite.writesField(base2, _, otherSink.getNode()) and + [base2, base2.(DataFlow::PostUpdateNode).getPreUpdateNode()] = + otherSinkAccessPath.getAUse() + ) and otherSinkAccessPath = sinkAccessPath.similar() ) ) diff --git a/go/ql/src/Security/CWE-327/InsecureTLS.ql b/go/ql/src/Security/CWE-327/InsecureTLS.ql index dba6f2d54ca..66e516a85eb 100644 --- a/go/ql/src/Security/CWE-327/InsecureTLS.ql +++ b/go/ql/src/Security/CWE-327/InsecureTLS.ql @@ -65,7 +65,11 @@ module TlsVersionFlowConfig implements DataFlow::ConfigSig { */ additional predicate isSink(DataFlow::Node sink, Field fld, DataFlow::Node base, Write fieldWrite) { fld.hasQualifiedName("crypto/tls", "Config", ["MinVersion", "MaxVersion"]) and - fieldWrite.writesField(base, fld, sink) + exists(DataFlow::Node n | fieldWrite.writesField(n, fld, sink) | + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) } predicate isSource(DataFlow::Node source) { intIsSource(source, _) } @@ -190,7 +194,11 @@ module TlsInsecureCipherSuitesFlowConfig implements DataFlow::ConfigSig { */ additional predicate isSink(DataFlow::Node sink, Field fld, DataFlow::Node base, Write fieldWrite) { fld.hasQualifiedName("crypto/tls", "Config", "CipherSuites") and - fieldWrite.writesField(base, fld, sink) + exists(DataFlow::Node n | fieldWrite.writesField(n, fld, sink) | + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) } predicate isSink(DataFlow::Node sink) { isSink(sink, _, _, _) } diff --git a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql index 8898a6bb101..501eb6109c7 100644 --- a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql +++ b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql @@ -61,7 +61,7 @@ predicate isUrlTaintingConfigStep(DataFlow::Node pred, DataFlow::Node succ) { exists(Write w, Field f | f.hasQualifiedName(package("golang.org/x/oauth2", ""), "Config", "RedirectURL") | - w.writesField(succ.(DataFlow::PostUpdateNode).getPreUpdateNode(), f, pred) + w.writesField(succ, f, pred) ) } diff --git a/go/ql/src/experimental/CWE-1004/AuthCookie.qll b/go/ql/src/experimental/CWE-1004/AuthCookie.qll index b16f09ac185..2cf8577ac5a 100644 --- a/go/ql/src/experimental/CWE-1004/AuthCookie.qll +++ b/go/ql/src/experimental/CWE-1004/AuthCookie.qll @@ -26,9 +26,14 @@ private class GorillaSessionOptionsField extends Field { * This should cover most typical patterns... */ private DataFlow::Node getValueForFieldWrite(StructLit sl, string field) { - exists(Write w, DataFlow::Node base, Field f | + exists(Write w, DataFlow::Node base, DataFlow::Node n, Field f | f.getName() = field and - w.writesField(base, f, result) and + w.writesField(n, f, result) and + ( + base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() + or + not n instanceof DataFlow::PostUpdateNode and base = n + ) and ( sl = base.asExpr() or @@ -209,10 +214,7 @@ private module GorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSi predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink } predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(GorillaSessionOptionsField f, DataFlow::Write w, DataFlow::Node base | - w.writesField(base, f, pred) and - succ = base - ) + exists(GorillaSessionOptionsField f, DataFlow::Write w | w.writesField(succ, f, pred)) } } @@ -236,10 +238,7 @@ private module BoolToGorillaSessionOptionsTrackingConfig implements DataFlow::Co sl = succ.asExpr() ) or - exists(GorillaSessionOptionsField f, DataFlow::Write w, DataFlow::Node base | - w.writesField(base, f, pred) and - succ = base - ) + exists(GorillaSessionOptionsField f, DataFlow::Write w | w.writesField(succ, f, pred)) } } diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index 05abe7bf8e4..aa4bccb4599 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -22,8 +22,12 @@ module ServerSideRequestForgery { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, node1) and node2 = v.getAUse() + exists(Write w, DataFlow::Node base, Field f, SsaWithFields v | + f.hasQualifiedName("net/url", "URL", "Host") + | + w.writesField(base, f, node1) and + [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = v.getAUse() and + node2 = v.getAUse() ) } diff --git a/go/ql/test/example-tests/snippets/typeinfo.expected b/go/ql/test/example-tests/snippets/typeinfo.expected index 728a1dfc6f7..91ea716693f 100644 --- a/go/ql/test/example-tests/snippets/typeinfo.expected +++ b/go/ql/test/example-tests/snippets/typeinfo.expected @@ -5,3 +5,4 @@ | main.go:18:12:18:14 | argument corresponding to req | | main.go:18:12:18:14 | definition of req | | main.go:20:5:20:7 | req | +| main.go:20:5:20:7 | req [postupdate] | diff --git a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected index 7e8c6406211..355c0a62b1b 100644 --- a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected +++ b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected @@ -154,51 +154,46 @@ edges | CookieWithoutHttpOnly.go:133:14:133:18 | false | CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | provenance | | | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:2:137:8 | session | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | -| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | Config | -| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | Config | -| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | Config | +| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | provenance | Config | | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | | | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | | | CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | session | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:149:2:149:8 | session | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] | provenance | | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | -| CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | Config | -| CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | Config | +| CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] | provenance | Config | | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:149:20:151:2 | &... | provenance | | | CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | provenance | | | CookieWithoutHttpOnly.go:157:14:157:17 | true | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | provenance | | | CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:2:161:8 | session | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | -| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | Config | -| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | Config | -| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | Config | +| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | provenance | Config | | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | | | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | | | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | provenance | Config | @@ -206,20 +201,18 @@ edges | CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | provenance | | | CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | provenance | Config | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:2:173:8 | session | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | -| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | Config | -| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | Config | -| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | Config | +| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | provenance | Config | +| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | provenance | Config | | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | | | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | | | CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | provenance | Config | @@ -356,10 +349,10 @@ nodes | CookieWithoutHttpOnly.go:133:14:133:18 | false | semmle.label | false | | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:134:16:134:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:137:2:137:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:137:2:137:8 | session | semmle.label | session | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | semmle.label | session [postupdate] | +| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | semmle.label | session [postupdate] | | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | semmle.label | &... | @@ -372,8 +365,8 @@ nodes | CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session | | CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:146:16:146:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:149:2:149:8 | session | semmle.label | session | +| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] | semmle.label | session [postupdate] | | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:149:20:151:2 | &... | semmle.label | &... | | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | semmle.label | struct literal | @@ -383,10 +376,10 @@ nodes | CookieWithoutHttpOnly.go:157:14:157:17 | true | semmle.label | true | | CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:158:16:158:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:161:2:161:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:161:2:161:8 | session | semmle.label | session | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | semmle.label | session [postupdate] | +| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | semmle.label | session [postupdate] | | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | semmle.label | &... | @@ -401,10 +394,10 @@ nodes | CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | semmle.label | definition of httpOnly | | CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | semmle.label | ... := ...[0] | | CookieWithoutHttpOnly.go:170:16:170:20 | store | semmle.label | store | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | semmle.label | implicit dereference | -| CookieWithoutHttpOnly.go:173:2:173:8 | session | semmle.label | session | -| CookieWithoutHttpOnly.go:173:2:173:8 | session | semmle.label | session | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | semmle.label | session [postupdate] | +| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | semmle.label | session [postupdate] | | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | semmle.label | &... | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected index cf8a278a903..fcbb78716a4 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected @@ -85,12 +85,15 @@ | main.go:26:11:26:11 | x | main.go:26:2:26:17 | ... := ...[0] | | main.go:38:2:38:2 | definition of s | main.go:39:15:39:15 | s | | main.go:38:7:38:20 | slice literal | main.go:38:2:38:2 | definition of s | +| main.go:38:7:38:20 | slice literal [postupdate] | main.go:38:2:38:2 | definition of s | | main.go:39:2:39:3 | definition of s1 | main.go:40:18:40:19 | s1 | | main.go:39:8:39:25 | call to append | main.go:39:2:39:3 | definition of s1 | | main.go:39:15:39:15 | s | main.go:40:15:40:15 | s | +| main.go:39:15:39:15 | s [postupdate] | main.go:40:15:40:15 | s | | main.go:40:2:40:3 | definition of s2 | main.go:43:9:43:10 | s2 | | main.go:40:8:40:23 | call to append | main.go:40:2:40:3 | definition of s2 | | main.go:40:15:40:15 | s | main.go:42:7:42:7 | s | +| main.go:40:15:40:15 | s [postupdate] | main.go:42:7:42:7 | s | | main.go:41:2:41:3 | definition of s4 | main.go:42:10:42:11 | s4 | | main.go:41:8:41:21 | call to make | main.go:41:2:41:3 | definition of s4 | | main.go:46:13:46:14 | argument corresponding to xs | main.go:46:13:46:14 | definition of xs | @@ -114,6 +117,7 @@ | main.go:55:6:55:7 | definition of ch | main.go:56:2:56:3 | ch | | main.go:55:6:55:7 | zero value for ch | main.go:55:6:55:7 | definition of ch | | main.go:56:2:56:3 | ch | main.go:57:4:57:5 | ch | +| main.go:56:2:56:3 | ch [postupdate] | main.go:57:4:57:5 | ch | | main.go:61:2:61:2 | definition of x | main.go:64:11:64:11 | x | | main.go:61:7:61:7 | 1 | main.go:61:2:61:2 | definition of x | | main.go:62:2:62:2 | definition of y | main.go:64:14:64:14 | y | @@ -165,30 +169,41 @@ | url.go:27:2:27:2 | definition of u | url.go:28:14:28:14 | u | | url.go:27:2:27:30 | ... = ...[0] | url.go:27:2:27:2 | definition of u | | url.go:28:14:28:14 | u | url.go:29:14:29:14 | u | +| url.go:28:14:28:14 | u [postupdate] | url.go:29:14:29:14 | u | | url.go:29:14:29:14 | u | url.go:30:11:30:11 | u | +| url.go:29:14:29:14 | u [postupdate] | url.go:30:11:30:11 | u | | url.go:30:2:30:3 | definition of bs | url.go:31:14:31:15 | bs | | url.go:30:2:30:27 | ... := ...[0] | url.go:30:2:30:3 | definition of bs | | url.go:30:11:30:11 | u | url.go:32:9:32:9 | u | +| url.go:30:11:30:11 | u [postupdate] | url.go:32:9:32:9 | u | | url.go:32:2:32:2 | definition of u | url.go:33:14:33:14 | u | | url.go:32:2:32:23 | ... = ...[0] | url.go:32:2:32:2 | definition of u | | url.go:33:14:33:14 | u | url.go:34:14:34:14 | u | +| url.go:33:14:33:14 | u [postupdate] | url.go:34:14:34:14 | u | | url.go:34:14:34:14 | u | url.go:35:14:35:14 | u | +| url.go:34:14:34:14 | u [postupdate] | url.go:35:14:35:14 | u | | url.go:35:14:35:14 | u | url.go:36:6:36:6 | u | +| url.go:35:14:35:14 | u [postupdate] | url.go:36:6:36:6 | u | | url.go:36:2:36:2 | definition of u | url.go:37:9:37:9 | u | | url.go:36:6:36:6 | u | url.go:36:25:36:25 | u | +| url.go:36:6:36:6 | u [postupdate] | url.go:36:25:36:25 | u | | url.go:36:6:36:26 | call to ResolveReference | url.go:36:2:36:2 | definition of u | | url.go:42:2:42:3 | definition of ui | url.go:43:11:43:12 | ui | | url.go:42:7:42:38 | call to UserPassword | url.go:42:2:42:3 | definition of ui | | url.go:43:2:43:3 | definition of pw | url.go:44:14:44:15 | pw | | url.go:43:2:43:23 | ... := ...[0] | url.go:43:2:43:3 | definition of pw | | url.go:43:11:43:12 | ui | url.go:45:14:45:15 | ui | +| url.go:43:11:43:12 | ui [postupdate] | url.go:45:14:45:15 | ui | | url.go:45:14:45:15 | ui | url.go:46:9:46:10 | ui | +| url.go:45:14:45:15 | ui [postupdate] | url.go:46:9:46:10 | ui | | url.go:49:12:49:12 | argument corresponding to q | url.go:49:12:49:12 | definition of q | | url.go:49:12:49:12 | definition of q | url.go:50:25:50:25 | q | | url.go:50:2:50:2 | definition of v | url.go:51:14:51:14 | v | | url.go:50:2:50:26 | ... := ...[0] | url.go:50:2:50:2 | definition of v | | url.go:51:14:51:14 | v | url.go:52:14:52:14 | v | +| url.go:51:14:51:14 | v [postupdate] | url.go:52:14:52:14 | v | | url.go:52:14:52:14 | v | url.go:53:9:53:9 | v | +| url.go:52:14:52:14 | v [postupdate] | url.go:53:9:53:9 | v | | url.go:56:12:56:12 | argument corresponding to q | url.go:56:12:56:12 | definition of q | | url.go:56:12:56:12 | definition of q | url.go:57:29:57:29 | q | | url.go:57:2:57:8 | definition of joined1 | url.go:58:38:58:44 | joined1 | 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 11b73b0915d..66784562496 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 @@ -1,8 +1,8 @@ | main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[0] | | main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[1] | -| main.go:38:13:38:13 | 1 | main.go:38:7:38:20 | slice literal [postupdate] | -| main.go:38:16:38:16 | 2 | main.go:38:7:38:20 | slice literal [postupdate] | -| main.go:38:19:38:19 | 3 | main.go:38:7:38:20 | slice literal [postupdate] | +| main.go:38:13:38:13 | 1 | main.go:38:7:38:20 | slice literal | +| main.go:38:16:38:16 | 2 | main.go:38:7:38:20 | slice literal | +| 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:40:15:40:15 | s | main.go:40:8:40:23 | call to append | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/LocalFlowStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/LocalFlowStep.expected index a74e39db2f1..5908aa8d113 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/LocalFlowStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/LocalFlowStep.expected @@ -80,105 +80,135 @@ | main.go:7:6:7:9 | function sink | main.go:150:2:150:5 | sink | | main.go:22:2:22:6 | definition of outer | main.go:25:7:25:11 | outer | | main.go:22:11:24:2 | struct literal | main.go:22:2:22:6 | definition of outer | +| main.go:22:11:24:2 | struct literal [postupdate] | main.go:22:2:22:6 | definition of outer | | main.go:25:7:25:11 | outer | main.go:26:7:26:11 | outer | | main.go:26:7:26:11 | outer | main.go:27:7:27:11 | outer | | main.go:27:7:27:11 | outer | main.go:28:7:28:11 | outer | | main.go:30:2:30:7 | definition of outerp | main.go:33:7:33:12 | outerp | | main.go:30:12:32:2 | &... | main.go:30:2:30:7 | definition of outerp | +| main.go:30:12:32:2 | &... [postupdate] | main.go:30:2:30:7 | definition of outerp | | main.go:33:7:33:12 | outerp | main.go:34:7:34:12 | outerp | +| main.go:33:7:33:12 | outerp [postupdate] | main.go:34:7:34:12 | outerp | | main.go:34:7:34:12 | outerp | main.go:35:7:35:12 | outerp | +| main.go:34:7:34:12 | outerp [postupdate] | main.go:35:7:35:12 | outerp | | main.go:35:7:35:12 | outerp | main.go:36:7:36:12 | outerp | +| main.go:35:7:35:12 | outerp [postupdate] | main.go:36:7:36:12 | outerp | | main.go:40:2:40:6 | definition of outer | main.go:41:7:41:11 | outer | | main.go:40:11:40:40 | struct literal | main.go:40:2:40:6 | definition of outer | +| main.go:40:11:40:40 | struct literal [postupdate] | main.go:40:2:40:6 | definition of outer | | main.go:41:7:41:11 | outer | main.go:42:7:42:11 | outer | | main.go:42:7:42:11 | outer | main.go:43:7:43:11 | outer | | main.go:43:7:43:11 | outer | main.go:44:7:44:11 | outer | | main.go:46:2:46:7 | definition of outerp | main.go:47:7:47:12 | outerp | | main.go:46:12:46:42 | &... | main.go:46:2:46:7 | definition of outerp | +| main.go:46:12:46:42 | &... [postupdate] | main.go:46:2:46:7 | definition of outerp | | main.go:47:7:47:12 | outerp | main.go:48:7:48:12 | outerp | +| main.go:47:7:47:12 | outerp [postupdate] | main.go:48:7:48:12 | outerp | | main.go:48:7:48:12 | outerp | main.go:49:7:49:12 | outerp | +| main.go:48:7:48:12 | outerp [postupdate] | main.go:49:7:49:12 | outerp | | main.go:49:7:49:12 | outerp | main.go:50:7:50:12 | outerp | +| main.go:49:7:49:12 | outerp [postupdate] | main.go:50:7:50:12 | outerp | | main.go:54:2:54:6 | definition of inner | main.go:55:19:55:23 | inner | | main.go:54:11:54:25 | struct literal | main.go:54:2:54:6 | definition of inner | +| main.go:54:11:54:25 | struct literal [postupdate] | main.go:54:2:54:6 | definition of inner | | main.go:55:2:55:7 | definition of middle | main.go:56:17:56:22 | middle | | main.go:55:12:55:24 | struct literal | main.go:55:2:55:7 | definition of middle | +| main.go:55:12:55:24 | struct literal [postupdate] | main.go:55:2:55:7 | definition of middle | | main.go:56:2:56:6 | definition of outer | main.go:57:7:57:11 | outer | | main.go:56:11:56:23 | struct literal | main.go:56:2:56:6 | definition of outer | +| main.go:56:11:56:23 | struct literal [postupdate] | main.go:56:2:56:6 | definition of outer | | main.go:57:7:57:11 | outer | main.go:58:7:58:11 | outer | | main.go:58:7:58:11 | outer | main.go:59:7:59:11 | outer | | main.go:59:7:59:11 | outer | main.go:60:7:60:11 | outer | | main.go:62:2:62:7 | definition of innerp | main.go:63:20:63:25 | innerp | | main.go:62:12:62:26 | struct literal | main.go:62:2:62:7 | definition of innerp | +| main.go:62:12:62:26 | struct literal [postupdate] | main.go:62:2:62:7 | definition of innerp | | main.go:63:2:63:8 | definition of middlep | main.go:64:18:64:24 | middlep | | main.go:63:13:63:26 | struct literal | main.go:63:2:63:8 | definition of middlep | +| main.go:63:13:63:26 | struct literal [postupdate] | main.go:63:2:63:8 | definition of middlep | | main.go:64:2:64:7 | definition of outerp | main.go:65:7:65:12 | outerp | | main.go:64:12:64:25 | struct literal | main.go:64:2:64:7 | definition of outerp | +| main.go:64:12:64:25 | struct literal [postupdate] | main.go:64:2:64:7 | definition of outerp | | main.go:65:7:65:12 | outerp | main.go:66:7:66:12 | outerp | | main.go:66:7:66:12 | outerp | main.go:67:7:67:12 | outerp | | main.go:67:7:67:12 | outerp | main.go:68:7:68:12 | outerp | | main.go:72:2:72:6 | definition of inner | main.go:73:26:73:30 | inner | | main.go:72:11:72:25 | struct literal | main.go:72:2:72:6 | definition of inner | +| main.go:72:11:72:25 | struct literal [postupdate] | main.go:72:2:72:6 | definition of inner | | main.go:73:2:73:7 | definition of middle | main.go:74:25:74:30 | middle | | main.go:73:12:73:31 | struct literal | main.go:73:2:73:7 | definition of middle | +| main.go:73:12:73:31 | struct literal [postupdate] | main.go:73:2:73:7 | definition of middle | | main.go:74:2:74:6 | definition of outer | main.go:75:7:75:11 | outer | | main.go:74:11:74:31 | struct literal | main.go:74:2:74:6 | definition of outer | +| main.go:74:11:74:31 | struct literal [postupdate] | main.go:74:2:74:6 | definition of outer | | main.go:75:7:75:11 | outer | main.go:76:7:76:11 | outer | | main.go:76:7:76:11 | outer | main.go:77:7:77:11 | outer | | main.go:77:7:77:11 | outer | main.go:78:7:78:11 | outer | | main.go:80:2:80:7 | definition of innerp | main.go:81:27:81:32 | innerp | | main.go:80:12:80:26 | struct literal | main.go:80:2:80:7 | definition of innerp | +| main.go:80:12:80:26 | struct literal [postupdate] | main.go:80:2:80:7 | definition of innerp | | main.go:81:2:81:8 | definition of middlep | main.go:82:26:82:32 | middlep | | main.go:81:13:81:33 | struct literal | main.go:81:2:81:8 | definition of middlep | +| main.go:81:13:81:33 | struct literal [postupdate] | main.go:81:2:81:8 | definition of middlep | | main.go:82:2:82:7 | definition of outerp | main.go:83:7:83:12 | outerp | | main.go:82:12:82:33 | struct literal | main.go:82:2:82:7 | definition of outerp | +| main.go:82:12:82:33 | struct literal [postupdate] | main.go:82:2:82:7 | definition of outerp | | main.go:83:7:83:12 | outerp | main.go:84:7:84:12 | outerp | | main.go:84:7:84:12 | outerp | main.go:85:7:85:12 | outerp | | main.go:85:7:85:12 | outerp | main.go:86:7:86:12 | outerp | | main.go:90:6:90:10 | definition of outer | main.go:91:2:91:6 | outer | | main.go:90:6:90:10 | zero value for outer | main.go:90:6:90:10 | definition of outer | | main.go:91:2:91:6 | outer | main.go:92:7:92:11 | outer | +| main.go:91:2:91:6 | outer [postupdate] | main.go:92:7:92:11 | outer | | main.go:92:7:92:11 | outer | main.go:93:7:93:11 | outer | | main.go:93:7:93:11 | outer | main.go:94:7:94:11 | outer | | main.go:94:7:94:11 | outer | main.go:95:7:95:11 | outer | | main.go:97:6:97:11 | definition of outerp | main.go:98:2:98:7 | outerp | | main.go:97:6:97:11 | zero value for outerp | main.go:97:6:97:11 | definition of outerp | | main.go:98:2:98:7 | outerp | main.go:99:7:99:12 | outerp | +| main.go:98:2:98:7 | outerp [postupdate] | main.go:99:7:99:12 | outerp | | main.go:99:7:99:12 | outerp | main.go:100:7:100:12 | outerp | | main.go:100:7:100:12 | outerp | main.go:101:7:101:12 | outerp | | main.go:101:7:101:12 | outerp | main.go:102:7:102:12 | outerp | | main.go:106:6:106:10 | definition of outer | main.go:107:2:107:6 | outer | | main.go:106:6:106:10 | zero value for outer | main.go:106:6:106:10 | definition of outer | | main.go:107:2:107:6 | outer | main.go:108:7:108:11 | outer | +| main.go:107:2:107:6 | outer [postupdate] | main.go:108:7:108:11 | outer | | main.go:108:7:108:11 | outer | main.go:109:7:109:11 | outer | | main.go:109:7:109:11 | outer | main.go:110:7:110:11 | outer | | main.go:110:7:110:11 | outer | main.go:111:7:111:11 | outer | | main.go:113:6:113:11 | definition of outerp | main.go:114:2:114:7 | outerp | | main.go:113:6:113:11 | zero value for outerp | main.go:113:6:113:11 | definition of outerp | | main.go:114:2:114:7 | outerp | main.go:115:7:115:12 | outerp | +| main.go:114:2:114:7 | outerp [postupdate] | main.go:115:7:115:12 | outerp | | main.go:115:7:115:12 | outerp | main.go:116:7:116:12 | outerp | | main.go:116:7:116:12 | outerp | main.go:117:7:117:12 | outerp | | main.go:117:7:117:12 | outerp | main.go:118:7:118:12 | outerp | | main.go:122:6:122:10 | definition of outer | main.go:123:2:123:6 | outer | | main.go:122:6:122:10 | zero value for outer | main.go:122:6:122:10 | definition of outer | | main.go:123:2:123:6 | outer | main.go:124:7:124:11 | outer | +| main.go:123:2:123:6 | outer [postupdate] | main.go:124:7:124:11 | outer | | main.go:124:7:124:11 | outer | main.go:125:7:125:11 | outer | | main.go:125:7:125:11 | outer | main.go:126:7:126:11 | outer | | main.go:126:7:126:11 | outer | main.go:127:7:127:11 | outer | | main.go:129:6:129:11 | definition of outerp | main.go:130:2:130:7 | outerp | | main.go:129:6:129:11 | zero value for outerp | main.go:129:6:129:11 | definition of outerp | | main.go:130:2:130:7 | outerp | main.go:131:7:131:12 | outerp | +| main.go:130:2:130:7 | outerp [postupdate] | main.go:131:7:131:12 | outerp | | main.go:131:7:131:12 | outerp | main.go:132:7:132:12 | outerp | | main.go:132:7:132:12 | outerp | main.go:133:7:133:12 | outerp | | main.go:133:7:133:12 | outerp | main.go:134:7:134:12 | outerp | | main.go:138:6:138:10 | definition of outer | main.go:139:2:139:6 | outer | | main.go:138:6:138:10 | zero value for outer | main.go:138:6:138:10 | definition of outer | | main.go:139:2:139:6 | outer | main.go:140:7:140:11 | outer | +| main.go:139:2:139:6 | outer [postupdate] | main.go:140:7:140:11 | outer | | main.go:140:7:140:11 | outer | main.go:141:7:141:11 | outer | | main.go:141:7:141:11 | outer | main.go:142:7:142:11 | outer | | main.go:142:7:142:11 | outer | main.go:143:7:143:11 | outer | | main.go:145:6:145:11 | definition of outerp | main.go:146:2:146:7 | outerp | | main.go:145:6:145:11 | zero value for outerp | main.go:145:6:145:11 | definition of outerp | | main.go:146:2:146:7 | outerp | main.go:147:7:147:12 | outerp | +| main.go:146:2:146:7 | outerp [postupdate] | main.go:147:7:147:12 | outerp | | main.go:147:7:147:12 | outerp | main.go:148:7:148:12 | outerp | | main.go:148:7:148:12 | outerp | main.go:149:7:149:12 | outerp | | main.go:149:7:149:12 | outerp | main.go:150:7:150:12 | outerp | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesElement.expected b/go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesElement.expected index 77bb562d3f5..44792aa3d29 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesElement.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesElement.expected @@ -1,3 +1,3 @@ -| tst.go:19:2:19:6 | assignment to element | tst.go:19:2:19:3 | xs | tst.go:19:5:19:5 | 0 | tst.go:19:10:19:14 | index expression | -| tst.go:20:2:20:6 | assignment to element | tst.go:20:2:20:3 | implicit dereference | tst.go:20:5:20:5 | 0 | tst.go:20:10:20:14 | index expression | -| tst.go:20:2:20:6 | assignment to element | tst.go:20:2:20:3 | ps | tst.go:20:5:20:5 | 0 | tst.go:20:10:20:14 | index expression | +| tst.go:19:2:19:6 | assignment to element | tst.go:19:2:19:3 | xs [postupdate] | tst.go:19:5:19:5 | 0 | tst.go:19:10:19:14 | index expression | +| tst.go:20:2:20:6 | assignment to element | tst.go:20:2:20:3 | implicit dereference [postupdate] | tst.go:20:5:20:5 | 0 | tst.go:20:10:20:14 | index expression | +| tst.go:20:2:20:6 | assignment to element | tst.go:20:2:20:3 | ps [postupdate] | tst.go:20:5:20:5 | 0 | tst.go:20:10:20:14 | index expression | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesField.expected b/go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesField.expected index 8e71670f8c1..7862b2d61b3 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesField.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesField.expected @@ -1,3 +1,3 @@ -| tst.go:8:2:8:4 | assignment to field f | tst.go:8:2:8:2 | implicit dereference | tst.go:4:2:4:2 | f | tst.go:8:8:8:14 | ...+... | -| tst.go:8:2:8:4 | assignment to field f | tst.go:8:2:8:2 | t | tst.go:4:2:4:2 | f | tst.go:8:8:8:14 | ...+... | -| tst.go:17:2:17:4 | assignment to field f | tst.go:17:2:17:2 | x | tst.go:4:2:4:2 | f | tst.go:17:8:17:14 | ...+... | +| tst.go:8:2:8:4 | assignment to field f | tst.go:8:2:8:2 | implicit dereference [postupdate] | tst.go:4:2:4:2 | f | tst.go:8:8:8:14 | ...+... | +| tst.go:8:2:8:4 | assignment to field f | tst.go:8:2:8:2 | t [postupdate] | tst.go:4:2:4:2 | f | tst.go:8:8:8:14 | ...+... | +| tst.go:17:2:17:4 | assignment to field f | tst.go:17:2:17:2 | x [postupdate] | tst.go:4:2:4:2 | f | tst.go:17:8:17:14 | ...+... | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Email/EmailData.expected b/go/ql/test/library-tests/semmle/go/frameworks/Email/EmailData.expected index 99b33b4a780..070800dab63 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Email/EmailData.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Email/EmailData.expected @@ -1,5 +1,8 @@ | mail.go:15:73:15:94 | type conversion | | mail.go:18:19:18:23 | definition of write | +| mail.go:18:19:18:38 | ... := ...[0] | +| mail.go:20:17:20:21 | write | +| mail.go:20:17:20:21 | write [postupdate] | | mail.go:26:49:26:52 | text | | mail.go:26:76:26:79 | text | | mail.go:27:20:27:23 | text | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected index 8e113c12ef7..703066d6449 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected @@ -1,26 +1,8 @@ edges -| main.go:18:46:18:48 | definition of req | main.go:18:46:18:48 | definition of req [Return] | provenance | | | main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | provenance | | -| main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | provenance | | -| main.go:18:46:18:48 | definition of req [Return] | proto/Hello.pb.micro.go:85:53:85:54 | definition of in | provenance | | -| proto/Hello.pb.micro.go:85:53:85:54 | definition of in | proto/Hello.pb.micro.go:85:53:85:54 | definition of in [Return] | provenance | | -| proto/Hello.pb.micro.go:85:53:85:54 | definition of in | proto/Hello.pb.micro.go:86:37:86:38 | in | provenance | | -| proto/Hello.pb.micro.go:85:53:85:54 | definition of in | proto/Hello.pb.micro.go:86:37:86:38 | in | provenance | | -| proto/Hello.pb.micro.go:85:53:85:54 | definition of in [Return] | proto/Hello.pb.micro.go:85:53:85:54 | definition of in | provenance | | -| proto/Hello.pb.micro.go:86:37:86:38 | in | main.go:18:46:18:48 | definition of req | provenance | | -| proto/Hello.pb.micro.go:86:37:86:38 | in | main.go:18:46:18:48 | definition of req | provenance | | -| proto/Hello.pb.micro.go:86:37:86:38 | in | proto/Hello.pb.micro.go:85:53:85:54 | definition of in | provenance | | -| proto/Hello.pb.micro.go:86:37:86:38 | in | proto/Hello.pb.micro.go:85:53:85:54 | definition of in | provenance | | nodes | main.go:18:46:18:48 | definition of req | semmle.label | definition of req | -| main.go:18:46:18:48 | definition of req | semmle.label | definition of req | -| main.go:18:46:18:48 | definition of req [Return] | semmle.label | definition of req [Return] | | main.go:21:28:21:31 | name | semmle.label | name | -| proto/Hello.pb.micro.go:85:53:85:54 | definition of in | semmle.label | definition of in | -| proto/Hello.pb.micro.go:85:53:85:54 | definition of in | semmle.label | definition of in | -| proto/Hello.pb.micro.go:85:53:85:54 | definition of in [Return] | semmle.label | definition of in [Return] | -| proto/Hello.pb.micro.go:86:37:86:38 | in | semmle.label | in | -| proto/Hello.pb.micro.go:86:37:86:38 | in | semmle.label | in | subpaths #select | main.go:21:28:21:31 | name | main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | This log entry depends on a $@. | main.go:18:46:18:48 | definition of req | user-provided value | 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 8209afc7b50..3bccd586d74 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 @@ -86,16 +86,16 @@ invalidModelRow | main.go:13:33:13:33 | v | main.go:13:2:13:52 | ... := ...[0] | | main.go:13:36:13:45 | "/*JSON*/" | main.go:13:2:13:52 | ... := ...[0] | | main.go:13:48:13:51 | " " | main.go:13:2:13:52 | ... := ...[0] | -| main.go:14:25:14:25 | b | main.go:14:9:14:41 | slice literal [postupdate] | -| main.go:14:28:14:30 | err | main.go:14:9:14:41 | slice literal [postupdate] | -| main.go:14:33:14:34 | b2 | main.go:14:9:14:41 | slice literal [postupdate] | -| main.go:14:37:14:40 | err2 | main.go:14:9:14:41 | slice literal [postupdate] | +| main.go:14:25:14:25 | b | main.go:14:9:14:41 | slice literal | +| main.go:14:28:14:30 | err | main.go:14:9:14:41 | slice literal | +| main.go:14:33:14:34 | b2 | main.go:14:9:14:41 | slice literal | +| main.go:14:37:14:40 | err2 | main.go:14:9:14:41 | slice literal | | main.go:19:18:19:42 | call to DecodeString | main.go:19:2:19:42 | ... := ...[0] | | main.go:19:18:19:42 | call to DecodeString | main.go:19:2:19:42 | ... := ...[1] | | main.go:19:35:19:41 | encoded | main.go:19:2:19:42 | ... := ...[0] | -| main.go:23:25:23:31 | decoded | main.go:23:9:23:48 | slice literal [postupdate] | -| main.go:23:34:23:36 | err | main.go:23:9:23:48 | slice literal [postupdate] | -| main.go:23:39:23:47 | reEncoded | main.go:23:9:23:48 | slice literal [postupdate] | +| main.go:23:25:23:31 | decoded | main.go:23:9:23:48 | slice literal | +| main.go:23:34:23:36 | err | main.go:23:9:23:48 | slice literal | +| main.go:23:39:23:47 | reEncoded | main.go:23:9:23:48 | slice literal | | main.go:28:2:28:4 | implicit dereference | main.go:28:2:28:4 | req [postupdate] | | main.go:28:2:28:4 | implicit dereference | main.go:28:2:28:9 | selection of Body | | main.go:28:2:28:4 | req | main.go:28:2:28:4 | implicit dereference | 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 22dec49d484..78dde84a947 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -56,8 +56,8 @@ edges | SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:80:23:80:29 | tainted | provenance | Config | | 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:9:2:9:8 | definition of tainted | provenance | | -| SanitizingDoubleDash.go:13:15:13:32 | array literal [postupdate] [array] | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:13:25:13:31 | tainted | SanitizingDoubleDash.go:13:15:13:32 | array literal [postupdate] [array] | provenance | | +| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:13:25:13:31 | tainted | SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | provenance | | | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | SanitizingDoubleDash.go:14:23:14:33 | slice element node | provenance | | | SanitizingDoubleDash.go:14:23:14:33 | slice element node | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | | | SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | SanitizingDoubleDash.go:39:14:39:44 | call to append | provenance | MaD:5 | @@ -65,8 +65,8 @@ edges | SanitizingDoubleDash.go:39:14:39:44 | call to append | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:39:14:39:44 | call to append [array] | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | provenance | | | SanitizingDoubleDash.go:39:31:39:37 | tainted | SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | provenance | | -| SanitizingDoubleDash.go:52:15:52:31 | slice literal [postupdate] [array] | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:52:24:52:30 | tainted | SanitizingDoubleDash.go:52:15:52:31 | slice literal [postupdate] [array] | provenance | | +| SanitizingDoubleDash.go:52:15:52:31 | slice literal [array] | SanitizingDoubleDash.go:53:21:53:28 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:52:24:52:30 | tainted | SanitizingDoubleDash.go:52:15:52:31 | slice literal [array] | provenance | | | SanitizingDoubleDash.go:52:24:52:30 | tainted | SanitizingDoubleDash.go:53:21:53:28 | arrayLit | provenance | | | 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 | | @@ -99,16 +99,16 @@ edges | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:142:31:142:37 | tainted | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:148:30:148:36 | tainted | provenance | | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:152:24:152:30 | tainted | provenance | | -| SanitizingDoubleDash.go:95:15:95:32 | array literal [postupdate] [array] | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:95:25:95:31 | tainted | SanitizingDoubleDash.go:95:15:95:32 | array literal [postupdate] [array] | provenance | | +| SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:95:25:95:31 | tainted | SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | provenance | | | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | SanitizingDoubleDash.go:96:24:96:34 | slice element node | provenance | | | SanitizingDoubleDash.go:96:24:96:34 | slice element node | SanitizingDoubleDash.go:96:24:96:34 | slice expression | provenance | | -| SanitizingDoubleDash.go:100:15:100:38 | array literal [postupdate] [array] | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:100:31:100:37 | tainted | SanitizingDoubleDash.go:100:15:100:38 | array literal [postupdate] [array] | provenance | | +| SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:100:31:100:37 | tainted | SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | provenance | | | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | SanitizingDoubleDash.go:101:24:101:34 | slice element node | provenance | | | SanitizingDoubleDash.go:101:24:101:34 | slice element node | SanitizingDoubleDash.go:101:24:101:34 | slice expression | provenance | | -| SanitizingDoubleDash.go:105:15:105:37 | slice literal [postupdate] [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | provenance | | -| SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [postupdate] [array] | provenance | | +| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | provenance | | +| SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | provenance | | | SanitizingDoubleDash.go:111:14:111:44 | []type{args} [array] | SanitizingDoubleDash.go:111:14:111:44 | call to append | provenance | MaD:5 | | SanitizingDoubleDash.go:111:14:111:44 | []type{args} [array] | SanitizingDoubleDash.go:111:14:111:44 | call to append [array] | provenance | MaD:5 | | SanitizingDoubleDash.go:111:14:111:44 | call to append | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | provenance | | @@ -124,8 +124,8 @@ edges | SanitizingDoubleDash.go:123:14:123:38 | call to append | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:123:14:123:38 | call to append [array] | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | provenance | | | SanitizingDoubleDash.go:123:31:123:37 | tainted | SanitizingDoubleDash.go:123:14:123:38 | []type{args} [array] | provenance | | -| SanitizingDoubleDash.go:128:15:128:31 | slice literal [postupdate] [array] | SanitizingDoubleDash.go:129:21:129:28 | arrayLit [array] | provenance | | -| SanitizingDoubleDash.go:128:24:128:30 | tainted | SanitizingDoubleDash.go:128:15:128:31 | slice literal [postupdate] [array] | provenance | | +| SanitizingDoubleDash.go:128:15:128:31 | slice literal [array] | SanitizingDoubleDash.go:129:21:129:28 | arrayLit [array] | provenance | | +| SanitizingDoubleDash.go:128:24:128:30 | tainted | SanitizingDoubleDash.go:128:15:128:31 | slice literal [array] | provenance | | | 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 | @@ -184,7 +184,7 @@ nodes | SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | semmle.label | definition of tainted | | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | semmle.label | selection of URL | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | semmle.label | call to Query | -| SanitizingDoubleDash.go:13:15:13:32 | array literal [postupdate] [array] | semmle.label | array literal [postupdate] [array] | +| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | semmle.label | array literal [array] | | SanitizingDoubleDash.go:13:25:13:31 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | semmle.label | arrayLit [array] | | SanitizingDoubleDash.go:14:23:14:33 | slice element node | semmle.label | slice element node | @@ -194,7 +194,7 @@ nodes | SanitizingDoubleDash.go:39:14:39:44 | call to append [array] | semmle.label | call to append [array] | | SanitizingDoubleDash.go:39:31:39:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | semmle.label | arrayLit | -| SanitizingDoubleDash.go:52:15:52:31 | slice literal [postupdate] [array] | semmle.label | slice literal [postupdate] [array] | +| SanitizingDoubleDash.go:52:15:52:31 | slice literal [array] | semmle.label | slice literal [array] | | SanitizingDoubleDash.go:52:24:52:30 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:53:14:53:35 | call to append | semmle.label | call to append | | SanitizingDoubleDash.go:53:14:53:35 | call to append [array] | semmle.label | call to append [array] | @@ -213,17 +213,17 @@ nodes | SanitizingDoubleDash.go:80:23:80:29 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | semmle.label | selection of URL | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | semmle.label | call to Query | -| SanitizingDoubleDash.go:95:15:95:32 | array literal [postupdate] [array] | semmle.label | array literal [postupdate] [array] | +| SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | semmle.label | array literal [array] | | SanitizingDoubleDash.go:95:25:95:31 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | semmle.label | arrayLit [array] | | SanitizingDoubleDash.go:96:24:96:34 | slice element node | semmle.label | slice element node | | SanitizingDoubleDash.go:96:24:96:34 | slice expression | semmle.label | slice expression | -| SanitizingDoubleDash.go:100:15:100:38 | array literal [postupdate] [array] | semmle.label | array literal [postupdate] [array] | +| SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | semmle.label | array literal [array] | | SanitizingDoubleDash.go:100:31:100:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | semmle.label | arrayLit [array] | | SanitizingDoubleDash.go:101:24:101:34 | slice element node | semmle.label | slice element node | | SanitizingDoubleDash.go:101:24:101:34 | slice expression | semmle.label | slice expression | -| SanitizingDoubleDash.go:105:15:105:37 | slice literal [postupdate] [array] | semmle.label | slice literal [postupdate] [array] | +| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | semmle.label | slice literal [array] | | SanitizingDoubleDash.go:105:30:105:36 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:111:14:111:44 | []type{args} [array] | semmle.label | []type{args} [array] | @@ -241,7 +241,7 @@ nodes | SanitizingDoubleDash.go:123:14:123:38 | call to append [array] | semmle.label | call to append [array] | | SanitizingDoubleDash.go:123:31:123:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | semmle.label | arrayLit | -| SanitizingDoubleDash.go:128:15:128:31 | slice literal [postupdate] [array] | semmle.label | slice literal [postupdate] [array] | +| SanitizingDoubleDash.go:128:15:128:31 | slice literal [array] | semmle.label | slice literal [array] | | SanitizingDoubleDash.go:128:24:128:30 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:129:14:129:35 | call to append | semmle.label | call to append | | SanitizingDoubleDash.go:129:14:129:35 | call to append [array] | semmle.label | call to append [array] | diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 542f1b5b89c..e8c6848b569 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -33,24 +33,24 @@ edges | SqlInjection.go:11:3:11:29 | index expression | SqlInjection.go:10:7:11:30 | call to Sprintf | provenance | FunctionModel | | issue48.go:17:2:17:33 | ... := ...[0] | issue48.go:18:17:18:17 | b | provenance | | | issue48.go:17:25:17:32 | selection of Body | issue48.go:17:2:17:33 | ... := ...[0] | provenance | Src:MaD:17 MaD:24 | -| issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... | provenance | MaD:22 | -| issue48.go:18:20:18:39 | &... | issue48.go:21:3:21:33 | index expression | provenance | | +| issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... [postupdate] | provenance | MaD:22 | +| issue48.go:18:20:18:39 | &... [postupdate] | issue48.go:21:3:21:33 | index expression | provenance | | | issue48.go:20:8:21:34 | []type{args} [array] | issue48.go:20:8:21:34 | call to Sprintf | provenance | MaD:23 | | issue48.go:20:8:21:34 | call to Sprintf | issue48.go:22:11:22:12 | q3 | provenance | Sink:MaD:1 | | issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | []type{args} [array] | provenance | | | issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | call to Sprintf | provenance | FunctionModel | | issue48.go:27:2:27:34 | ... := ...[0] | issue48.go:28:17:28:18 | b2 | provenance | | | issue48.go:27:26:27:33 | selection of Body | issue48.go:27:2:27:34 | ... := ...[0] | provenance | Src:MaD:17 MaD:24 | -| issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... | provenance | MaD:22 | -| issue48.go:28:21:28:41 | &... | issue48.go:31:3:31:31 | selection of Category | provenance | | +| issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... [postupdate] | provenance | MaD:22 | +| issue48.go:28:21:28:41 | &... [postupdate] | issue48.go:31:3:31:31 | selection of Category | provenance | | | issue48.go:30:8:31:32 | []type{args} [array] | issue48.go:30:8:31:32 | call to Sprintf | provenance | MaD:23 | | issue48.go:30:8:31:32 | call to Sprintf | issue48.go:32:11:32:12 | q4 | provenance | Sink:MaD:1 | | issue48.go:31:3:31:31 | selection of Category | issue48.go:30:8:31:32 | []type{args} [array] | provenance | | | issue48.go:31:3:31:31 | selection of Category | issue48.go:30:8:31:32 | call to Sprintf | provenance | FunctionModel | -| issue48.go:37:17:37:50 | type conversion | issue48.go:37:53:37:73 | &... | provenance | MaD:22 | +| issue48.go:37:17:37:50 | type conversion | issue48.go:37:53:37:73 | &... [postupdate] | provenance | MaD:22 | | issue48.go:37:24:37:30 | selection of URL | issue48.go:37:24:37:38 | call to Query | provenance | Src:MaD:21 MaD:26 | | issue48.go:37:24:37:38 | call to Query | issue48.go:37:17:37:50 | type conversion | provenance | | -| issue48.go:37:53:37:73 | &... | issue48.go:40:3:40:31 | selection of Category | provenance | | +| issue48.go:37:53:37:73 | &... [postupdate] | issue48.go:40:3:40:31 | selection of Category | provenance | | | issue48.go:39:8:40:32 | []type{args} [array] | issue48.go:39:8:40:32 | call to Sprintf | provenance | MaD:23 | | issue48.go:39:8:40:32 | call to Sprintf | issue48.go:41:11:41:12 | q5 | provenance | Sink:MaD:1 | | issue48.go:40:3:40:31 | selection of Category | issue48.go:39:8:40:32 | []type{args} [array] | provenance | | @@ -76,39 +76,33 @@ edges | main.go:34:3:34:13 | implicit dereference [Category] | main.go:34:3:34:22 | selection of Category | provenance | | | main.go:34:3:34:22 | selection of Category | main.go:33:7:34:23 | []type{args} [array] | provenance | | | main.go:34:3:34:22 | selection of Category | main.go:33:7:34:23 | call to Sprintf | provenance | FunctionModel | -| main.go:39:2:39:12 | definition of RequestData [pointer, Category] | main.go:40:2:40:12 | RequestData [pointer, Category] | provenance | | -| main.go:39:2:39:12 | definition of RequestData [pointer, Category] | main.go:43:3:43:13 | RequestData [pointer, Category] | provenance | | -| main.go:40:2:40:12 | RequestData [pointer, Category] | main.go:40:2:40:12 | implicit dereference [Category] | provenance | | -| main.go:40:2:40:12 | implicit dereference [Category] | main.go:39:2:39:12 | definition of RequestData [pointer, Category] | provenance | | +| main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | main.go:43:3:43:13 | RequestData [pointer, Category] | provenance | | +| main.go:40:2:40:12 | implicit dereference [postupdate] [Category] | main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | provenance | | | main.go:40:25:40:31 | selection of URL | main.go:40:25:40:39 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:40:25:40:39 | call to Query | main.go:40:25:40:51 | index expression | provenance | | -| main.go:40:25:40:51 | index expression | main.go:40:2:40:12 | implicit dereference [Category] | provenance | | +| main.go:40:25:40:51 | index expression | main.go:40:2:40:12 | implicit dereference [postupdate] [Category] | provenance | | | main.go:42:7:43:23 | []type{args} [array] | main.go:42:7:43:23 | call to Sprintf | provenance | MaD:23 | | main.go:42:7:43:23 | call to Sprintf | main.go:44:11:44:11 | q | provenance | Sink:MaD:1 | | main.go:43:3:43:13 | RequestData [pointer, Category] | main.go:43:3:43:13 | implicit dereference [Category] | provenance | | | main.go:43:3:43:13 | implicit dereference [Category] | main.go:43:3:43:22 | selection of Category | provenance | | | main.go:43:3:43:22 | selection of Category | main.go:42:7:43:23 | []type{args} [array] | provenance | | | main.go:43:3:43:22 | selection of Category | main.go:42:7:43:23 | call to Sprintf | provenance | FunctionModel | -| main.go:48:2:48:12 | definition of RequestData [pointer, Category] | main.go:49:4:49:14 | RequestData [pointer, Category] | provenance | | -| main.go:48:2:48:12 | definition of RequestData [pointer, Category] | main.go:52:3:52:13 | RequestData [pointer, Category] | provenance | | -| main.go:49:3:49:14 | star expression [Category] | main.go:48:2:48:12 | definition of RequestData [pointer, Category] | provenance | | -| main.go:49:4:49:14 | RequestData [pointer, Category] | main.go:49:3:49:14 | star expression [Category] | provenance | | +| main.go:49:3:49:14 | star expression [postupdate] [Category] | main.go:49:4:49:14 | RequestData [postupdate] [pointer, Category] | provenance | | +| main.go:49:4:49:14 | RequestData [postupdate] [pointer, Category] | main.go:52:3:52:13 | RequestData [pointer, Category] | provenance | | | main.go:49:28:49:34 | selection of URL | main.go:49:28:49:42 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:49:28:49:42 | call to Query | main.go:49:28:49:54 | index expression | provenance | | -| main.go:49:28:49:54 | index expression | main.go:49:3:49:14 | star expression [Category] | provenance | | +| main.go:49:28:49:54 | index expression | main.go:49:3:49:14 | star expression [postupdate] [Category] | provenance | | | main.go:51:7:52:23 | []type{args} [array] | main.go:51:7:52:23 | call to Sprintf | provenance | MaD:23 | | main.go:51:7:52:23 | call to Sprintf | main.go:53:11:53:11 | q | provenance | Sink:MaD:1 | | main.go:52:3:52:13 | RequestData [pointer, Category] | main.go:52:3:52:13 | implicit dereference [Category] | provenance | | | main.go:52:3:52:13 | implicit dereference [Category] | main.go:52:3:52:22 | selection of Category | provenance | | | main.go:52:3:52:22 | selection of Category | main.go:51:7:52:23 | []type{args} [array] | provenance | | | main.go:52:3:52:22 | selection of Category | main.go:51:7:52:23 | call to Sprintf | provenance | FunctionModel | -| main.go:57:2:57:12 | definition of RequestData [pointer, Category] | main.go:58:4:58:14 | RequestData [pointer, Category] | provenance | | -| main.go:57:2:57:12 | definition of RequestData [pointer, Category] | main.go:61:5:61:15 | RequestData [pointer, Category] | provenance | | -| main.go:58:3:58:14 | star expression [Category] | main.go:57:2:57:12 | definition of RequestData [pointer, Category] | provenance | | -| main.go:58:4:58:14 | RequestData [pointer, Category] | main.go:58:3:58:14 | star expression [Category] | provenance | | +| main.go:58:3:58:14 | star expression [postupdate] [Category] | main.go:58:4:58:14 | RequestData [postupdate] [pointer, Category] | provenance | | +| main.go:58:4:58:14 | RequestData [postupdate] [pointer, Category] | main.go:61:5:61:15 | RequestData [pointer, Category] | provenance | | | main.go:58:28:58:34 | selection of URL | main.go:58:28:58:42 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:58:28:58:42 | call to Query | main.go:58:28:58:54 | index expression | provenance | | -| main.go:58:28:58:54 | index expression | main.go:58:3:58:14 | star expression [Category] | provenance | | +| main.go:58:28:58:54 | index expression | main.go:58:3:58:14 | star expression [postupdate] [Category] | provenance | | | main.go:60:7:61:26 | []type{args} [array] | main.go:60:7:61:26 | call to Sprintf | provenance | MaD:23 | | main.go:60:7:61:26 | call to Sprintf | main.go:62:11:62:11 | q | provenance | Sink:MaD:1 | | main.go:61:3:61:25 | selection of Category | main.go:60:7:61:26 | []type{args} [array] | provenance | | @@ -170,7 +164,7 @@ nodes | issue48.go:17:2:17:33 | ... := ...[0] | semmle.label | ... := ...[0] | | issue48.go:17:25:17:32 | selection of Body | semmle.label | selection of Body | | issue48.go:18:17:18:17 | b | semmle.label | b | -| issue48.go:18:20:18:39 | &... | semmle.label | &... | +| issue48.go:18:20:18:39 | &... [postupdate] | semmle.label | &... [postupdate] | | issue48.go:20:8:21:34 | []type{args} [array] | semmle.label | []type{args} [array] | | issue48.go:20:8:21:34 | call to Sprintf | semmle.label | call to Sprintf | | issue48.go:21:3:21:33 | index expression | semmle.label | index expression | @@ -178,7 +172,7 @@ nodes | issue48.go:27:2:27:34 | ... := ...[0] | semmle.label | ... := ...[0] | | issue48.go:27:26:27:33 | selection of Body | semmle.label | selection of Body | | issue48.go:28:17:28:18 | b2 | semmle.label | b2 | -| issue48.go:28:21:28:41 | &... | semmle.label | &... | +| issue48.go:28:21:28:41 | &... [postupdate] | semmle.label | &... [postupdate] | | issue48.go:30:8:31:32 | []type{args} [array] | semmle.label | []type{args} [array] | | issue48.go:30:8:31:32 | call to Sprintf | semmle.label | call to Sprintf | | issue48.go:31:3:31:31 | selection of Category | semmle.label | selection of Category | @@ -186,7 +180,7 @@ nodes | issue48.go:37:17:37:50 | type conversion | semmle.label | type conversion | | issue48.go:37:24:37:30 | selection of URL | semmle.label | selection of URL | | issue48.go:37:24:37:38 | call to Query | semmle.label | call to Query | -| issue48.go:37:53:37:73 | &... | semmle.label | &... | +| issue48.go:37:53:37:73 | &... [postupdate] | semmle.label | &... [postupdate] | | issue48.go:39:8:40:32 | []type{args} [array] | semmle.label | []type{args} [array] | | issue48.go:39:8:40:32 | call to Sprintf | semmle.label | call to Sprintf | | issue48.go:40:3:40:31 | selection of Category | semmle.label | selection of Category | @@ -213,9 +207,8 @@ nodes | main.go:34:3:34:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | | main.go:34:3:34:22 | selection of Category | semmle.label | selection of Category | | main.go:35:11:35:11 | q | semmle.label | q | -| main.go:39:2:39:12 | definition of RequestData [pointer, Category] | semmle.label | definition of RequestData [pointer, Category] | -| main.go:40:2:40:12 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | -| main.go:40:2:40:12 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | +| main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | semmle.label | RequestData [postupdate] [pointer, Category] | +| main.go:40:2:40:12 | implicit dereference [postupdate] [Category] | semmle.label | implicit dereference [postupdate] [Category] | | main.go:40:25:40:31 | selection of URL | semmle.label | selection of URL | | main.go:40:25:40:39 | call to Query | semmle.label | call to Query | | main.go:40:25:40:51 | index expression | semmle.label | index expression | @@ -225,9 +218,8 @@ nodes | main.go:43:3:43:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | | main.go:43:3:43:22 | selection of Category | semmle.label | selection of Category | | main.go:44:11:44:11 | q | semmle.label | q | -| main.go:48:2:48:12 | definition of RequestData [pointer, Category] | semmle.label | definition of RequestData [pointer, Category] | -| main.go:49:3:49:14 | star expression [Category] | semmle.label | star expression [Category] | -| main.go:49:4:49:14 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | +| main.go:49:3:49:14 | star expression [postupdate] [Category] | semmle.label | star expression [postupdate] [Category] | +| main.go:49:4:49:14 | RequestData [postupdate] [pointer, Category] | semmle.label | RequestData [postupdate] [pointer, Category] | | main.go:49:28:49:34 | selection of URL | semmle.label | selection of URL | | main.go:49:28:49:42 | call to Query | semmle.label | call to Query | | main.go:49:28:49:54 | index expression | semmle.label | index expression | @@ -237,9 +229,8 @@ nodes | main.go:52:3:52:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | | main.go:52:3:52:22 | selection of Category | semmle.label | selection of Category | | main.go:53:11:53:11 | q | semmle.label | q | -| main.go:57:2:57:12 | definition of RequestData [pointer, Category] | semmle.label | definition of RequestData [pointer, Category] | -| main.go:58:3:58:14 | star expression [Category] | semmle.label | star expression [Category] | -| main.go:58:4:58:14 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | +| main.go:58:3:58:14 | star expression [postupdate] [Category] | semmle.label | star expression [postupdate] [Category] | +| main.go:58:4:58:14 | RequestData [postupdate] [pointer, Category] | semmle.label | RequestData [postupdate] [pointer, Category] | | main.go:58:28:58:34 | selection of URL | semmle.label | selection of URL | | main.go:58:28:58:42 | call to Query | semmle.label | call to Query | | main.go:58:28:58:54 | index expression | semmle.label | index expression | diff --git a/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/main.go b/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/main.go index 027a88b9bb6..3cb5d107a70 100644 --- a/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/main.go +++ b/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/main.go @@ -64,9 +64,22 @@ func bad3() *http.Transport { return transport } -func good3() *http.Transport { - insecureTransport := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // OK +func good3(i int) *http.Transport { + if i == 0 { + insecureTransport := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // OK + } + return insecureTransport + } else if i == 1 { + temp1 := tls.Config{InsecureSkipVerify: true} + temp2 := &temp1 + selfSignConfig := &http.Transport{TLSClientConfig: temp2} // OK + return selfSignConfig + } else if i == 2 { + temp1 := tls.Config{} + temp1.InsecureSkipVerify = true + untrustedTransport := &http.Transport{TLSClientConfig: &temp1} // OK + return untrustedTransport } - return insecureTransport + return nil } 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 2b96941ce1a..f748c7a7773 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -187,10 +187,10 @@ edges | passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | | | passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | provenance | Config | | passwords.go:34:28:34:35 | password | passwords.go:42:6:42:13 | password | provenance | | -| passwords.go:36:10:38:2 | struct literal [postupdate] | passwords.go:39:14:39:17 | obj1 | provenance | | -| passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal [postupdate] | provenance | Config | -| passwords.go:41:10:43:2 | struct literal [postupdate] | passwords.go:44:14:44:17 | obj2 | provenance | | -| passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal [postupdate] | provenance | Config | +| passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | | +| passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal | provenance | Config | +| passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | | +| passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal | provenance | Config | | passwords.go:42:6:42:13 | password | passwords.go:48:11:48:18 | password | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:92:23:92:28 | secret | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:102:33:102:40 | password | provenance | | @@ -198,8 +198,8 @@ edges | passwords.go:48:11:48:18 | password | passwords.go:113:33:113:40 | password | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:123:13:123:20 | password | provenance | | | passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | provenance | | -| passwords.go:86:19:88:2 | struct literal [postupdate] | passwords.go:89:14:89:26 | utilityObject | provenance | | -| passwords.go:87:16:87:36 | call to make | passwords.go:86:19:88:2 | struct literal [postupdate] | provenance | Config | +| passwords.go:86:19:88:2 | struct literal | passwords.go:89:14:89:26 | utilityObject | provenance | | +| passwords.go:87:16:87:36 | call to make | passwords.go:86:19:88:2 | struct literal | provenance | Config | | passwords.go:102:33:102:40 | password | passwords.go:102:15:102:40 | ...+... | provenance | Config | | passwords.go:102:33:102:40 | password | passwords.go:108:34:108:41 | password | provenance | | | passwords.go:102:33:102:40 | password | passwords.go:113:33:113:40 | password | provenance | | @@ -212,14 +212,14 @@ edges | passwords.go:116:6:116:14 | definition of password1 | passwords.go:117:28:117:36 | password1 | provenance | | | passwords.go:117:28:117:36 | password1 | passwords.go:117:28:117:45 | call to String | provenance | Config | | passwords.go:117:28:117:45 | call to String | passwords.go:117:14:117:45 | ...+... | provenance | Config | -| passwords.go:120:12:125:2 | struct literal [postupdate] | passwords.go:127:14:127:19 | config | provenance | | -| passwords.go:120:12:125:2 | struct literal [postupdate] [x] | passwords.go:128:14:128:19 | config [x] | provenance | | -| passwords.go:120:12:125:2 | struct literal [postupdate] [y] | passwords.go:129:14:129:19 | config [y] | provenance | | -| passwords.go:121:13:121:14 | x3 | passwords.go:120:12:125:2 | struct literal [postupdate] | provenance | Config | -| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [postupdate] | provenance | Config | -| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [postupdate] [x] | provenance | | -| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [postupdate] | provenance | Config | -| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [postupdate] [y] | provenance | | +| passwords.go:120:12:125:2 | struct literal | passwords.go:127:14:127:19 | config | provenance | | +| passwords.go:120:12:125:2 | struct literal [x] | passwords.go:128:14:128:19 | config [x] | provenance | | +| passwords.go:120:12:125:2 | struct literal [y] | passwords.go:129:14:129:19 | config [y] | provenance | | +| passwords.go:121:13:121:14 | x3 | passwords.go:120:12:125:2 | struct literal | provenance | Config | +| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal | provenance | Config | +| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [x] | provenance | | +| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal | provenance | Config | +| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [y] | provenance | | | passwords.go:128:14:128:19 | config [x] | passwords.go:128:14:128:21 | selection of x | provenance | | | passwords.go:129:14:129:19 | config [y] | passwords.go:129:14:129:21 | selection of y | provenance | | | protobuf.go:9:2:9:9 | definition of password | protobuf.go:12:22:12:29 | password | provenance | | @@ -311,16 +311,16 @@ 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:10:38:2 | struct literal [postupdate] | semmle.label | struct literal [postupdate] | +| 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:10:43:2 | struct literal [postupdate] | semmle.label | struct literal [postupdate] | +| 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:48:11:48:18 | password | semmle.label | password | | passwords.go:50:2:50:15 | definition of fixed_password | semmle.label | definition of fixed_password | | passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password | -| passwords.go:86:19:88:2 | struct literal [postupdate] | semmle.label | struct literal [postupdate] | +| passwords.go:86:19:88:2 | struct literal | semmle.label | struct literal | | passwords.go:87:16:87:36 | call to make | semmle.label | call to make | | passwords.go:89:14:89:26 | utilityObject | semmle.label | utilityObject | | passwords.go:92:23:92:28 | secret | semmle.label | secret | @@ -334,9 +334,9 @@ nodes | passwords.go:117:14:117:45 | ...+... | semmle.label | ...+... | | passwords.go:117:28:117:36 | password1 | semmle.label | password1 | | passwords.go:117:28:117:45 | call to String | semmle.label | call to String | -| passwords.go:120:12:125:2 | struct literal [postupdate] | semmle.label | struct literal [postupdate] | -| passwords.go:120:12:125:2 | struct literal [postupdate] [x] | semmle.label | struct literal [postupdate] [x] | -| passwords.go:120:12:125:2 | struct literal [postupdate] [y] | semmle.label | struct literal [postupdate] [y] | +| passwords.go:120:12:125:2 | struct literal | semmle.label | struct literal | +| passwords.go:120:12:125:2 | struct literal [x] | semmle.label | struct literal [x] | +| passwords.go:120:12:125:2 | struct literal [y] | semmle.label | struct literal [y] | | passwords.go:121:13:121:14 | x3 | semmle.label | x3 | | passwords.go:123:13:123:20 | password | semmle.label | password | | passwords.go:124:13:124:25 | call to getPassword | semmle.label | call to getPassword | From 748c53a7919d8668f6d7cdc4446ceb2cb673ab02 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 18 Sep 2025 14:35:43 +0100 Subject: [PATCH 35/70] Refactor: Create `writesFieldOnSsaWithFields` --- go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll | 9 +++++++++ .../go/security/OpenUrlRedirectCustomizations.qll | 5 ++--- go/ql/lib/semmle/go/security/RequestForgery.qll | 7 ++----- go/ql/lib/semmle/go/security/SafeUrlFlow.qll | 7 ++----- go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql | 11 ++--------- go/ql/src/experimental/CWE-918/SSRF.qll | 7 ++----- 6 files changed, 19 insertions(+), 27 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index 58a3ae3d44e..7d38fbe934d 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -152,6 +152,15 @@ module ControlFlow { ) } + /** + * Holds if this node sets the value of field `f` on `v` to `rhs`. + */ + predicate writesFieldOnSsaWithFields(SsaWithFields v, Field f, DataFlow::Node rhs) { + exists(IR::Instruction insn | this.writesFieldInsn(insn, f, rhs.asInstruction()) | + v.getAUse().asInstruction() = insn + ) + } + private predicate writesFieldInsn(IR::Instruction base, Field f, IR::Instruction rhs) { exists(IR::FieldTarget trg | trg = super.getLhs() | ( diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index 48d027d49fa..6121d716abf 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -90,10 +90,9 @@ module OpenUrlRedirect { */ class PathAssignmentBarrier extends Barrier, Read { PathAssignmentBarrier() { - exists(Write w, DataFlow::Node base, SsaWithFields var | + exists(Write w, SsaWithFields var | hasHostnameSanitizingSubstring(w.getRhs()) and - w.writesField(base, any(Field f | f.getName() = "Path"), _) and - [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = var.getAUse() and + w.writesFieldOnSsaWithFields(var, any(Field f | f.getName() = "Path"), _) and useIsDominated(var, w, this) ) } diff --git a/go/ql/lib/semmle/go/security/RequestForgery.qll b/go/ql/lib/semmle/go/security/RequestForgery.qll index 8508d0dda96..9497f528004 100644 --- a/go/ql/lib/semmle/go/security/RequestForgery.qll +++ b/go/ql/lib/semmle/go/security/RequestForgery.qll @@ -27,11 +27,8 @@ module RequestForgery { predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { // propagate to a URL when its host is assigned to - exists(Write w, DataFlow::Node base, Field f, SsaWithFields v | - f.hasQualifiedName("net/url", "URL", "Host") - | - w.writesField(base, f, pred) and - [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = v.getAUse() and + exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | + w.writesFieldOnSsaWithFields(v, f, pred) and succ = v.getAUse() ) } diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll index e53214955d5..a1f5ad7051b 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll @@ -23,11 +23,8 @@ module SafeUrlFlow { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // propagate to a URL when its host is assigned to - exists(Write w, DataFlow::Node base, Field f, SsaWithFields v | - f.hasQualifiedName("net/url", "URL", "Host") - | - w.writesField(base, f, node1) and - [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = v.getAUse() and + exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | + w.writesFieldOnSsaWithFields(v, f, node1) and node2 = v.getAUse() ) } diff --git a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql index e88b7bf0f95..f7c35b78d87 100644 --- a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql +++ b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql @@ -98,15 +98,8 @@ predicate hostCheckReachesSink(Flow::PathNode sink) { Flow::flowPath(source, otherSink) and Config::writeIsSink(sink.getNode(), sinkWrite) and Config::writeIsSink(otherSink.getNode(), otherSinkWrite) and - exists(DataFlow::Node base1 | - sinkWrite.writesField(base1, _, sink.getNode()) and - [base1, base1.(DataFlow::PostUpdateNode).getPreUpdateNode()] = sinkAccessPath.getAUse() - ) and - exists(DataFlow::Node base2 | - otherSinkWrite.writesField(base2, _, otherSink.getNode()) and - [base2, base2.(DataFlow::PostUpdateNode).getPreUpdateNode()] = - otherSinkAccessPath.getAUse() - ) and + sinkWrite.writesFieldOnSsaWithFields(sinkAccessPath, _, sink.getNode()) and + otherSinkWrite.writesFieldOnSsaWithFields(otherSinkAccessPath, _, otherSink.getNode()) and otherSinkAccessPath = sinkAccessPath.similar() ) ) diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index aa4bccb4599..0879534d666 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -22,11 +22,8 @@ module ServerSideRequestForgery { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // propagate to a URL when its host is assigned to - exists(Write w, DataFlow::Node base, Field f, SsaWithFields v | - f.hasQualifiedName("net/url", "URL", "Host") - | - w.writesField(base, f, node1) and - [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = v.getAUse() and + exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | + w.writesFieldOnSsaWithFields(v, f, node1) and node2 = v.getAUse() ) } From 62155876c59c4d0c757a970351adc8ad435c3e0d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 18 Sep 2025 16:31:29 +0100 Subject: [PATCH 36/70] Fix flow to variable capture The jump step to a `SsaCaptureVariable` should start at the last use before it, rather than from the previous definition. --- .../go/dataflow/internal/DataFlowPrivate.qll | 15 ++++++++--- .../frameworks/Twirp/RequestForgery.expected | 26 +++++-------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 613441f9868..57ca5bea110 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -120,11 +120,18 @@ predicate jumpStep(Node n1, Node n2) { n2 = v.getARead() ) or - exists(SsaDefinition pred, SsaDefinition succ | - succ.(SsaVariableCapture).getSourceVariable() = pred.(SsaExplicitDefinition).getSourceVariable() - | - n1 = ssaNode(pred) and + exists(SsaExplicitDefinition def, SsaVariableCapture succ | + succ.getSourceVariable() = def.getSourceVariable() and n2 = ssaNode(succ) + | + not exists(def.getAFirstUse()) and n1 = ssaNode(def) + or + exists(IR::Instruction lastUse | + lastUse = getAnAdjacentUse*(def.getAFirstUse()) and + not exists(getAnAdjacentUse(lastUse)) + | + [n1, n1.(DataFlow::PostUpdateNode).getPreUpdateNode()] = instructionNode(lastUse) + ) ) or // If a channel-typed field is referenced exactly once in the context of diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.expected b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.expected index 6bda68257ef..7b1fa1a3121 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.expected @@ -3,42 +3,28 @@ | server/main.go:30:38:30:48 | selection of Text | server/main.go:19:56:19:61 | definition of params | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | server/main.go:19:56:19:61 | definition of params | user-provided value | edges | client/main.go:16:35:16:78 | &... | server/main.go:19:56:19:61 | definition of params | provenance | | -| rpc/notes/service.twirp.go:473:6:473:13 | definition of typedReq | rpc/notes/service.twirp.go:477:44:477:51 | typedReq | provenance | | -| rpc/notes/service.twirp.go:477:44:477:51 | typedReq | server/main.go:19:56:19:61 | definition of params | provenance | | -| rpc/notes/service.twirp.go:493:2:496:2 | capture variable reqContent | rpc/notes/service.twirp.go:495:35:495:44 | reqContent | provenance | | -| rpc/notes/service.twirp.go:495:35:495:44 | reqContent | server/main.go:19:56:19:61 | definition of params | provenance | | +| client/main.go:16:35:16:78 | &... [postupdate] | client/main.go:16:35:16:78 | &... | provenance | | | rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | rpc/notes/service.twirp.go:544:27:544:29 | buf | provenance | | | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | provenance | Src:MaD:1 MaD:3 | -| rpc/notes/service.twirp.go:543:2:543:11 | definition of reqContent | rpc/notes/service.twirp.go:574:2:577:2 | capture variable reqContent | provenance | | -| rpc/notes/service.twirp.go:544:27:544:29 | buf | rpc/notes/service.twirp.go:543:2:543:11 | definition of reqContent | provenance | MaD:2 | -| rpc/notes/service.twirp.go:554:6:554:13 | definition of typedReq | rpc/notes/service.twirp.go:558:44:558:51 | typedReq | provenance | | -| rpc/notes/service.twirp.go:558:44:558:51 | typedReq | server/main.go:19:56:19:61 | definition of params | provenance | | +| rpc/notes/service.twirp.go:544:27:544:29 | buf | rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | provenance | MaD:2 | +| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | rpc/notes/service.twirp.go:574:2:577:2 | capture variable reqContent | provenance | | | rpc/notes/service.twirp.go:574:2:577:2 | capture variable reqContent | rpc/notes/service.twirp.go:576:35:576:44 | reqContent | provenance | | | rpc/notes/service.twirp.go:576:35:576:44 | reqContent | server/main.go:19:56:19:61 | definition of params | provenance | | | server/main.go:19:56:19:61 | definition of params | server/main.go:19:56:19:61 | definition of params [Return] | provenance | | | server/main.go:19:56:19:61 | definition of params | server/main.go:30:38:30:48 | selection of Text | provenance | | | server/main.go:19:56:19:61 | definition of params | server/main.go:30:38:30:48 | selection of Text | provenance | | -| server/main.go:19:56:19:61 | definition of params [Return] | client/main.go:16:35:16:78 | &... | provenance | | -| server/main.go:19:56:19:61 | definition of params [Return] | rpc/notes/service.twirp.go:473:6:473:13 | definition of typedReq | provenance | | -| server/main.go:19:56:19:61 | definition of params [Return] | rpc/notes/service.twirp.go:493:2:496:2 | capture variable reqContent | provenance | | -| server/main.go:19:56:19:61 | definition of params [Return] | rpc/notes/service.twirp.go:554:6:554:13 | definition of typedReq | provenance | | -| server/main.go:19:56:19:61 | definition of params [Return] | rpc/notes/service.twirp.go:574:2:577:2 | capture variable reqContent | provenance | | +| server/main.go:19:56:19:61 | definition of params [Return] | client/main.go:16:35:16:78 | &... [postupdate] | provenance | | models | 1 | Source: net/http; Request; true; Body; ; ; ; remote; manual | | 2 | Summary: google.golang.org/protobuf/proto; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual | | 3 | Summary: io; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual | nodes | client/main.go:16:35:16:78 | &... | semmle.label | &... | -| rpc/notes/service.twirp.go:473:6:473:13 | definition of typedReq | semmle.label | definition of typedReq | -| rpc/notes/service.twirp.go:477:44:477:51 | typedReq | semmle.label | typedReq | -| rpc/notes/service.twirp.go:493:2:496:2 | capture variable reqContent | semmle.label | capture variable reqContent | -| rpc/notes/service.twirp.go:495:35:495:44 | reqContent | semmle.label | reqContent | +| client/main.go:16:35:16:78 | &... [postupdate] | semmle.label | &... [postupdate] | | rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | semmle.label | ... := ...[0] | | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | semmle.label | selection of Body | -| rpc/notes/service.twirp.go:543:2:543:11 | definition of reqContent | semmle.label | definition of reqContent | | rpc/notes/service.twirp.go:544:27:544:29 | buf | semmle.label | buf | -| rpc/notes/service.twirp.go:554:6:554:13 | definition of typedReq | semmle.label | definition of typedReq | -| rpc/notes/service.twirp.go:558:44:558:51 | typedReq | semmle.label | typedReq | +| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | semmle.label | reqContent [postupdate] | | rpc/notes/service.twirp.go:574:2:577:2 | capture variable reqContent | semmle.label | capture variable reqContent | | rpc/notes/service.twirp.go:576:35:576:44 | reqContent | semmle.label | reqContent | | server/main.go:19:56:19:61 | definition of params | semmle.label | definition of params | From 3906f2560d356a822b11d0147ec7d9f58fec074e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 18 Sep 2025 17:02:40 +0100 Subject: [PATCH 37/70] Adjust Stack Exposure test so it passes A minor bug in our CFG means that we evaluate the base of a SliceExpr before the bounds. Since the bounds may have side effects, as in this case, it would be better to evaluate them first. But in the short term I am just adjusting the test to make it work. --- .../Security/CWE-209/StackTraceExposure.expected | 8 ++++---- go/ql/test/query-tests/Security/CWE-209/test.go | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) 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 c62c6126648..732b9cd5cae 100644 --- a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,8 +1,8 @@ edges -| test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | provenance | | +| test.go:15:28:15:30 | buf [postupdate] | test.go:18:10:18:12 | buf | provenance | | nodes -| test.go:14:2:14:4 | definition of buf | semmle.label | definition of buf | -| test.go:17:10:17:12 | buf | semmle.label | buf | +| test.go:15:28:15:30 | buf [postupdate] | semmle.label | buf [postupdate] | +| test.go:18:10:18:12 | buf | semmle.label | buf | 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 | +| test.go:18:10:18:12 | buf | test.go:15:28:15:30 | buf [postupdate] | test.go:18:10:18:12 | buf | HTTP response depends on $@ and may be exposed to an external user. | test.go:15:28:15:30 | buf [postupdate] | stack trace information | diff --git a/go/ql/test/query-tests/Security/CWE-209/test.go b/go/ql/test/query-tests/Security/CWE-209/test.go index 2ad35680048..77df73b8046 100644 --- a/go/ql/test/query-tests/Security/CWE-209/test.go +++ b/go/ql/test/query-tests/Security/CWE-209/test.go @@ -12,7 +12,8 @@ var logger log.Logger func handlePanic(w http.ResponseWriter, r *http.Request) { buf := make([]byte, 2<<16) - buf = buf[:runtime.Stack(buf, true)] + stackLen := runtime.Stack(buf, true) + buf = buf[:stackLen] // BAD: printing a stack trace back to the response w.Write(buf) // GOOD: logging the response to the server and sending From 5efc8ac1a45b6fffa78bdb1ec64dc50c4876ceff Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 23 Sep 2025 22:06:42 +0100 Subject: [PATCH 38/70] Fix backwards flow through TaintTracking::FunctionModel We only do this for taint models as there isn't any backwards flow through data flow function models. --- .../dataflow/internal/TaintTrackingUtil.qll | 64 +++++++++++++++---- .../frameworks/TaintSteps/TaintStep.expected | 6 +- .../Security/CWE-640/EmailInjection.expected | 33 +++++----- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index ff5b4f74e77..dc350eac5a6 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -83,11 +83,9 @@ class AdditionalTaintStep extends Unit { abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); } -/** - * Holds if the additional step from `pred` to `succ` should be included in all - * global taint flow configurations. - */ -predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ, string model) { +private predicate localAdditionalForwardTaintStep( + DataFlow::Node pred, DataFlow::Node succ, string model +) { exists(DataFlow::Node pred2 | pred2 = pred or @@ -103,7 +101,7 @@ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ, str ) and model = "" or - any(FunctionModel fm).taintStep(pred, succ) and model = "FunctionModel" + any(FunctionModel fm).forwardTaintStep(pred, succ) and model = "FunctionModel" or any(AdditionalTaintStep a).step(pred, succ) and model = "AdditionalTaintStep" or @@ -111,6 +109,37 @@ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ, str .getSummaryNode(), succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false, model) } +private predicate localForwardTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + DataFlow::localFlow(pred, succ) or + localAdditionalForwardTaintStep(pred, succ, _) 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(pred, succ, _) +} + +/** + * Holds if taint flows backwards from `pred` to `succ` via a function model. + */ +private predicate localAdditionalBackwardTaintStep( + DataFlow::Node pred, DataFlow::Node succ, string model +) { + // backward step through function model + exists(FunctionModel m, DataFlow::Node resultNode | + m.backwardTaintStep(resultNode, succ) and + localForwardTaintStep+(resultNode, pred.(DataFlow::PostUpdateNode).getPreUpdateNode()) + ) and + model = "FunctionModel" +} + +/** + * Holds if the additional step from `pred` to `succ` should be included in all + * global taint flow configurations. + */ +predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ, string model) { + localAdditionalForwardTaintStep(pred, succ, model) or + localAdditionalBackwardTaintStep(pred, succ, model) +} + /** * Holds if taint flows from `pred` to `succ` via a reference or dereference. * @@ -199,23 +228,36 @@ abstract class FunctionModel extends Function { abstract predicate hasTaintFlow(FunctionInput input, FunctionOutput output); /** Gets an input node for this model for the call `c`. */ - DataFlow::Node getAnInputNode(DataFlow::CallNode c) { this.taintStepForCall(result, _, c) } + DataFlow::Node getAnInputNode(DataFlow::CallNode c) { this.taintStepForCall(result, _, c, _) } /** Gets an output node for this model for the call `c`. */ - DataFlow::Node getAnOutputNode(DataFlow::CallNode c) { this.taintStepForCall(_, result, c) } + DataFlow::Node getAnOutputNode(DataFlow::CallNode c) { this.taintStepForCall(_, result, c, _) } /** Holds if this function model causes taint to flow from `pred` to `succ` for the call `c`. */ - predicate taintStepForCall(DataFlow::Node pred, DataFlow::Node succ, DataFlow::CallNode c) { + predicate taintStepForCall( + DataFlow::Node pred, DataFlow::Node succ, DataFlow::CallNode c, Boolean forward + ) { c = this.getACall() and exists(FunctionInput inp, FunctionOutput outp | this.hasTaintFlow(inp, outp) | pred = pragma[only_bind_out](inp).getNode(c) and - succ = pragma[only_bind_out](outp).getNode(c) + succ = pragma[only_bind_out](outp).getNode(c) and + if inp.isResult() or inp.isResult(_) then forward = false else forward = true ) } /** Holds if this function model causes taint to flow from `pred` to `succ`. */ predicate taintStep(DataFlow::Node pred, DataFlow::Node succ) { - this.taintStepForCall(pred, succ, _) + this.taintStepForCall(pred, succ, _, _) + } + + /** Holds if this function model causes taint to flow forward from `pred` to `succ`. */ + predicate forwardTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + this.taintStepForCall(pred, succ, _, true) + } + + /** Holds if this function model causes taint to flow backwards from `pred` to `succ`. */ + predicate backwardTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + this.taintStepForCall(pred, succ, _, false) } } 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 3bccd586d74..cfbbc771f77 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 @@ -8,8 +8,6 @@ invalidModelRow | crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | ... := ...[1] | | crypto.go:11:42:11:51 | ciphertext | crypto.go:11:2:11:57 | ... := ...[0] | | 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 | &... [postupdate] | -| io.go:16:3:16:3 | definition of w | io.go:16:30:16:34 | &... [postupdate] | | io.go:16:23:16:27 | &... | io.go:16:24:16:27 | buf1 [postupdate] | | io.go:16:23:16:27 | &... [postupdate] | io.go:16:24:16:27 | buf1 [postupdate] | | io.go:16:24:16:27 | buf1 | io.go:16:23:16:27 | &... | @@ -18,6 +16,8 @@ invalidModelRow | io.go:16:30:16:34 | &... [postupdate] | io.go:16:31:16:34 | buf2 [postupdate] | | io.go:16:31:16:34 | buf2 | io.go:16:30:16:34 | &... | | io.go:16:31:16:34 | buf2 [postupdate] | io.go:16:30:16:34 | &... | +| io.go:18:11:18:11 | w [postupdate] | io.go:16:23:16:27 | &... [postupdate] | +| io.go:18:11:18:11 | w [postupdate] | io.go:16:30:16:34 | &... [postupdate] | | io.go:18:14:18:19 | reader | io.go:18:11:18:11 | w [postupdate] | | io.go:22:31:22:43 | "some string" | io.go:22:13:22:44 | call to NewReader | | io.go:25:19:25:23 | &... | io.go:25:20:25:23 | buf1 [postupdate] | @@ -31,9 +31,9 @@ invalidModelRow | io.go:33:20:33:23 | buf1 | io.go:33:19:33:23 | &... | | io.go:33:20:33:23 | buf1 [postupdate] | io.go:33:19:33:23 | &... | | io.go:35:16:35:21 | reader | io.go:35:12:35:13 | w2 [postupdate] | -| io.go:39:6:39:6 | definition of w | io.go:39:3:39:19 | ... := ...[0] | | 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:14:40:14 | w [postupdate] | io.go:39:3:39:19 | ... := ...[0] | | io.go:40:17:40:31 | "some string\\n" | io.go:40:14:40:14 | w [postupdate] | | io.go:43:16:43:16 | r | io.go:43:3:43:5 | buf [postupdate] | | io.go:44:13:44:15 | buf | io.go:44:13:44:24 | call to String | diff --git a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected index c56e35fa7a8..06f61ee8956 100644 --- a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected @@ -1,7 +1,6 @@ #select | EmailBad.go:12:56:12:67 | type conversion | EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:12:56:12:67 | type conversion | Email content may contain $@. | EmailBad.go:9:10:9:17 | selection of Header | untrusted input | | main.go:33:57:33:78 | type conversion | main.go:31:21:31:31 | call to Referer | main.go:33:57:33:78 | type conversion | Email content may contain $@. | main.go:31:21:31:31 | call to Referer | untrusted input | -| main.go:42:3:42:7 | definition of write | main.go:39:21:39:31 | call to Referer | main.go:42:3:42:7 | definition of write | Email content may contain $@. | main.go:39:21:39:31 | call to Referer | untrusted input | | main.go:54:46:54:59 | untrustedInput | main.go:48:21:48:31 | call to Referer | main.go:54:46:54:59 | untrustedInput | Email content may contain $@. | main.go:48:21:48:31 | call to Referer | untrusted input | | main.go:55:52:55:65 | untrustedInput | main.go:48:21:48:31 | call to Referer | main.go:55:52:55:65 | untrustedInput | Email content may contain $@. | main.go:48:21:48:31 | call to Referer | untrusted input | | main.go:65:16:65:22 | content | main.go:60:21:60:31 | call to Referer | main.go:65:16:65:22 | content | Email content may contain $@. | main.go:60:21:60:31 | call to Referer | untrusted input | @@ -16,8 +15,6 @@ edges | EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:9:10:9:29 | call to Get | provenance | Src:MaD:1 MaD:7 | | EmailBad.go:9:10:9:29 | call to Get | EmailBad.go:12:56:12:67 | type conversion | provenance | | | main.go:31:21:31:31 | call to Referer | main.go:33:57:33:78 | type conversion | provenance | Src:MaD:2 | -| main.go:39:21:39:31 | call to Referer | main.go:43:25:43:38 | untrustedInput | provenance | Src:MaD:2 | -| main.go:43:25:43:38 | untrustedInput | main.go:42:3:42:7 | definition of write | provenance | MaD:5 | | main.go:48:21:48:31 | call to Referer | main.go:54:46:54:59 | untrustedInput | provenance | Src:MaD:2 | | main.go:48:21:48:31 | call to Referer | main.go:55:52:55:65 | untrustedInput | provenance | Src:MaD:2 | | main.go:60:21:60:31 | call to Referer | main.go:62:47:62:60 | untrustedInput | provenance | Src:MaD:2 | @@ -33,15 +30,15 @@ edges | main.go:93:15:93:62 | call to NewContent | main.go:95:16:95:23 | content2 | provenance | | | main.go:93:48:93:61 | untrustedInput | main.go:93:15:93:62 | call to NewContent | provenance | MaD:4 | | main.go:113:21:113:31 | call to Referer | main.go:119:28:119:41 | untrustedInput | provenance | Src:MaD:2 | -| main.go:116:3:116:4 | definition of mw | main.go:116:29:116:30 | &... | provenance | FunctionModel | -| main.go:116:29:116:30 | &... | main.go:124:57:124:57 | b | provenance | | -| main.go:119:28:119:41 | untrustedInput | main.go:116:3:116:4 | definition of mw | provenance | MaD:6 | +| main.go:116:29:116:30 | &... [postupdate] | main.go:124:57:124:57 | b | provenance | | +| main.go:119:3:119:4 | mw [postupdate] | main.go:116:29:116:30 | &... [postupdate] | provenance | FunctionModel | +| main.go:119:28:119:41 | untrustedInput | main.go:119:3:119:4 | mw [postupdate] | provenance | MaD:6 | | main.go:124:57:124:57 | b | main.go:124:57:124:65 | call to Bytes | provenance | MaD:3 | | main.go:129:21:129:31 | call to Referer | main.go:136:30:136:43 | untrustedInput | provenance | Src:MaD:2 | -| main.go:132:3:132:4 | definition of mw | main.go:132:29:132:30 | &... | provenance | FunctionModel | -| main.go:132:29:132:30 | &... | main.go:141:57:141:57 | b | provenance | | -| main.go:135:3:135:12 | definition of formWriter | main.go:132:3:132:4 | definition of mw | provenance | FunctionModel | -| main.go:136:30:136:43 | untrustedInput | main.go:135:3:135:12 | definition of formWriter | provenance | MaD:5 | +| main.go:132:29:132:30 | &... [postupdate] | main.go:141:57:141:57 | b | provenance | | +| main.go:135:20:135:21 | mw [postupdate] | main.go:132:29:132:30 | &... [postupdate] | provenance | FunctionModel | +| main.go:136:18:136:27 | formWriter [postupdate] | main.go:135:20:135:21 | mw [postupdate] | provenance | FunctionModel | +| main.go:136:30:136:43 | untrustedInput | main.go:136:18:136:27 | formWriter [postupdate] | provenance | MaD:5 | | main.go:141:57:141:57 | b | main.go:141:57:141:65 | call to Bytes | provenance | MaD:3 | models | 1 | Source: net/http; Request; true; Header; ; ; ; remote; manual | @@ -57,9 +54,6 @@ nodes | EmailBad.go:12:56:12:67 | type conversion | semmle.label | type conversion | | main.go:31:21:31:31 | call to Referer | semmle.label | call to Referer | | main.go:33:57:33:78 | type conversion | semmle.label | type conversion | -| main.go:39:21:39:31 | call to Referer | semmle.label | call to Referer | -| main.go:42:3:42:7 | definition of write | semmle.label | definition of write | -| main.go:43:25:43:38 | untrustedInput | semmle.label | untrustedInput | | main.go:48:21:48:31 | call to Referer | semmle.label | call to Referer | | main.go:54:46:54:59 | untrustedInput | semmle.label | untrustedInput | | main.go:55:52:55:65 | untrustedInput | semmle.label | untrustedInput | @@ -79,16 +73,19 @@ nodes | main.go:93:48:93:61 | untrustedInput | semmle.label | untrustedInput | | main.go:95:16:95:23 | content2 | semmle.label | content2 | | main.go:113:21:113:31 | call to Referer | semmle.label | call to Referer | -| main.go:116:3:116:4 | definition of mw | semmle.label | definition of mw | -| main.go:116:29:116:30 | &... | semmle.label | &... | +| main.go:116:29:116:30 | &... [postupdate] | semmle.label | &... [postupdate] | +| main.go:119:3:119:4 | mw [postupdate] | semmle.label | mw [postupdate] | | main.go:119:28:119:41 | untrustedInput | semmle.label | untrustedInput | | main.go:124:57:124:57 | b | semmle.label | b | | main.go:124:57:124:65 | call to Bytes | semmle.label | call to Bytes | | main.go:129:21:129:31 | call to Referer | semmle.label | call to Referer | -| main.go:132:3:132:4 | definition of mw | semmle.label | definition of mw | -| main.go:132:29:132:30 | &... | semmle.label | &... | -| main.go:135:3:135:12 | definition of formWriter | semmle.label | definition of formWriter | +| main.go:132:29:132:30 | &... [postupdate] | semmle.label | &... [postupdate] | +| main.go:135:20:135:21 | mw [postupdate] | semmle.label | mw [postupdate] | +| main.go:136:18:136:27 | formWriter [postupdate] | semmle.label | formWriter [postupdate] | | main.go:136:30:136:43 | untrustedInput | semmle.label | untrustedInput | | main.go:141:57:141:57 | b | semmle.label | b | | main.go:141:57:141:65 | call to Bytes | semmle.label | call to Bytes | subpaths +testFailures +| main.go:39:33:39:43 | comment | Missing result: Source | +| main.go:42:24:42:33 | comment | Missing result: Alert | From 6cb69535a555936ce44ef4c8ff3d0f50acaccfd4 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 19 Sep 2025 09:34:51 +0100 Subject: [PATCH 39/70] Add missing qldocs --- go/ql/lib/semmle/go/controlflow/IR.qll | 1 + go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll | 1 + 2 files changed, 2 insertions(+) diff --git a/go/ql/lib/semmle/go/controlflow/IR.qll b/go/ql/lib/semmle/go/controlflow/IR.qll index 2b8a30437bb..2c8b673184e 100644 --- a/go/ql/lib/semmle/go/controlflow/IR.qll +++ b/go/ql/lib/semmle/go/controlflow/IR.qll @@ -446,6 +446,7 @@ module IR { /** Gets the target to which this instruction writes. */ WriteTarget getLhs() { result = lhs } + /** Holds if this instruction initializes a literal. */ predicate isInitialization() { initialization = true } /** Gets the instruction computing the value this instruction writes. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 5e9cc7f6b74..d48335d299f 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -817,6 +817,7 @@ module Public { abstract Node getPreUpdateNode(); } + /** Holds if the node corresponding to `insn` has a post-update node. */ predicate insnHasPostUpdateNode(IR::Instruction insn) { exists(Expr e | insn.(IR::EvalInstruction).getExpr() = e | e instanceof AddressExpr or From a9420d46c895a404925fe0b65bc8e2c1d4923b36 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 19 Sep 2025 15:22:12 +0100 Subject: [PATCH 40/70] Fix bad join order --- go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 57ca5bea110..df352dc03d8 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -103,6 +103,10 @@ private Field getASparselyUsedChannelTypedField() { count(result.getARead()) = 2 } +bindingset[v] +pragma[inline_late] +private predicate jumpStepHelper(ValueEntity v, Node n) { n = v.getARead() } + /** * Holds if data can flow from `node1` to `node2` in a way that loses the * calling context. For example, this would happen with flow through a @@ -117,7 +121,7 @@ predicate jumpStep(Node n1, Node n2) { or n1.(DataFlow::PostUpdateNode).getPreUpdateNode() = v.getARead() ) and - n2 = v.getARead() + jumpStepHelper(v, n2) ) or exists(SsaExplicitDefinition def, SsaVariableCapture succ | From 52b65396970f61a93853c36aa51022718d38dd81 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:47:03 +0100 Subject: [PATCH 41/70] Typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go b/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go index a15fb819ccc..4a9f4e161f6 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go @@ -178,7 +178,7 @@ func testLocalRedirects(ctx echo.Context) error { param := ctx.Param("someParam") param2 := param param3 := param - // Gratuitious copy because sanitization of uses propagates to subsequent uses + // Gratuitous copy because sanitization of uses propagates to subsequent uses // GOOD: local redirects are unproblematic ctx.Redirect(301, "/local"+param) // BAD: this could be a non-local redirect From f5f6d64d9d35843e71c63711fafc3d2b258de912 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 19 Sep 2025 16:46:18 +0100 Subject: [PATCH 42/70] Add change notes --- go/ql/lib/change-notes/2025-09-19-api-changes.md | 6 ++++++ .../2025-09-19-use-use-flow-proper-post-update-nodes.md | 4 ++++ 2 files changed, 10 insertions(+) create mode 100644 go/ql/lib/change-notes/2025-09-19-api-changes.md create mode 100644 go/ql/lib/change-notes/2025-09-19-use-use-flow-proper-post-update-nodes.md diff --git a/go/ql/lib/change-notes/2025-09-19-api-changes.md b/go/ql/lib/change-notes/2025-09-19-api-changes.md new file mode 100644 index 00000000000..44f070fb1d7 --- /dev/null +++ b/go/ql/lib/change-notes/2025-09-19-api-changes.md @@ -0,0 +1,6 @@ +--- +category: breaking +--- +* The member predicate `writesField(DataFlow::Node base, Field f, DataFlow::Node rhs)` on `DataFlow::Write` now uses the post-update node for `base` when that is the node being updated, which is in all cases except initializing a struct literal. A new member predicate `writesFieldOnSsaWithFields(SsaWithFields v, Field f, DataFlow::Node rhs)` has been added for the case of writes to a SsaWithFields node. +* The member predicate `writesElement(DataFlow::Node base, DataFlow::Node index, DataFlow::Node rhs)` on `DataFlow::Write` now uses the post-update node for `base` when that is the node being updated, which is in all cases except initializing an array/slice/map literal. +* The member predicate `writesComponent(DataFlow::Node base, DataFlow::Node rhs)` on `DataFlow::Write` now uses the post-update node for `base` when that is the node being updated, which is in all cases except initializing a struct/array/slice/map literal. diff --git a/go/ql/lib/change-notes/2025-09-19-use-use-flow-proper-post-update-nodes.md b/go/ql/lib/change-notes/2025-09-19-use-use-flow-proper-post-update-nodes.md new file mode 100644 index 00000000000..e0ffe72002b --- /dev/null +++ b/go/ql/lib/change-notes/2025-09-19-use-use-flow-proper-post-update-nodes.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* Previously, data flow used def-use flow and a node's post-update node was either its definition or the node itself. This caused some problems with false positives caused by steps backwards from a node to its definition. Now, data flow has been changed to use-use flow with proper post-update nodes. This should improve accuracy and reduce false positives in the analysis. The main effect on queries is that sanitization works differently - if you sanitize a node then flow will not reach any uses after the sanitized node. Where this is not desired it maybe be necessary to add an additional flow step to propagate the flow forward. From 25f182302d5bdabcd22b201193395bfb4aaaa714 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 18 Sep 2025 11:58:09 +0100 Subject: [PATCH 43/70] Fix email injection sink that needs local flow --- go/ql/lib/semmle/go/frameworks/Email.qll | 24 +++++++++++++-- .../go/frameworks/Email/EmailData.expected | 3 -- .../Security/CWE-640/EmailInjection.expected | 30 ++++++++++++++----- .../test/query-tests/Security/CWE-640/main.go | 17 +++++++++-- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/go/ql/lib/semmle/go/frameworks/Email.qll b/go/ql/lib/semmle/go/frameworks/Email.qll index a1d43d3c397..d7744951c08 100644 --- a/go/ql/lib/semmle/go/frameworks/Email.qll +++ b/go/ql/lib/semmle/go/frameworks/Email.qll @@ -26,9 +26,14 @@ module EmailData { private class SmtpData extends Range { SmtpData() { // func (c *Client) Data() (io.WriteCloser, error) - exists(Method data | + exists(Method data, DataFlow::Node n | data.hasQualifiedName("net/smtp", "Client", "Data") and - this.(DataFlow::SsaNode).getInit() = data.getACall().getResult(0) + // Deal with cases like + // w, _ := s.Data() + // io.WriteString(w, source()) // $ Alert + // w.Write(source()) // $ Alert + DataFlow::localFlow(data.getACall().getResult(0), n) and + this.(DataFlow::PostUpdateNode).getPreUpdateNode() = n ) or // func SendMail(addr string, a Auth, from string, to []string, msg []byte) error @@ -98,3 +103,18 @@ private class MultipartNewWriterModel extends TaintTracking::FunctionModel { input.isResult() and output.isParameter(0) } } +// /** +// * A taint model of the `Data` method of `Client` from `net/smtp`. +// * +// * If tainted data is written to the writer created by this method, the client +// * should be considered tainted as well. +// */ +// private class SmtpClientDataModel extends TaintTracking::FunctionModel, Method { +// SmtpClientDataModel() { +// // func (c *Client) Data() (io.WriteCloser, error) +// this.hasQualifiedName("net/smtp", "Client", "Data") +// } +// override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { +// input.isResult(0) and output.isReceiver() +// } +// } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Email/EmailData.expected b/go/ql/test/library-tests/semmle/go/frameworks/Email/EmailData.expected index 070800dab63..3324ee56033 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Email/EmailData.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Email/EmailData.expected @@ -1,7 +1,4 @@ | mail.go:15:73:15:94 | type conversion | -| mail.go:18:19:18:23 | definition of write | -| mail.go:18:19:18:38 | ... := ...[0] | -| mail.go:20:17:20:21 | write | | mail.go:20:17:20:21 | write [postupdate] | | mail.go:26:49:26:52 | text | | mail.go:26:76:26:79 | text | diff --git a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected index 06f61ee8956..aa4b4914c18 100644 --- a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected @@ -1,6 +1,7 @@ #select | EmailBad.go:12:56:12:67 | type conversion | EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:12:56:12:67 | type conversion | Email content may contain $@. | EmailBad.go:9:10:9:17 | selection of Header | untrusted input | | main.go:33:57:33:78 | type conversion | main.go:31:21:31:31 | call to Referer | main.go:33:57:33:78 | type conversion | Email content may contain $@. | main.go:31:21:31:31 | call to Referer | untrusted input | +| main.go:43:18:43:22 | write [postupdate] | main.go:39:21:39:31 | call to Referer | main.go:43:18:43:22 | write [postupdate] | Email content may contain $@. | main.go:39:21:39:31 | call to Referer | untrusted input | | main.go:54:46:54:59 | untrustedInput | main.go:48:21:48:31 | call to Referer | main.go:54:46:54:59 | untrustedInput | Email content may contain $@. | main.go:48:21:48:31 | call to Referer | untrusted input | | main.go:55:52:55:65 | untrustedInput | main.go:48:21:48:31 | call to Referer | main.go:55:52:55:65 | untrustedInput | Email content may contain $@. | main.go:48:21:48:31 | call to Referer | untrusted input | | main.go:65:16:65:22 | content | main.go:60:21:60:31 | call to Referer | main.go:65:16:65:22 | content | Email content may contain $@. | main.go:60:21:60:31 | call to Referer | untrusted input | @@ -11,10 +12,14 @@ | main.go:95:16:95:23 | content2 | main.go:84:21:84:31 | call to Referer | main.go:95:16:95:23 | content2 | Email content may contain $@. | main.go:84:21:84:31 | call to Referer | untrusted input | | main.go:124:57:124:65 | call to Bytes | main.go:113:21:113:31 | call to Referer | main.go:124:57:124:65 | call to Bytes | Email content may contain $@. | main.go:113:21:113:31 | call to Referer | untrusted input | | main.go:141:57:141:65 | call to Bytes | main.go:129:21:129:31 | call to Referer | main.go:141:57:141:65 | call to Bytes | Email content may contain $@. | main.go:129:21:129:31 | call to Referer | untrusted input | +| main.go:151:3:151:3 | w [postupdate] | main.go:146:22:146:32 | call to Referer | main.go:151:3:151:3 | w [postupdate] | Email content may contain $@. | main.go:146:22:146:32 | call to Referer | untrusted input | +| main.go:152:3:152:3 | w [postupdate] | main.go:147:22:147:32 | call to Referer | main.go:152:3:152:3 | w [postupdate] | Email content may contain $@. | main.go:147:22:147:32 | call to Referer | untrusted input | edges -| EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:9:10:9:29 | call to Get | provenance | Src:MaD:1 MaD:7 | +| EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:9:10:9:29 | call to Get | provenance | Src:MaD:1 MaD:8 | | EmailBad.go:9:10:9:29 | call to Get | EmailBad.go:12:56:12:67 | type conversion | provenance | | | main.go:31:21:31:31 | call to Referer | main.go:33:57:33:78 | type conversion | provenance | Src:MaD:2 | +| main.go:39:21:39:31 | call to Referer | main.go:43:25:43:38 | untrustedInput | provenance | Src:MaD:2 | +| main.go:43:25:43:38 | untrustedInput | main.go:43:18:43:22 | write [postupdate] | provenance | MaD:5 | | main.go:48:21:48:31 | call to Referer | main.go:54:46:54:59 | untrustedInput | provenance | Src:MaD:2 | | main.go:48:21:48:31 | call to Referer | main.go:55:52:55:65 | untrustedInput | provenance | Src:MaD:2 | | main.go:60:21:60:31 | call to Referer | main.go:62:47:62:60 | untrustedInput | provenance | Src:MaD:2 | @@ -32,7 +37,7 @@ edges | main.go:113:21:113:31 | call to Referer | main.go:119:28:119:41 | untrustedInput | provenance | Src:MaD:2 | | main.go:116:29:116:30 | &... [postupdate] | main.go:124:57:124:57 | b | provenance | | | main.go:119:3:119:4 | mw [postupdate] | main.go:116:29:116:30 | &... [postupdate] | provenance | FunctionModel | -| main.go:119:28:119:41 | untrustedInput | main.go:119:3:119:4 | mw [postupdate] | provenance | MaD:6 | +| main.go:119:28:119:41 | untrustedInput | main.go:119:3:119:4 | mw [postupdate] | provenance | MaD:7 | | main.go:124:57:124:57 | b | main.go:124:57:124:65 | call to Bytes | provenance | MaD:3 | | main.go:129:21:129:31 | call to Referer | main.go:136:30:136:43 | untrustedInput | provenance | Src:MaD:2 | | main.go:132:29:132:30 | &... [postupdate] | main.go:141:57:141:57 | b | provenance | | @@ -40,20 +45,28 @@ edges | main.go:136:18:136:27 | formWriter [postupdate] | main.go:135:20:135:21 | mw [postupdate] | provenance | FunctionModel | | main.go:136:30:136:43 | untrustedInput | main.go:136:18:136:27 | formWriter [postupdate] | provenance | MaD:5 | | main.go:141:57:141:57 | b | main.go:141:57:141:65 | call to Bytes | provenance | MaD:3 | +| main.go:146:22:146:32 | call to Referer | main.go:151:11:151:33 | type conversion | provenance | Src:MaD:2 | +| main.go:147:22:147:32 | call to Referer | main.go:152:11:152:33 | type conversion | provenance | Src:MaD:2 | +| main.go:151:11:151:33 | type conversion | main.go:151:3:151:3 | w [postupdate] | provenance | MaD:6 | +| main.go:152:11:152:33 | type conversion | main.go:152:3:152:3 | w [postupdate] | provenance | MaD:6 | models | 1 | Source: net/http; Request; true; Header; ; ; ; remote; manual | | 2 | Source: net/http; Request; true; Referer; ; ; ReturnValue; remote; manual | | 3 | Summary: bytes; Buffer; true; Bytes; ; ; Argument[receiver]; ReturnValue; taint; manual | | 4 | Summary: github.com/sendgrid/sendgrid-go/helpers/mail; ; false; NewContent; ; ; Argument[1]; ReturnValue; taint; manual | | 5 | Summary: io; ; false; WriteString; ; ; Argument[1]; Argument[0]; taint; manual | -| 6 | Summary: mime/multipart; Writer; true; WriteField; ; ; Argument[0..1]; Argument[receiver]; taint; manual | -| 7 | Summary: net/http; Header; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 6 | Summary: io; Writer; true; Write; ; ; Argument[0]; Argument[receiver]; taint; manual | +| 7 | Summary: mime/multipart; Writer; true; WriteField; ; ; Argument[0..1]; Argument[receiver]; taint; manual | +| 8 | Summary: net/http; Header; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | nodes | EmailBad.go:9:10:9:17 | selection of Header | semmle.label | selection of Header | | EmailBad.go:9:10:9:29 | call to Get | semmle.label | call to Get | | EmailBad.go:12:56:12:67 | type conversion | semmle.label | type conversion | | main.go:31:21:31:31 | call to Referer | semmle.label | call to Referer | | main.go:33:57:33:78 | type conversion | semmle.label | type conversion | +| main.go:39:21:39:31 | call to Referer | semmle.label | call to Referer | +| main.go:43:18:43:22 | write [postupdate] | semmle.label | write [postupdate] | +| main.go:43:25:43:38 | untrustedInput | semmle.label | untrustedInput | | main.go:48:21:48:31 | call to Referer | semmle.label | call to Referer | | main.go:54:46:54:59 | untrustedInput | semmle.label | untrustedInput | | main.go:55:52:55:65 | untrustedInput | semmle.label | untrustedInput | @@ -85,7 +98,10 @@ nodes | main.go:136:30:136:43 | untrustedInput | semmle.label | untrustedInput | | main.go:141:57:141:57 | b | semmle.label | b | | main.go:141:57:141:65 | call to Bytes | semmle.label | call to Bytes | +| main.go:146:22:146:32 | call to Referer | semmle.label | call to Referer | +| main.go:147:22:147:32 | call to Referer | semmle.label | call to Referer | +| main.go:151:3:151:3 | w [postupdate] | semmle.label | w [postupdate] | +| main.go:151:11:151:33 | type conversion | semmle.label | type conversion | +| main.go:152:3:152:3 | w [postupdate] | semmle.label | w [postupdate] | +| main.go:152:11:152:33 | type conversion | semmle.label | type conversion | subpaths -testFailures -| main.go:39:33:39:43 | comment | Missing result: Source | -| main.go:42:24:42:33 | comment | Missing result: Alert | diff --git a/go/ql/test/query-tests/Security/CWE-640/main.go b/go/ql/test/query-tests/Security/CWE-640/main.go index f83b413ebc4..73ff8f6b1fb 100644 --- a/go/ql/test/query-tests/Security/CWE-640/main.go +++ b/go/ql/test/query-tests/Security/CWE-640/main.go @@ -39,8 +39,8 @@ func main() { untrustedInput := r.Referer() // $ Source s, _ := smtp.Dial("test.test") - write, _ := s.Data() // $ Alert - io.WriteString(write, untrustedInput) + write, _ := s.Data() + io.WriteString(write, untrustedInput) // $ Alert }) // Not OK @@ -141,6 +141,19 @@ func main() { smtp.SendMail("test.test", nil, "from@from.com", nil, b.Bytes()) // $ Alert }) + // Not OK - check only one result when sink is Client.Data() from net/smtp + { + untrustedInput1 := r.Referer() // $ Source=s1 + untrustedInput2 := r.Referer() // $ Source=s2 + c, _ := smtp.Dial("mail.example.com:smtp") + w, _ := c.Data() + w.Write([]byte("safe text")) + w.Write([]byte(untrustedInput1)) // $ Alert=s1 + w.Write([]byte(untrustedInput2)) // $ Alert=s2 + w.Close() + c.Quit() + } + log.Println(http.ListenAndServe(":80", nil)) } From 4ee236d73fd566d5c1c51b22e2f9c70731381e1f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 11:34:27 +0100 Subject: [PATCH 44/70] Delete commented out code --- go/ql/lib/semmle/go/frameworks/Email.qll | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/go/ql/lib/semmle/go/frameworks/Email.qll b/go/ql/lib/semmle/go/frameworks/Email.qll index d7744951c08..ba4cf8be415 100644 --- a/go/ql/lib/semmle/go/frameworks/Email.qll +++ b/go/ql/lib/semmle/go/frameworks/Email.qll @@ -103,18 +103,3 @@ private class MultipartNewWriterModel extends TaintTracking::FunctionModel { input.isResult() and output.isParameter(0) } } -// /** -// * A taint model of the `Data` method of `Client` from `net/smtp`. -// * -// * If tainted data is written to the writer created by this method, the client -// * should be considered tainted as well. -// */ -// private class SmtpClientDataModel extends TaintTracking::FunctionModel, Method { -// SmtpClientDataModel() { -// // func (c *Client) Data() (io.WriteCloser, error) -// this.hasQualifiedName("net/smtp", "Client", "Data") -// } -// override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { -// input.isResult(0) and output.isReceiver() -// } -// } From 1d9a93a7313ed1ce9006f5fd96fc4f147416e45e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 11:27:28 +0100 Subject: [PATCH 45/70] Rename helper predicate --- go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 4 ++-- 1 file changed, 2 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 df352dc03d8..cd54bb5f1ce 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -105,7 +105,7 @@ private Field getASparselyUsedChannelTypedField() { bindingset[v] pragma[inline_late] -private predicate jumpStepHelper(ValueEntity v, Node n) { n = v.getARead() } +private predicate isValueEntityRead(ValueEntity v, Node n) { n = v.getARead() } /** * Holds if data can flow from `node1` to `node2` in a way that loses the @@ -121,7 +121,7 @@ predicate jumpStep(Node n1, Node n2) { or n1.(DataFlow::PostUpdateNode).getPreUpdateNode() = v.getARead() ) and - jumpStepHelper(v, n2) + isValueEntityRead(v, n2) ) or exists(SsaExplicitDefinition def, SsaVariableCapture succ | From b1bcbec37d5662ec16a3dcf9c7766dc87b630ec6 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 11:31:53 +0100 Subject: [PATCH 46/70] Use slightly less confusing syntax --- go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index cd54bb5f1ce..3f2efd3b492 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -134,7 +134,8 @@ predicate jumpStep(Node n1, Node n2) { lastUse = getAnAdjacentUse*(def.getAFirstUse()) and not exists(getAnAdjacentUse(lastUse)) | - [n1, n1.(DataFlow::PostUpdateNode).getPreUpdateNode()] = instructionNode(lastUse) + n1 = instructionNode(lastUse) or + n1.(DataFlow::PostUpdateNode).getPreUpdateNode() = instructionNode(lastUse) ) ) or From 630a8446ad5ded8a0ea2eda15b1f42ea88921318 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 12:33:42 +0100 Subject: [PATCH 47/70] Rename confusing predicate and add qldoc --- .../semmle/go/dataflow/internal/TaintTrackingUtil.qll | 10 ++++++++-- 1 file changed, 8 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 dc350eac5a6..af28f7f4020 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -109,7 +109,13 @@ private predicate localAdditionalForwardTaintStep( .getSummaryNode(), succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false, model) } -private predicate localForwardTaintStep(DataFlow::Node pred, DataFlow::Node succ) { +/** + * This is a helper predicate for `localAdditionalBackwardTaintStep`. It mixes + * local data flow with local forward taint steps. It should only ever be used + * via its transitive closure, which gives local forward taint flow, that is + * with backward steps excluded. + */ +private predicate partialLocalForwardTaintFlow(DataFlow::Node pred, DataFlow::Node succ) { DataFlow::localFlow(pred, succ) or localAdditionalForwardTaintStep(pred, succ, _) or // Simple flow through library code is included in the exposed local @@ -126,7 +132,7 @@ private predicate localAdditionalBackwardTaintStep( // backward step through function model exists(FunctionModel m, DataFlow::Node resultNode | m.backwardTaintStep(resultNode, succ) and - localForwardTaintStep+(resultNode, pred.(DataFlow::PostUpdateNode).getPreUpdateNode()) + partialLocalForwardTaintFlow+(resultNode, pred.(DataFlow::PostUpdateNode).getPreUpdateNode()) ) and model = "FunctionModel" } From 7b426186aadd2730fa8f0cb90f99e5a53a797e87 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 12:53:55 +0100 Subject: [PATCH 48/70] Rephrase change note to avoid technical terms --- .../2025-09-19-use-use-flow-proper-post-update-nodes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/change-notes/2025-09-19-use-use-flow-proper-post-update-nodes.md b/go/ql/lib/change-notes/2025-09-19-use-use-flow-proper-post-update-nodes.md index e0ffe72002b..607f23dfb03 100644 --- a/go/ql/lib/change-notes/2025-09-19-use-use-flow-proper-post-update-nodes.md +++ b/go/ql/lib/change-notes/2025-09-19-use-use-flow-proper-post-update-nodes.md @@ -1,4 +1,4 @@ --- category: majorAnalysis --- -* Previously, data flow used def-use flow and a node's post-update node was either its definition or the node itself. This caused some problems with false positives caused by steps backwards from a node to its definition. Now, data flow has been changed to use-use flow with proper post-update nodes. This should improve accuracy and reduce false positives in the analysis. The main effect on queries is that sanitization works differently - if you sanitize a node then flow will not reach any uses after the sanitized node. Where this is not desired it maybe be necessary to add an additional flow step to propagate the flow forward. +* The shape of the Go data-flow graph has changed. Previously for code like `x := def(); use1(x); use2(x)`, there would be edges from the definition of `x` to each use. Now there is an edge from the definition to the first use, then another from the first use to the second, and so on. This means that data-flow barriers work differently - flow will not reach any uses after the barrier node. Where this is not desired it may be be necessary to add an additional flow step to propagate the flow forward. Additionally, when a variable may be subject to a side-effect, such as updating an array, passing a pointer to a function that might write through it or writing to a field of a struct, there is now a dedicated post-update node representing the variable after this side-effect has taken place. Previously post-update nodes were aliases for either a variable's definition, or were equal to the pre-update node. This led to backwards steps in the data-flow graph, which could cause false positives. For example, in the previous code there would be an edge from `x` in `use2(x)` back to the definition of `x`. If we define our sources as any argument of `use2` and our sinks as any argument of `use1` then this would lead to a false positive path. Now there are distinct post-update nodes and no backwards edge to the definition, so we will not find this false positive path. From 1144bb99b4d9419ef400218252d0bf817efb4321 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 16:13:31 +0100 Subject: [PATCH 49/70] Convert OpenUrlRedirect tests to InlineExpectations --- .../OpenUrlRedirect/OpenUrlRedirect.go | 2 +- .../OpenUrlRedirect/OpenUrlRedirect.qlref | 4 +- .../CWE-601/OpenUrlRedirect/stdlib.go | 38 +++++++++---------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.go b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.go index 606b5d43ac0..752cf47decc 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.go +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.go @@ -7,6 +7,6 @@ import ( func serve() { http.HandleFunc("/redir", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - http.Redirect(w, r, r.Form.Get("target"), 302) + http.Redirect(w, r, r.Form.Get("target"), 302) // $ Alert }) } diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.qlref b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.qlref index 867dd766561..13add930f51 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.qlref +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.qlref @@ -1,2 +1,4 @@ query: Security/CWE-601/OpenUrlRedirect.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go index f6cd1e5576f..80eb8c970b1 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go @@ -10,18 +10,18 @@ func serveStdlib() { http.HandleFunc("/ex", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - target := r.Form.Get("target") + target := r.Form.Get("target") // $ Source // BAD: a request parameter is incorporated without validation into a URL redirect - w.Header().Set("Location", target) + w.Header().Set("Location", target) // $ Alert w.WriteHeader(302) }) http.HandleFunc("/ex1", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - target := r.Form.Get("target") + target := r.Form.Get("target") // $ Source // Probably OK because the status is set to 500, but we catch it anyway - w.Header().Set("Location", target) + w.Header().Set("Location", target) // $ Alert w.WriteHeader(500) }) @@ -30,13 +30,13 @@ func serveStdlib() { // Taking gratuitous copies of target so that sanitizing the use in // the first request doesn't also sanitize other uses - target := r.Form.Get("target") + target := r.Form.Get("target") // $ Source target2 := target target3 := target // GOOD: local redirects are unproblematic w.Header().Set("Location", "/local"+target) // BAD: this could be a non-local redirect - w.Header().Set("Location", "/"+target2) + w.Header().Set("Location", "/"+target2) // $ Alert // GOOD: localhost redirects are unproblematic w.Header().Set("Location", "//localhost/"+target3) w.WriteHeader(302) @@ -45,9 +45,9 @@ func serveStdlib() { http.HandleFunc("/ex3", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - target := r.Form.Get("target") + target := r.Form.Get("target") // $ Source // BAD: using the utility function - http.Redirect(w, r, target, 301) + http.Redirect(w, r, target, 301) // $ Alert }) http.HandleFunc("/ex4", func(w http.ResponseWriter, r *http.Request) { @@ -65,10 +65,10 @@ func serveStdlib() { http.HandleFunc("/ex5", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - target := r.Form.Get("target") + target := r.Form.Get("target") // $ Source me := "me" // BAD: may be a global redirection - http.Redirect(w, r, target+"?from="+me, 301) + http.Redirect(w, r, target+"?from="+me, 301) // $ Alert }) http.HandleFunc("/ex6", func(w http.ResponseWriter, r *http.Request) { @@ -90,10 +90,10 @@ func serveStdlib() { http.HandleFunc("/ex7", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - target := r.Form.Get("target") + target := r.Form.Get("target") // $ Source target += "/index.html" // BAD - http.Redirect(w, r, target, 302) + http.Redirect(w, r, target, 302) // $ Alert }) http.HandleFunc("/ex7", func(w http.ResponseWriter, r *http.Request) { @@ -147,13 +147,13 @@ func serveStdlib() { http.HandleFunc("/ex9", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - target := r.Form.Get("target") + target := r.Form.Get("target") // $ Source // GOOD, but we catch this anyway: a check is done on the URL if !isValidRedirect(target) { target = "/" } - http.Redirect(w, r, target, 302) + http.Redirect(w, r, target, 302) // $ SPURIOUS: Alert }) http.HandleFunc("/ex8", func(w http.ResponseWriter, r *http.Request) { @@ -183,19 +183,19 @@ func serveStdlib() { http.HandleFunc("/ex9", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - target := r.FormValue("target") + target := r.FormValue("target") // $ Source // BAD: a request parameter is incorporated without validation into a URL redirect - http.Redirect(w, r, target, 301) + http.Redirect(w, r, target, 301) // $ Alert }) http.HandleFunc("/ex10", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - target, _ := url.ParseRequestURI(r.FormValue("target")) + target, _ := url.ParseRequestURI(r.FormValue("target")) // $ Source // BAD: Path could start with `//` - http.Redirect(w, r, target.Path, 301) + http.Redirect(w, r, target.Path, 301) // $ Alert // BAD: EscapedPath() does not help with that - http.Redirect(w, r, target.EscapedPath(), 301) + http.Redirect(w, r, target.EscapedPath(), 301) // $ Alert }) http.HandleFunc("/ex11", func(w http.ResponseWriter, r *http.Request) { From 414bab1f3068ac2d9316d16fb4bfdae6eee09548 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 15:57:14 +0100 Subject: [PATCH 50/70] Add OpenUrlRedirect tests for Url.Host field --- .../OpenUrlRedirect/OpenUrlRedirect.expected | 60 +++++++++++++++++++ .../CWE-601/OpenUrlRedirect/stdlib.go | 16 +++++ 2 files changed, 76 insertions(+) diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index b091d0343d8..7986b0a7e8c 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -10,6 +10,10 @@ | stdlib.go:188:23:188:28 | target | stdlib.go:186:13:186:33 | call to FormValue | stdlib.go:188:23:188:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:186:13:186:33 | call to FormValue | user-provided value | | stdlib.go:196:23:196:33 | selection of Path | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:196:23:196:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | | stdlib.go:198:23:198:42 | call to EscapedPath | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:198:23:198:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | +| stdlib.go:201:23:201:33 | selection of Path | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:201:23:201:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | +| stdlib.go:203:23:203:37 | call to String | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:203:23:203:37 | call to String | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | +| stdlib.go:212:23:212:28 | selection of Path | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:212:23:212:28 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:210:12:210:30 | call to FormValue | user-provided value | +| stdlib.go:214:23:214:32 | call to String | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:214:23:214:32 | call to String | This path to an untrusted URL redirection depends on a $@. | stdlib.go:210:12:210:30 | call to FormValue | user-provided value | edges | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | provenance | Src:MaD:2 Config Sink:MaD:1 | | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:13:13:13:32 | call to Get | provenance | Src:MaD:2 Config | @@ -55,9 +59,41 @@ edges | stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config | | stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 | | stdlib.go:196:23:196:28 | target | stdlib.go:198:23:198:28 | target | provenance | | +| stdlib.go:196:23:196:28 | target | stdlib.go:199:3:199:8 | target | provenance | | | stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config | | stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:198:23:198:28 | target | provenance | | +| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:199:3:199:8 | target | provenance | | | stdlib.go:198:23:198:28 | target | stdlib.go:198:23:198:42 | call to EscapedPath | provenance | Config Sink:MaD:1 | +| stdlib.go:199:3:199:8 | implicit dereference | stdlib.go:199:3:199:8 | target [postupdate] | provenance | Config | +| stdlib.go:199:3:199:8 | target | stdlib.go:199:3:199:8 | implicit dereference | provenance | Config | +| stdlib.go:199:3:199:8 | target | stdlib.go:201:23:201:28 | target | provenance | | +| stdlib.go:199:3:199:8 | target [postupdate] | stdlib.go:199:3:199:8 | implicit dereference | provenance | Config | +| stdlib.go:199:3:199:8 | target [postupdate] | stdlib.go:201:23:201:28 | target | provenance | | +| stdlib.go:201:23:201:28 | implicit dereference | stdlib.go:201:23:201:28 | target [postupdate] | provenance | Config | +| stdlib.go:201:23:201:28 | implicit dereference | stdlib.go:201:23:201:33 | selection of Path | provenance | Config Sink:MaD:1 | +| stdlib.go:201:23:201:28 | target | stdlib.go:201:23:201:28 | implicit dereference | provenance | Config | +| stdlib.go:201:23:201:28 | target | stdlib.go:201:23:201:33 | selection of Path | provenance | Config Sink:MaD:1 | +| stdlib.go:201:23:201:28 | target | stdlib.go:203:23:203:28 | target | provenance | | +| stdlib.go:201:23:201:28 | target [postupdate] | stdlib.go:201:23:201:28 | implicit dereference | provenance | Config | +| stdlib.go:201:23:201:28 | target [postupdate] | stdlib.go:203:23:203:28 | target | provenance | | +| stdlib.go:203:23:203:28 | target | stdlib.go:203:23:203:37 | call to String | provenance | Config Sink:MaD:1 | +| stdlib.go:210:3:210:3 | implicit dereference | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Config | +| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Config | +| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] [pointer] | provenance | | +| stdlib.go:210:3:210:3 | u [postupdate] | stdlib.go:210:3:210:3 | implicit dereference | provenance | Config | +| stdlib.go:210:3:210:3 | u [postupdate] | stdlib.go:212:23:212:23 | u | provenance | | +| stdlib.go:210:3:210:3 | u [postupdate] [pointer] | stdlib.go:212:23:212:23 | u [pointer] | provenance | | +| stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | implicit dereference [postupdate] | provenance | Src:MaD:3 Config | +| stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Src:MaD:3 Config | +| stdlib.go:212:23:212:23 | implicit dereference | stdlib.go:212:23:212:23 | u [postupdate] | provenance | Config | +| stdlib.go:212:23:212:23 | implicit dereference | stdlib.go:212:23:212:28 | selection of Path | provenance | Config Sink:MaD:1 | +| stdlib.go:212:23:212:23 | u | stdlib.go:212:23:212:23 | implicit dereference | provenance | Config | +| stdlib.go:212:23:212:23 | u | stdlib.go:212:23:212:28 | selection of Path | provenance | Config Sink:MaD:1 | +| stdlib.go:212:23:212:23 | u | stdlib.go:214:23:214:23 | u | provenance | | +| stdlib.go:212:23:212:23 | u [pointer] | stdlib.go:212:23:212:23 | implicit dereference | provenance | | +| stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:212:23:212:23 | implicit dereference | provenance | Config | +| stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:214:23:214:23 | u | provenance | | +| stdlib.go:214:23:214:23 | u | stdlib.go:214:23:214:32 | call to String | provenance | Config Sink:MaD:1 | models | 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual | | 2 | Source: net/http; Request; true; Form; ; ; ; remote; manual | @@ -119,4 +155,28 @@ nodes | stdlib.go:196:23:196:33 | selection of Path | semmle.label | selection of Path | | stdlib.go:198:23:198:28 | target | semmle.label | target | | stdlib.go:198:23:198:42 | call to EscapedPath | semmle.label | call to EscapedPath | +| stdlib.go:199:3:199:8 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:199:3:199:8 | target | semmle.label | target | +| stdlib.go:199:3:199:8 | target [postupdate] | semmle.label | target [postupdate] | +| stdlib.go:201:23:201:28 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:201:23:201:28 | target | semmle.label | target | +| stdlib.go:201:23:201:28 | target [postupdate] | semmle.label | target [postupdate] | +| stdlib.go:201:23:201:33 | selection of Path | semmle.label | selection of Path | +| stdlib.go:203:23:203:28 | target | semmle.label | target | +| stdlib.go:203:23:203:37 | call to String | semmle.label | call to String | +| stdlib.go:210:3:210:3 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| stdlib.go:210:3:210:3 | u [postupdate] | semmle.label | u [postupdate] | +| stdlib.go:210:3:210:3 | u [postupdate] [pointer] | semmle.label | u [postupdate] [pointer] | +| stdlib.go:210:12:210:30 | call to FormValue | semmle.label | call to FormValue | +| stdlib.go:212:23:212:23 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:212:23:212:23 | u | semmle.label | u | +| stdlib.go:212:23:212:23 | u [pointer] | semmle.label | u [pointer] | +| stdlib.go:212:23:212:23 | u [postupdate] | semmle.label | u [postupdate] | +| stdlib.go:212:23:212:28 | selection of Path | semmle.label | selection of Path | +| stdlib.go:214:23:214:23 | u | semmle.label | u | +| stdlib.go:214:23:214:32 | call to String | semmle.label | call to String | subpaths +testFailures +| stdlib.go:201:23:201:33 | selection of Path | Fixed missing result: Alert | +| stdlib.go:203:23:203:37 | call to String | Unexpected result: Alert | diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go index 80eb8c970b1..c32661f6688 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go @@ -196,9 +196,25 @@ func serveStdlib() { http.Redirect(w, r, target.Path, 301) // $ Alert // BAD: EscapedPath() does not help with that http.Redirect(w, r, target.EscapedPath(), 301) // $ Alert + target.Host = "example.com" + // BAD: Host field was overwritten but Path field remains untrusted + http.Redirect(w, r, target.Path, 301) // $ MISSING: Alert + // GOOD: untrusted Host field was overwritten + http.Redirect(w, r, target.String(), 301) }) http.HandleFunc("/ex11", func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + + u, _ := url.Parse("http://bing.com/search?q=dotnet") + u.Host = r.FormValue("host") // $ Source + // GOOD: Path field is trusted + http.Redirect(w, r, u.Path, 301) // $ SPURIOUS: Alert + // BAD: Host field is untrusted + http.Redirect(w, r, u.String(), 301) // $ Alert + }) + + http.HandleFunc("/ex12", func(w http.ResponseWriter, r *http.Request) { // GOOD: all these fields and methods are disregarded for OpenRedirect attacks: buf := make([]byte, 100) r.Body.Read(buf) From c9a2816bfe49c5ad4f97e44564d9a23b2a876dba Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 16:13:43 +0100 Subject: [PATCH 51/70] Fix OpenUrlRedirect barrier for write to Url.Host --- .../semmle/go/security/OpenUrlRedirect.qll | 6 ++-- .../OpenUrlRedirect/OpenUrlRedirect.expected | 32 ------------------- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll index e2495055fdc..eb651c3b69f 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll @@ -48,8 +48,10 @@ module OpenUrlRedirect { predicate isBarrierOut(DataFlow::Node node) { // block propagation of this unsafe value when its host is overwritten - exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(node.(DataFlow::PostUpdateNode).getPreUpdateNode(), f, _) + exists(Write w, Field f, DataFlow::Node base | + f.hasQualifiedName("net/url", "URL", "Host") and + w.writesField(base, f, _) and + base.(DataFlow::PostUpdateNode).getPreUpdateNode() = node ) or hostnameSanitizingPrefixEdge(node, _) diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index 7986b0a7e8c..1d302f911cd 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -10,8 +10,6 @@ | stdlib.go:188:23:188:28 | target | stdlib.go:186:13:186:33 | call to FormValue | stdlib.go:188:23:188:28 | target | This path to an untrusted URL redirection depends on a $@. | stdlib.go:186:13:186:33 | call to FormValue | user-provided value | | stdlib.go:196:23:196:33 | selection of Path | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:196:23:196:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | | stdlib.go:198:23:198:42 | call to EscapedPath | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:198:23:198:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | -| stdlib.go:201:23:201:33 | selection of Path | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:201:23:201:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | -| stdlib.go:203:23:203:37 | call to String | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:203:23:203:37 | call to String | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | | stdlib.go:212:23:212:28 | selection of Path | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:212:23:212:28 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:210:12:210:30 | call to FormValue | user-provided value | | stdlib.go:214:23:214:32 | call to String | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:214:23:214:32 | call to String | This path to an untrusted URL redirection depends on a $@. | stdlib.go:210:12:210:30 | call to FormValue | user-provided value | edges @@ -59,28 +57,11 @@ edges | stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config | | stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 | | stdlib.go:196:23:196:28 | target | stdlib.go:198:23:198:28 | target | provenance | | -| stdlib.go:196:23:196:28 | target | stdlib.go:199:3:199:8 | target | provenance | | | stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config | | stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:198:23:198:28 | target | provenance | | -| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:199:3:199:8 | target | provenance | | | stdlib.go:198:23:198:28 | target | stdlib.go:198:23:198:42 | call to EscapedPath | provenance | Config Sink:MaD:1 | -| stdlib.go:199:3:199:8 | implicit dereference | stdlib.go:199:3:199:8 | target [postupdate] | provenance | Config | -| stdlib.go:199:3:199:8 | target | stdlib.go:199:3:199:8 | implicit dereference | provenance | Config | -| stdlib.go:199:3:199:8 | target | stdlib.go:201:23:201:28 | target | provenance | | -| stdlib.go:199:3:199:8 | target [postupdate] | stdlib.go:199:3:199:8 | implicit dereference | provenance | Config | -| stdlib.go:199:3:199:8 | target [postupdate] | stdlib.go:201:23:201:28 | target | provenance | | -| stdlib.go:201:23:201:28 | implicit dereference | stdlib.go:201:23:201:28 | target [postupdate] | provenance | Config | -| stdlib.go:201:23:201:28 | implicit dereference | stdlib.go:201:23:201:33 | selection of Path | provenance | Config Sink:MaD:1 | -| stdlib.go:201:23:201:28 | target | stdlib.go:201:23:201:28 | implicit dereference | provenance | Config | -| stdlib.go:201:23:201:28 | target | stdlib.go:201:23:201:33 | selection of Path | provenance | Config Sink:MaD:1 | -| stdlib.go:201:23:201:28 | target | stdlib.go:203:23:203:28 | target | provenance | | -| stdlib.go:201:23:201:28 | target [postupdate] | stdlib.go:201:23:201:28 | implicit dereference | provenance | Config | -| stdlib.go:201:23:201:28 | target [postupdate] | stdlib.go:203:23:203:28 | target | provenance | | -| stdlib.go:203:23:203:28 | target | stdlib.go:203:23:203:37 | call to String | provenance | Config Sink:MaD:1 | -| stdlib.go:210:3:210:3 | implicit dereference | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Config | | stdlib.go:210:3:210:3 | implicit dereference [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Config | | stdlib.go:210:3:210:3 | implicit dereference [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] [pointer] | provenance | | -| stdlib.go:210:3:210:3 | u [postupdate] | stdlib.go:210:3:210:3 | implicit dereference | provenance | Config | | stdlib.go:210:3:210:3 | u [postupdate] | stdlib.go:212:23:212:23 | u | provenance | | | stdlib.go:210:3:210:3 | u [postupdate] [pointer] | stdlib.go:212:23:212:23 | u [pointer] | provenance | | | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | implicit dereference [postupdate] | provenance | Src:MaD:3 Config | @@ -155,16 +136,6 @@ nodes | stdlib.go:196:23:196:33 | selection of Path | semmle.label | selection of Path | | stdlib.go:198:23:198:28 | target | semmle.label | target | | stdlib.go:198:23:198:42 | call to EscapedPath | semmle.label | call to EscapedPath | -| stdlib.go:199:3:199:8 | implicit dereference | semmle.label | implicit dereference | -| stdlib.go:199:3:199:8 | target | semmle.label | target | -| stdlib.go:199:3:199:8 | target [postupdate] | semmle.label | target [postupdate] | -| stdlib.go:201:23:201:28 | implicit dereference | semmle.label | implicit dereference | -| stdlib.go:201:23:201:28 | target | semmle.label | target | -| stdlib.go:201:23:201:28 | target [postupdate] | semmle.label | target [postupdate] | -| stdlib.go:201:23:201:33 | selection of Path | semmle.label | selection of Path | -| stdlib.go:203:23:203:28 | target | semmle.label | target | -| stdlib.go:203:23:203:37 | call to String | semmle.label | call to String | -| stdlib.go:210:3:210:3 | implicit dereference | semmle.label | implicit dereference | | stdlib.go:210:3:210:3 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | | stdlib.go:210:3:210:3 | u [postupdate] | semmle.label | u [postupdate] | | stdlib.go:210:3:210:3 | u [postupdate] [pointer] | semmle.label | u [postupdate] [pointer] | @@ -177,6 +148,3 @@ nodes | stdlib.go:214:23:214:23 | u | semmle.label | u | | stdlib.go:214:23:214:32 | call to String | semmle.label | call to String | subpaths -testFailures -| stdlib.go:201:23:201:33 | selection of Path | Fixed missing result: Alert | -| stdlib.go:203:23:203:37 | call to String | Unexpected result: Alert | From 489b8431eaddb900b5316868054d04ae48fc2437 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 16:59:32 +0100 Subject: [PATCH 52/70] Add and use `WriteNode.writesFieldPreUpdate` --- .../go/controlflow/ControlFlowGraph.qll | 25 ++++++++++---- .../go/dataflow/internal/FlowSummaryImpl.qll | 13 ++------ go/ql/lib/semmle/go/frameworks/GinCors.qll | 33 +++++-------------- go/ql/lib/semmle/go/frameworks/RsCors.qll | 33 +++++-------------- go/ql/src/RedundantCode/DeadStoreOfField.ql | 5 ++- go/ql/src/Security/CWE-327/InsecureTLS.ql | 12 ++----- .../src/experimental/CWE-1004/AuthCookie.qll | 9 ++--- 7 files changed, 45 insertions(+), 85 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index 7d38fbe934d..e66feeadaac 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -134,17 +134,17 @@ module ControlFlow { /** * Holds if this node sets the value of field `f` on `base` (or its implicit dereference) to - * `rhs`. + * `rhs`, where `base` represents the post-update value. * * For example, for the assignment `x.width = newWidth`, `base` is the post-update node of * either the data-flow node corresponding to `x` or (if `x` is a pointer) the data-flow node * corresponding to the implicit dereference `*x`, `f` is the field referenced by `width`, and * `rhs` is the data-flow node corresponding to `newWidth`. If this `WriteNode` is a struct - * initialization then there is no need for a post-update node and `base` is the struct literal - * being initialized. + * initialization then there is no post-update node and `base` is the struct literal being + * initialized. */ predicate writesField(DataFlow::Node base, Field f, DataFlow::Node rhs) { - exists(DataFlow::Node b | this.writesFieldInsn(b.asInstruction(), f, rhs.asInstruction()) | + exists(DataFlow::Node b | this.writesFieldPreUpdate(b, f, rhs) | this.isInitialization() and base = b or not this.isInitialization() and @@ -152,13 +152,24 @@ module ControlFlow { ) } + /** + * Holds if this node sets the value of field `f` on `base` (or its implicit dereference) to + * `rhs`, where `base` represents the pre-update value. + * + * For example, for the assignment `x.width = newWidth`, `base` is either the data-flow node + * corresponding to `x` or (if `x` is a pointer) the data-flow node corresponding to the + * implicit dereference `*x`, `f` is the field referenced by `width`, and `rhs` is the + * data-flow node corresponding to `newWidth`. + */ + predicate writesFieldPreUpdate(DataFlow::Node base, Field f, DataFlow::Node rhs) { + this.writesFieldInsn(base.asInstruction(), f, rhs.asInstruction()) + } + /** * Holds if this node sets the value of field `f` on `v` to `rhs`. */ predicate writesFieldOnSsaWithFields(SsaWithFields v, Field f, DataFlow::Node rhs) { - exists(IR::Instruction insn | this.writesFieldInsn(insn, f, rhs.asInstruction()) | - v.getAUse().asInstruction() = insn - ) + this.writesFieldPreUpdate(v.getAUse(), f, rhs) } private predicate writesFieldInsn(IR::Instruction base, Field f, IR::Instruction rhs) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index a7dfbab15c2..f12c9e6eeb1 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -437,20 +437,13 @@ module SourceSinkInterpretationInput implements mid.asCallable() = getNodeEnclosingCallable(ret) ) or - exists( - SourceOrSinkElement e, DataFlow::Write fw, DataFlow::Node base, DataFlow::Node qual, Field f - | + exists(SourceOrSinkElement e, DataFlow::Write fw, DataFlow::Node base, Field f | e = mid.asElement() and f = e.asFieldEntity() | c = "" and - fw.writesField(base, f, node.asNode()) and - pragma[only_bind_into](e) = getElementWithQualifier(f, qual) and - ( - qual = base.(PostUpdateNode).getPreUpdateNode() - or - not base instanceof PostUpdateNode and qual = base - ) + fw.writesFieldPreUpdate(base, f, node.asNode()) and + pragma[only_bind_into](e) = getElementWithQualifier(f, base) ) or // A package-scope (or universe-scope) variable diff --git a/go/ql/lib/semmle/go/frameworks/GinCors.qll b/go/ql/lib/semmle/go/frameworks/GinCors.qll index a26ab2eaa12..cc993ea4dee 100644 --- a/go/ql/lib/semmle/go/frameworks/GinCors.qll +++ b/go/ql/lib/semmle/go/frameworks/GinCors.qll @@ -25,15 +25,10 @@ module GinCors { DataFlow::Node base; AllowCredentialsWrite() { - exists(Field f, Write w, DataFlow::Node n | + exists(Field f, Write w | f.hasQualifiedName(packagePath(), "Config", "AllowCredentials") and - w.writesField(n, f, this) and - this.getType() instanceof BoolType and - ( - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) + w.writesFieldPreUpdate(base, f, this) and + this.getType() instanceof BoolType ) } @@ -64,15 +59,10 @@ module GinCors { DataFlow::Node base; AllowOriginsWrite() { - exists(Field f, Write w, DataFlow::Node n | + exists(Field f, Write w | f.hasQualifiedName(packagePath(), "Config", "AllowOrigins") and - w.writesField(n, f, this) and - this.asExpr() instanceof SliceLit and - ( - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) + w.writesFieldPreUpdate(base, f, this) and + this.asExpr() instanceof SliceLit ) } @@ -103,15 +93,10 @@ module GinCors { DataFlow::Node base; AllowAllOriginsWrite() { - exists(Field f, Write w, DataFlow::Node n | + exists(Field f, Write w | f.hasQualifiedName(packagePath(), "Config", "AllowAllOrigins") and - w.writesField(n, f, this) and - this.getType() instanceof BoolType and - ( - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) + w.writesFieldPreUpdate(base, f, this) and + this.getType() instanceof BoolType ) } diff --git a/go/ql/lib/semmle/go/frameworks/RsCors.qll b/go/ql/lib/semmle/go/frameworks/RsCors.qll index aa49df3c432..52b4a7fe6d0 100644 --- a/go/ql/lib/semmle/go/frameworks/RsCors.qll +++ b/go/ql/lib/semmle/go/frameworks/RsCors.qll @@ -52,15 +52,10 @@ module RsCors { DataFlow::Node base; AllowCredentialsWrite() { - exists(Field f, Write w, DataFlow::Node n | + exists(Field f, Write w | f.hasQualifiedName(packagePath(), "Options", "AllowCredentials") and - w.writesField(n, f, this) and - this.getType() instanceof BoolType and - ( - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) + w.writesFieldPreUpdate(base, f, this) and + this.getType() instanceof BoolType ) } @@ -85,15 +80,10 @@ module RsCors { DataFlow::Node base; AllowOriginsWrite() { - exists(Field f, Write w, DataFlow::Node n | + exists(Field f, Write w | f.hasQualifiedName(packagePath(), "Options", "AllowedOrigins") and - w.writesField(n, f, this) and - this.asExpr() instanceof SliceLit and - ( - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) + w.writesFieldPreUpdate(base, f, this) and + this.asExpr() instanceof SliceLit ) } @@ -121,15 +111,10 @@ module RsCors { DataFlow::Node base; AllowAllOriginsWrite() { - exists(Field f, Write w, DataFlow::Node n | + exists(Field f, Write w | f.hasQualifiedName(packagePath(), "Options", "AllowAllOrigins") and - w.writesField(n, f, this) and - this.getType() instanceof BoolType and - ( - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) + w.writesFieldPreUpdate(base, f, this) and + this.getType() instanceof BoolType ) } diff --git a/go/ql/src/RedundantCode/DeadStoreOfField.ql b/go/ql/src/RedundantCode/DeadStoreOfField.ql index 3f757cd8b54..4a971343823 100644 --- a/go/ql/src/RedundantCode/DeadStoreOfField.ql +++ b/go/ql/src/RedundantCode/DeadStoreOfField.ql @@ -86,11 +86,10 @@ Type getTypeEmbeddedViaPointer(Type t) { result = getEmbeddedType*(getEmbeddedType(getEmbeddedType*(t), true)) } -from Write w, DataFlow::Node base, LocalVariable v, Field f +from Write w, LocalVariable v, Field f where // `w` writes `f` on `v` - w.writesField(base, f, _) and - [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = v.getARead() and + w.writesFieldPreUpdate(v.getARead(), f, _) and // but `f` is never read on `v` not exists(Read r | r.readsField(v.getARead(), f)) and // exclude pointer-typed `v`; there may be reads through an alias diff --git a/go/ql/src/Security/CWE-327/InsecureTLS.ql b/go/ql/src/Security/CWE-327/InsecureTLS.ql index 66e516a85eb..b5d8a81f3d8 100644 --- a/go/ql/src/Security/CWE-327/InsecureTLS.ql +++ b/go/ql/src/Security/CWE-327/InsecureTLS.ql @@ -65,11 +65,7 @@ module TlsVersionFlowConfig implements DataFlow::ConfigSig { */ additional predicate isSink(DataFlow::Node sink, Field fld, DataFlow::Node base, Write fieldWrite) { fld.hasQualifiedName("crypto/tls", "Config", ["MinVersion", "MaxVersion"]) and - exists(DataFlow::Node n | fieldWrite.writesField(n, fld, sink) | - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) + fieldWrite.writesFieldPreUpdate(base, fld, sink) } predicate isSource(DataFlow::Node source) { intIsSource(source, _) } @@ -194,11 +190,7 @@ module TlsInsecureCipherSuitesFlowConfig implements DataFlow::ConfigSig { */ additional predicate isSink(DataFlow::Node sink, Field fld, DataFlow::Node base, Write fieldWrite) { fld.hasQualifiedName("crypto/tls", "Config", "CipherSuites") and - exists(DataFlow::Node n | fieldWrite.writesField(n, fld, sink) | - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) + fieldWrite.writesFieldPreUpdate(base, fld, sink) } predicate isSink(DataFlow::Node sink) { isSink(sink, _, _, _) } diff --git a/go/ql/src/experimental/CWE-1004/AuthCookie.qll b/go/ql/src/experimental/CWE-1004/AuthCookie.qll index 2cf8577ac5a..58c9f8642b3 100644 --- a/go/ql/src/experimental/CWE-1004/AuthCookie.qll +++ b/go/ql/src/experimental/CWE-1004/AuthCookie.qll @@ -26,14 +26,9 @@ private class GorillaSessionOptionsField extends Field { * This should cover most typical patterns... */ private DataFlow::Node getValueForFieldWrite(StructLit sl, string field) { - exists(Write w, DataFlow::Node base, DataFlow::Node n, Field f | + exists(Write w, DataFlow::Node base, Field f | f.getName() = field and - w.writesField(n, f, result) and - ( - base = n.(DataFlow::PostUpdateNode).getPreUpdateNode() - or - not n instanceof DataFlow::PostUpdateNode and base = n - ) and + w.writesFieldPreUpdate(base, f, result) and ( sl = base.asExpr() or From 2ffb638b7e6bb00ac322d4d31a4b80558489dd53 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 25 Sep 2025 17:09:08 +0100 Subject: [PATCH 53/70] Delete `WriteNode.writesFieldOnSsaWithFields` This can be easily expressed in terms of `WriteNode.writesFieldPreUpdate`. --- go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll | 7 ------- .../semmle/go/security/OpenUrlRedirectCustomizations.qll | 2 +- go/ql/lib/semmle/go/security/RequestForgery.qll | 2 +- go/ql/lib/semmle/go/security/SafeUrlFlow.qll | 2 +- go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql | 4 ++-- go/ql/src/experimental/CWE-918/SSRF.qll | 2 +- 6 files changed, 6 insertions(+), 13 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index e66feeadaac..9cf9633daa2 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -165,13 +165,6 @@ module ControlFlow { this.writesFieldInsn(base.asInstruction(), f, rhs.asInstruction()) } - /** - * Holds if this node sets the value of field `f` on `v` to `rhs`. - */ - predicate writesFieldOnSsaWithFields(SsaWithFields v, Field f, DataFlow::Node rhs) { - this.writesFieldPreUpdate(v.getAUse(), f, rhs) - } - private predicate writesFieldInsn(IR::Instruction base, Field f, IR::Instruction rhs) { exists(IR::FieldTarget trg | trg = super.getLhs() | ( diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index 6121d716abf..da5110a2ef5 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -92,7 +92,7 @@ module OpenUrlRedirect { PathAssignmentBarrier() { exists(Write w, SsaWithFields var | hasHostnameSanitizingSubstring(w.getRhs()) and - w.writesFieldOnSsaWithFields(var, any(Field f | f.getName() = "Path"), _) and + w.writesFieldPreUpdate(var.getAUse(), any(Field f | f.getName() = "Path"), _) and useIsDominated(var, w, this) ) } diff --git a/go/ql/lib/semmle/go/security/RequestForgery.qll b/go/ql/lib/semmle/go/security/RequestForgery.qll index 9497f528004..0cd86b12abb 100644 --- a/go/ql/lib/semmle/go/security/RequestForgery.qll +++ b/go/ql/lib/semmle/go/security/RequestForgery.qll @@ -28,7 +28,7 @@ module RequestForgery { predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { // propagate to a URL when its host is assigned to exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesFieldOnSsaWithFields(v, f, pred) and + w.writesFieldPreUpdate(v.getAUse(), f, pred) and succ = v.getAUse() ) } diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll index a1f5ad7051b..d88c2c852ae 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll @@ -24,7 +24,7 @@ module SafeUrlFlow { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // propagate to a URL when its host is assigned to exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesFieldOnSsaWithFields(v, f, node1) and + w.writesFieldPreUpdate(v.getAUse(), f, node1) and node2 = v.getAUse() ) } diff --git a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql index f7c35b78d87..87c5a2184b0 100644 --- a/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql +++ b/go/ql/src/Security/CWE-322/InsecureHostKeyCallback.ql @@ -98,8 +98,8 @@ predicate hostCheckReachesSink(Flow::PathNode sink) { Flow::flowPath(source, otherSink) and Config::writeIsSink(sink.getNode(), sinkWrite) and Config::writeIsSink(otherSink.getNode(), otherSinkWrite) and - sinkWrite.writesFieldOnSsaWithFields(sinkAccessPath, _, sink.getNode()) and - otherSinkWrite.writesFieldOnSsaWithFields(otherSinkAccessPath, _, otherSink.getNode()) and + sinkWrite.writesFieldPreUpdate(sinkAccessPath.getAUse(), _, sink.getNode()) and + otherSinkWrite.writesFieldPreUpdate(otherSinkAccessPath.getAUse(), _, otherSink.getNode()) and otherSinkAccessPath = sinkAccessPath.similar() ) ) diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index 0879534d666..ae041415dfe 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -23,7 +23,7 @@ module ServerSideRequestForgery { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // propagate to a URL when its host is assigned to exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesFieldOnSsaWithFields(v, f, node1) and + w.writesFieldPreUpdate(v.getAUse(), f, node1) and node2 = v.getAUse() ) } From 6fcd35885e21bb58afebe218e85df1fdc104a98f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 26 Sep 2025 15:27:58 +0100 Subject: [PATCH 54/70] Fix pointer content store step for write to field of pointer dereference --- go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 3f2efd3b492..94609d1c111 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -164,15 +164,17 @@ predicate jumpStep(Node n1, Node n2) { */ predicate storeStep(Node node1, ContentSet cs, Node node2) { exists(Content c | cs.asOneContent() = c | - // a write `(*p).f = rhs` is modeled as two store steps: `rhs` is flows into field `f` of `(*p)`, - // which in turn flows into the pointer content of `p` + // a write `(*p).f = rhs` is modeled as two store steps: `rhs` is flows into field `f` of the + // post-update node of `(*p)`, which in turn flows into the pointer content of the post-update + // node of `p` exists(Write w, Field f, DataFlow::Node base, DataFlow::Node rhs | w.writesField(base, f, rhs) | node1 = rhs and node2 = base and c = any(DataFlow::FieldContent fc | fc.getField() = f) or node1 = base and - node2.(PostUpdateNode).getPreUpdateNode() = node1.(PointerDereferenceNode).getOperand() and + node2.(PostUpdateNode).getPreUpdateNode() = + node1.(PostUpdateNode).getPreUpdateNode().(PointerDereferenceNode).getOperand() and c = any(DataFlow::PointerContent pc | pc.getPointerType() = node2.getType()) ) or From 59e3c14a5e3f5ebc005c4bc21fbd4c54e0108211 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Mon, 29 Sep 2025 17:20:11 +0100 Subject: [PATCH 55/70] Add and use `WriteNode.writesElementPreUpdate` --- .../go/controlflow/ControlFlowGraph.qll | 19 ++++++++++++++++--- .../semmle/go/frameworks/stdlib/NetHttp.qll | 8 +------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index 9cf9633daa2..df9a025915e 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -188,9 +188,7 @@ module ControlFlow { * initialized. */ predicate writesElement(DataFlow::Node base, DataFlow::Node index, DataFlow::Node rhs) { - exists(DataFlow::Node b | - this.writesElementInsn(b.asInstruction(), index.asInstruction(), rhs.asInstruction()) - | + exists(DataFlow::Node b | this.writesElementPreUpdate(b, index, rhs) | this.isInitialization() and base = b or not this.isInitialization() and @@ -198,6 +196,21 @@ module ControlFlow { ) } + /** + * Holds if this node sets the value of element `index` on `base` (or its implicit dereference) + * to `rhs`. + * + * For example, for the assignment `xs[i] = v`, `base` is the post-update node of the data-flow + * node corresponding to `xs` or (if `xs` is a pointer) the implicit dereference `*xs`, `index` + * is the data-flow node corresponding to `i`, and `rhs` is the data-flow node corresponding to + * `base`. If this `WriteNode` corresponds to the initialization of an array/slice/map then + * there is no need for a post-update node and `base` is the array/slice/map literal being + * initialized. + */ + predicate writesElementPreUpdate(DataFlow::Node base, DataFlow::Node index, DataFlow::Node rhs) { + this.writesElementInsn(base.asInstruction(), index.asInstruction(), rhs.asInstruction()) + } + private predicate writesElementInsn( IR::Instruction base, IR::Instruction index, IR::Instruction rhs ) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll index 0ba122006e6..88c9605502f 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll @@ -52,13 +52,7 @@ module NetHttp { MapWrite() { this.getType().hasQualifiedName("net/http", "Header") and - exists(Write write, DataFlow::Node base | - write.writesElement(base, index, rhs) and - // The following line works because `Http::HeaderWrite::Range` extends - // `DataFlow::ExprNode`, which is incompatible with - // `DataFlow::PostUpdateNode`. - this = [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] - ) + any(Write write).writesElementPreUpdate(this, index, rhs) } override DataFlow::Node getName() { result = index } From 8a21a4ff924b55dc3b132a39e095d8cd52a6d747 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Mon, 29 Sep 2025 17:22:01 +0100 Subject: [PATCH 56/70] Deprecate `WriteNode.writesComponent` --- go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll | 4 +++- go/ql/lib/semmle/go/frameworks/Protobuf.qll | 9 +++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index df9a025915e..d527a650b9d 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -225,9 +225,11 @@ module ControlFlow { } /** + * DEPRECATED: Use the disjunct of `writesElement` and `writesField` instead. + * * Holds if this node sets any field or element of `base` to `rhs`. */ - predicate writesComponent(DataFlow::Node base, DataFlow::Node rhs) { + deprecated predicate writesComponent(DataFlow::Node base, DataFlow::Node rhs) { this.writesElement(base, _, rhs) or this.writesField(base, _, rhs) } diff --git a/go/ql/lib/semmle/go/frameworks/Protobuf.qll b/go/ql/lib/semmle/go/frameworks/Protobuf.qll index 4103815e7d2..62443eb46af 100644 --- a/go/ql/lib/semmle/go/frameworks/Protobuf.qll +++ b/go/ql/lib/semmle/go/frameworks/Protobuf.qll @@ -141,13 +141,10 @@ module Protobuf { private class WriteMessageFieldStep extends TaintTracking::AdditionalTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { [succ.getType(), succ.getType().getPointerType()] instanceof MessageType and - exists(DataFlow::Node n, DataFlow::ReadNode base | - succ.(DataFlow::PostUpdateNode).getPreUpdateNode() = getUnderlyingNode(base) + exists(DataFlow::Write w, DataFlow::ReadNode base | + w.writesElementPreUpdate(base, _, pred) or w.writesFieldPreUpdate(base, _, pred) | - any(DataFlow::Write w).writesComponent(n, pred) and - // The below line only works because `base`'s type, `DataFlow::ReadNode`, - // is incompatible with `DataFlow::PostUpdateNode`. - base = [n, n.(DataFlow::PostUpdateNode).getPreUpdateNode()] + succ.(DataFlow::PostUpdateNode).getPreUpdateNode() = getUnderlyingNode(base) ) } } From 620ae33e0c53bdee1cbeda7131e0c8dc6ffcfa75 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 30 Sep 2025 16:33:56 +0100 Subject: [PATCH 57/70] Make SafeUrlFlow test more comprehensive (failing) --- .../security/SafeUrlFlow/SafeUrlFlow.expected | 51 +++++++++++-------- .../go/security/SafeUrlFlow/SafeUrlFlow.go | 8 +-- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected b/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected index 79e0c9145fe..7182e118ff1 100644 --- a/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected +++ b/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected @@ -16,17 +16,19 @@ | SafeUrlFlow.go:70:39:70:54 | call to String | SafeUrlFlow.go:54:13:54:19 | selection of URL | SafeUrlFlow.go:70:39:70:54 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:54:13:54:19 | selection of URL | here | | SafeUrlFlow.go:74:70:74:85 | call to String | SafeUrlFlow.go:54:13:54:19 | selection of URL | SafeUrlFlow.go:74:70:74:85 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:54:13:54:19 | selection of URL | here | | SafeUrlFlow.go:78:40:78:55 | call to String | SafeUrlFlow.go:54:13:54:19 | selection of URL | SafeUrlFlow.go:78:40:78:55 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:54:13:54:19 | selection of URL | here | -| SafeUrlFlow.go:89:24:89:41 | call to String | SafeUrlFlow.go:84:14:84:21 | selection of Host | SafeUrlFlow.go:89:24:89:41 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:84:14:84:21 | selection of Host | here | -| SafeUrlFlow.go:109:11:109:23 | reconstructed | SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:109:11:109:23 | reconstructed | A safe URL flows here from $@. | SafeUrlFlow.go:100:13:100:19 | selection of URL | here | -| SafeUrlFlow.go:112:24:112:50 | ...+... | SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:112:24:112:50 | ...+... | A safe URL flows here from $@. | SafeUrlFlow.go:100:13:100:19 | selection of URL | here | -| SafeUrlFlow.go:113:29:113:58 | ...+... | SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:113:29:113:58 | ...+... | A safe URL flows here from $@. | SafeUrlFlow.go:100:13:100:19 | selection of URL | here | -| SafeUrlFlow.go:114:12:114:42 | ...+... | SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:114:12:114:42 | ...+... | A safe URL flows here from $@. | SafeUrlFlow.go:100:13:100:19 | selection of URL | here | -| SafeUrlFlow.go:115:12:115:25 | safeOpaquePart | SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:115:12:115:25 | safeOpaquePart | A safe URL flows here from $@. | SafeUrlFlow.go:100:13:100:19 | selection of URL | here | +| SafeUrlFlow.go:92:11:92:28 | call to String | SafeUrlFlow.go:84:14:84:21 | selection of Host | SafeUrlFlow.go:92:11:92:28 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:84:14:84:21 | selection of Host | here | +| SafeUrlFlow.go:105:11:105:23 | reconstructed | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:105:11:105:23 | reconstructed | A safe URL flows here from $@. | SafeUrlFlow.go:96:13:96:19 | selection of URL | here | +| SafeUrlFlow.go:108:24:108:50 | ...+... | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:108:24:108:50 | ...+... | A safe URL flows here from $@. | SafeUrlFlow.go:96:13:96:19 | selection of URL | here | +| SafeUrlFlow.go:109:29:109:58 | ...+... | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:109:29:109:58 | ...+... | A safe URL flows here from $@. | SafeUrlFlow.go:96:13:96:19 | selection of URL | here | +| SafeUrlFlow.go:110:12:110:42 | ...+... | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:110:12:110:42 | ...+... | A safe URL flows here from $@. | SafeUrlFlow.go:96:13:96:19 | selection of URL | here | +| SafeUrlFlow.go:111:12:111:25 | safeOpaquePart | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:111:12:111:25 | safeOpaquePart | A safe URL flows here from $@. | SafeUrlFlow.go:96:13:96:19 | selection of URL | here | edges | SafeUrlFlow.go:10:14:10:21 | selection of Host | SafeUrlFlow.go:11:24:11:50 | ...+... | provenance | Sink:MaD:1 | | SafeUrlFlow.go:10:14:10:21 | selection of Host | SafeUrlFlow.go:17:19:17:26 | safeHost | provenance | | | SafeUrlFlow.go:13:13:13:19 | selection of URL | SafeUrlFlow.go:14:29:14:35 | safeURL | provenance | Src:MaD:2 | | SafeUrlFlow.go:14:29:14:35 | safeURL | SafeUrlFlow.go:14:29:14:44 | call to String | provenance | MaD:3 | +| SafeUrlFlow.go:17:2:17:10 | targetURL | SafeUrlFlow.go:18:11:18:19 | targetURL | provenance | | +| SafeUrlFlow.go:17:19:17:26 | safeHost | SafeUrlFlow.go:17:2:17:10 | targetURL | provenance | Config | | SafeUrlFlow.go:17:19:17:26 | safeHost | SafeUrlFlow.go:18:11:18:19 | targetURL | provenance | Config | | SafeUrlFlow.go:18:11:18:19 | targetURL | SafeUrlFlow.go:18:11:18:28 | call to String | provenance | MaD:3 | | SafeUrlFlow.go:37:13:37:19 | selection of URL | SafeUrlFlow.go:45:24:45:61 | ...+... | provenance | Src:MaD:2 Sink:MaD:1 | @@ -55,13 +57,15 @@ edges | SafeUrlFlow.go:74:70:74:76 | safeURL | SafeUrlFlow.go:74:70:74:85 | call to String | provenance | MaD:3 | | SafeUrlFlow.go:78:40:78:46 | safeURL | SafeUrlFlow.go:78:40:78:55 | call to String | provenance | MaD:3 | | SafeUrlFlow.go:84:14:84:21 | selection of Host | SafeUrlFlow.go:87:19:87:26 | safeHost | provenance | | -| SafeUrlFlow.go:87:19:87:26 | safeHost | SafeUrlFlow.go:89:24:89:32 | targetURL | provenance | Config | -| SafeUrlFlow.go:89:24:89:32 | targetURL | SafeUrlFlow.go:89:24:89:41 | call to String | provenance | MaD:3 Sink:MaD:1 | -| SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:109:11:109:23 | reconstructed | provenance | Src:MaD:2 | -| SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:112:24:112:50 | ...+... | provenance | Src:MaD:2 Sink:MaD:1 | -| SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:113:29:113:58 | ...+... | provenance | Src:MaD:2 | -| SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:114:12:114:42 | ...+... | provenance | Src:MaD:2 | -| SafeUrlFlow.go:100:13:100:19 | selection of URL | SafeUrlFlow.go:115:12:115:25 | safeOpaquePart | provenance | Src:MaD:2 | +| SafeUrlFlow.go:87:19:87:26 | safeHost | SafeUrlFlow.go:91:2:91:10 | targetURL | provenance | Config | +| SafeUrlFlow.go:87:19:87:26 | safeHost | SafeUrlFlow.go:92:11:92:19 | targetURL | provenance | Config | +| SafeUrlFlow.go:91:2:91:10 | targetURL | SafeUrlFlow.go:92:11:92:19 | targetURL | provenance | | +| SafeUrlFlow.go:92:11:92:19 | targetURL | SafeUrlFlow.go:92:11:92:28 | call to String | provenance | MaD:3 | +| SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:105:11:105:23 | reconstructed | provenance | Src:MaD:2 | +| SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:108:24:108:50 | ...+... | provenance | Src:MaD:2 Sink:MaD:1 | +| SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:109:29:109:58 | ...+... | provenance | Src:MaD:2 | +| SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:110:12:110:42 | ...+... | provenance | Src:MaD:2 | +| SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:111:12:111:25 | safeOpaquePart | provenance | Src:MaD:2 | models | 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual | | 2 | Source: net/http; Request; true; URL; ; ; ; remote; manual | @@ -72,6 +76,7 @@ nodes | SafeUrlFlow.go:13:13:13:19 | selection of URL | semmle.label | selection of URL | | SafeUrlFlow.go:14:29:14:35 | safeURL | semmle.label | safeURL | | SafeUrlFlow.go:14:29:14:44 | call to String | semmle.label | call to String | +| SafeUrlFlow.go:17:2:17:10 | targetURL | semmle.label | targetURL | | SafeUrlFlow.go:17:19:17:26 | safeHost | semmle.label | safeHost | | SafeUrlFlow.go:18:11:18:19 | targetURL | semmle.label | targetURL | | SafeUrlFlow.go:18:11:18:28 | call to String | semmle.label | call to String | @@ -104,12 +109,16 @@ nodes | SafeUrlFlow.go:78:40:78:55 | call to String | semmle.label | call to String | | SafeUrlFlow.go:84:14:84:21 | selection of Host | semmle.label | selection of Host | | SafeUrlFlow.go:87:19:87:26 | safeHost | semmle.label | safeHost | -| SafeUrlFlow.go:89:24:89:32 | targetURL | semmle.label | targetURL | -| SafeUrlFlow.go:89:24:89:41 | call to String | semmle.label | call to String | -| SafeUrlFlow.go:100:13:100:19 | selection of URL | semmle.label | selection of URL | -| SafeUrlFlow.go:109:11:109:23 | reconstructed | semmle.label | reconstructed | -| SafeUrlFlow.go:112:24:112:50 | ...+... | semmle.label | ...+... | -| SafeUrlFlow.go:113:29:113:58 | ...+... | semmle.label | ...+... | -| SafeUrlFlow.go:114:12:114:42 | ...+... | semmle.label | ...+... | -| SafeUrlFlow.go:115:12:115:25 | safeOpaquePart | semmle.label | safeOpaquePart | +| SafeUrlFlow.go:91:2:91:10 | targetURL | semmle.label | targetURL | +| SafeUrlFlow.go:92:11:92:19 | targetURL | semmle.label | targetURL | +| SafeUrlFlow.go:92:11:92:28 | call to String | semmle.label | call to String | +| SafeUrlFlow.go:96:13:96:19 | selection of URL | semmle.label | selection of URL | +| SafeUrlFlow.go:105:11:105:23 | reconstructed | semmle.label | reconstructed | +| SafeUrlFlow.go:108:24:108:50 | ...+... | semmle.label | ...+... | +| SafeUrlFlow.go:109:29:109:58 | ...+... | semmle.label | ...+... | +| SafeUrlFlow.go:110:12:110:42 | ...+... | semmle.label | ...+... | +| SafeUrlFlow.go:111:12:111:25 | safeOpaquePart | semmle.label | safeOpaquePart | subpaths +testFailures +| SafeUrlFlow.go:89:62:89:71 | comment | Missing result: Alert | +| SafeUrlFlow.go:92:11:92:28 | call to String | Unexpected result: Alert | diff --git a/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.go b/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.go index 9a1b2e5677e..4718b973844 100644 --- a/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.go +++ b/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.go @@ -87,13 +87,9 @@ func testHostFieldAssignmentFlow(w http.ResponseWriter, req *http.Request) { targetURL.Host = safeHost // URL is safe if Host is safe http.Redirect(w, req, targetURL.String(), http.StatusFound) // $ Alert -} -func testHostFieldOverwritten(w http.ResponseWriter, req *http.Request) { - safeURL := req.URL - - safeURL.Host = "something.else.com" // safeURL is not guaranteed to be safe now that Host is overwritten - http.Get(safeURL.String()) // not guaranteed to be safe + targetURL.Host = "something.else.com" // targetURL is not guaranteed to be safe now that Host is overwritten + http.Get(targetURL.String()) } func testFieldAccess(w http.ResponseWriter, req *http.Request) { From 6e4dbe8e223336c4a24685225d7db745b457354e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 30 Sep 2025 21:07:12 +0100 Subject: [PATCH 58/70] Fix SafeUrlFlow so test passes --- go/ql/lib/semmle/go/security/SafeUrlFlow.qll | 17 ++++++----- .../security/SafeUrlFlow/SafeUrlFlow.expected | 28 +++++++++---------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll index d88c2c852ae..7144614c305 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll @@ -22,18 +22,21 @@ module SafeUrlFlow { predicate isSink(DataFlow::Node sink) { sink instanceof Sink } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesFieldPreUpdate(v.getAUse(), f, node1) and - node2 = v.getAUse() + // propagate taint to the post-update node of a URL when its host is + // assigned to + exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | + w.writesField(node2, f, node1) ) } predicate isBarrierOut(DataFlow::Node node) { // block propagation of this safe value when its host is overwritten - exists(Write w, DataFlow::Node base, Field f | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(base, f, _) and - [base, base.(DataFlow::PostUpdateNode).getPreUpdateNode()] = node.getASuccessor() + exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | + // We sanitize the pre-update node to block flow from previous value. + // This fits in with the additional flow step above propagating taint + // from the value written to the Host field to the post-update node of + // the URL. + w.writesFieldPreUpdate(node, f, _) ) or node instanceof SanitizerEdge diff --git a/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected b/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected index 7182e118ff1..c2f82841d83 100644 --- a/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected +++ b/go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected @@ -16,7 +16,7 @@ | SafeUrlFlow.go:70:39:70:54 | call to String | SafeUrlFlow.go:54:13:54:19 | selection of URL | SafeUrlFlow.go:70:39:70:54 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:54:13:54:19 | selection of URL | here | | SafeUrlFlow.go:74:70:74:85 | call to String | SafeUrlFlow.go:54:13:54:19 | selection of URL | SafeUrlFlow.go:74:70:74:85 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:54:13:54:19 | selection of URL | here | | SafeUrlFlow.go:78:40:78:55 | call to String | SafeUrlFlow.go:54:13:54:19 | selection of URL | SafeUrlFlow.go:78:40:78:55 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:54:13:54:19 | selection of URL | here | -| SafeUrlFlow.go:92:11:92:28 | call to String | SafeUrlFlow.go:84:14:84:21 | selection of Host | SafeUrlFlow.go:92:11:92:28 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:84:14:84:21 | selection of Host | here | +| SafeUrlFlow.go:89:24:89:41 | call to String | SafeUrlFlow.go:84:14:84:21 | selection of Host | SafeUrlFlow.go:89:24:89:41 | call to String | A safe URL flows here from $@. | SafeUrlFlow.go:84:14:84:21 | selection of Host | here | | SafeUrlFlow.go:105:11:105:23 | reconstructed | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:105:11:105:23 | reconstructed | A safe URL flows here from $@. | SafeUrlFlow.go:96:13:96:19 | selection of URL | here | | SafeUrlFlow.go:108:24:108:50 | ...+... | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:108:24:108:50 | ...+... | A safe URL flows here from $@. | SafeUrlFlow.go:96:13:96:19 | selection of URL | here | | SafeUrlFlow.go:109:29:109:58 | ...+... | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:109:29:109:58 | ...+... | A safe URL flows here from $@. | SafeUrlFlow.go:96:13:96:19 | selection of URL | here | @@ -27,9 +27,8 @@ edges | SafeUrlFlow.go:10:14:10:21 | selection of Host | SafeUrlFlow.go:17:19:17:26 | safeHost | provenance | | | SafeUrlFlow.go:13:13:13:19 | selection of URL | SafeUrlFlow.go:14:29:14:35 | safeURL | provenance | Src:MaD:2 | | SafeUrlFlow.go:14:29:14:35 | safeURL | SafeUrlFlow.go:14:29:14:44 | call to String | provenance | MaD:3 | -| SafeUrlFlow.go:17:2:17:10 | targetURL | SafeUrlFlow.go:18:11:18:19 | targetURL | provenance | | -| SafeUrlFlow.go:17:19:17:26 | safeHost | SafeUrlFlow.go:17:2:17:10 | targetURL | provenance | Config | -| SafeUrlFlow.go:17:19:17:26 | safeHost | SafeUrlFlow.go:18:11:18:19 | targetURL | provenance | Config | +| SafeUrlFlow.go:17:2:17:10 | targetURL [postupdate] | SafeUrlFlow.go:18:11:18:19 | targetURL | provenance | | +| SafeUrlFlow.go:17:19:17:26 | safeHost | SafeUrlFlow.go:17:2:17:10 | targetURL [postupdate] | provenance | Config | | SafeUrlFlow.go:18:11:18:19 | targetURL | SafeUrlFlow.go:18:11:18:28 | call to String | provenance | MaD:3 | | SafeUrlFlow.go:37:13:37:19 | selection of URL | SafeUrlFlow.go:45:24:45:61 | ...+... | provenance | Src:MaD:2 Sink:MaD:1 | | SafeUrlFlow.go:37:13:37:19 | selection of URL | SafeUrlFlow.go:46:29:46:55 | ...+... | provenance | Src:MaD:2 | @@ -57,10 +56,11 @@ edges | SafeUrlFlow.go:74:70:74:76 | safeURL | SafeUrlFlow.go:74:70:74:85 | call to String | provenance | MaD:3 | | SafeUrlFlow.go:78:40:78:46 | safeURL | SafeUrlFlow.go:78:40:78:55 | call to String | provenance | MaD:3 | | SafeUrlFlow.go:84:14:84:21 | selection of Host | SafeUrlFlow.go:87:19:87:26 | safeHost | provenance | | -| SafeUrlFlow.go:87:19:87:26 | safeHost | SafeUrlFlow.go:91:2:91:10 | targetURL | provenance | Config | -| SafeUrlFlow.go:87:19:87:26 | safeHost | SafeUrlFlow.go:92:11:92:19 | targetURL | provenance | Config | -| SafeUrlFlow.go:91:2:91:10 | targetURL | SafeUrlFlow.go:92:11:92:19 | targetURL | provenance | | -| SafeUrlFlow.go:92:11:92:19 | targetURL | SafeUrlFlow.go:92:11:92:28 | call to String | provenance | MaD:3 | +| SafeUrlFlow.go:87:2:87:10 | implicit dereference [postupdate] | SafeUrlFlow.go:87:2:87:10 | targetURL [postupdate] | provenance | | +| SafeUrlFlow.go:87:2:87:10 | targetURL [postupdate] | SafeUrlFlow.go:89:24:89:32 | targetURL | provenance | | +| SafeUrlFlow.go:87:19:87:26 | safeHost | SafeUrlFlow.go:87:2:87:10 | implicit dereference [postupdate] | provenance | Config | +| SafeUrlFlow.go:87:19:87:26 | safeHost | SafeUrlFlow.go:87:2:87:10 | targetURL [postupdate] | provenance | Config | +| SafeUrlFlow.go:89:24:89:32 | targetURL | SafeUrlFlow.go:89:24:89:41 | call to String | provenance | MaD:3 Sink:MaD:1 | | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:105:11:105:23 | reconstructed | provenance | Src:MaD:2 | | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:108:24:108:50 | ...+... | provenance | Src:MaD:2 Sink:MaD:1 | | SafeUrlFlow.go:96:13:96:19 | selection of URL | SafeUrlFlow.go:109:29:109:58 | ...+... | provenance | Src:MaD:2 | @@ -76,7 +76,7 @@ nodes | SafeUrlFlow.go:13:13:13:19 | selection of URL | semmle.label | selection of URL | | SafeUrlFlow.go:14:29:14:35 | safeURL | semmle.label | safeURL | | SafeUrlFlow.go:14:29:14:44 | call to String | semmle.label | call to String | -| SafeUrlFlow.go:17:2:17:10 | targetURL | semmle.label | targetURL | +| SafeUrlFlow.go:17:2:17:10 | targetURL [postupdate] | semmle.label | targetURL [postupdate] | | SafeUrlFlow.go:17:19:17:26 | safeHost | semmle.label | safeHost | | SafeUrlFlow.go:18:11:18:19 | targetURL | semmle.label | targetURL | | SafeUrlFlow.go:18:11:18:28 | call to String | semmle.label | call to String | @@ -108,10 +108,11 @@ nodes | SafeUrlFlow.go:78:40:78:46 | safeURL | semmle.label | safeURL | | SafeUrlFlow.go:78:40:78:55 | call to String | semmle.label | call to String | | SafeUrlFlow.go:84:14:84:21 | selection of Host | semmle.label | selection of Host | +| SafeUrlFlow.go:87:2:87:10 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| SafeUrlFlow.go:87:2:87:10 | targetURL [postupdate] | semmle.label | targetURL [postupdate] | | SafeUrlFlow.go:87:19:87:26 | safeHost | semmle.label | safeHost | -| SafeUrlFlow.go:91:2:91:10 | targetURL | semmle.label | targetURL | -| SafeUrlFlow.go:92:11:92:19 | targetURL | semmle.label | targetURL | -| SafeUrlFlow.go:92:11:92:28 | call to String | semmle.label | call to String | +| SafeUrlFlow.go:89:24:89:32 | targetURL | semmle.label | targetURL | +| SafeUrlFlow.go:89:24:89:41 | call to String | semmle.label | call to String | | SafeUrlFlow.go:96:13:96:19 | selection of URL | semmle.label | selection of URL | | SafeUrlFlow.go:105:11:105:23 | reconstructed | semmle.label | reconstructed | | SafeUrlFlow.go:108:24:108:50 | ...+... | semmle.label | ...+... | @@ -119,6 +120,3 @@ nodes | SafeUrlFlow.go:110:12:110:42 | ...+... | semmle.label | ...+... | | SafeUrlFlow.go:111:12:111:25 | safeOpaquePart | semmle.label | safeOpaquePart | subpaths -testFailures -| SafeUrlFlow.go:89:62:89:71 | comment | Missing result: Alert | -| SafeUrlFlow.go:92:11:92:28 | call to String | Unexpected result: Alert | From 8b04d0a2b9f7e41836475e51def398ede92a4f78 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 1 Oct 2025 10:06:12 +0100 Subject: [PATCH 59/70] Convert SSRF tests to inline expectations tests --- go/ql/test/experimental/CWE-918/SSRF.qlref | 4 +- go/ql/test/experimental/CWE-918/builtin.go | 22 +++++------ go/ql/test/experimental/CWE-918/new-tests.go | 40 ++++++++++---------- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/go/ql/test/experimental/CWE-918/SSRF.qlref b/go/ql/test/experimental/CWE-918/SSRF.qlref index 7cba541836f..d68094fa2a0 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.qlref +++ b/go/ql/test/experimental/CWE-918/SSRF.qlref @@ -1,2 +1,4 @@ query: experimental/CWE-918/SSRF.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-918/builtin.go b/go/ql/test/experimental/CWE-918/builtin.go index 5c65bc9d3de..463f4b3d09b 100644 --- a/go/ql/test/experimental/CWE-918/builtin.go +++ b/go/ql/test/experimental/CWE-918/builtin.go @@ -16,10 +16,10 @@ import ( ) func handler(w http.ResponseWriter, req *http.Request) { - target := req.FormValue("target") + target := req.FormValue("target") // $ Source // BAD: `target` is controlled by the attacker - _, err := http.Get("https://" + target + ".example.com/data/") + _, err := http.Get("https://" + target + ".example.com/data/") // $ Alert if err != nil { // error handling } @@ -80,12 +80,12 @@ func test() { // x net websocket dial bad http.HandleFunc("/ex2", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source origin := "http://localhost/" // bad as input is directly passed to dial function - ws, _ := websocket.Dial(untrustedInput, "", origin) // SSRF + ws, _ := websocket.Dial(untrustedInput, "", origin) // $ Alert var msg = make([]byte, 512) var n int n, _ = ws.Read(msg) @@ -94,12 +94,12 @@ func test() { // x net websocket dialConfig bad http.HandleFunc("/ex3", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source origin := "http://localhost/" // bad as input is directly used - config, _ := websocket.NewConfig(untrustedInput, origin) // SSRF - ws2, _ := websocket.DialConfig(config) + config, _ := websocket.NewConfig(untrustedInput, origin) // $ Sink + ws2, _ := websocket.DialConfig(config) // $ Alert var msg = make([]byte, 512) var n int n, _ = ws2.Read(msg) @@ -108,10 +108,10 @@ func test() { // gorilla websocket Dialer.Dial bad http.HandleFunc("/ex6", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source dialer := gorilla.Dialer{} - dialer.Dial(untrustedInput, r.Header) //SSRF + dialer.Dial(untrustedInput, r.Header) // $ Alert }) // gorilla websocket Dialer.Dial good @@ -126,10 +126,10 @@ func test() { // gorilla websocket Dialer.DialContext bad http.HandleFunc("/ex8", func(w http.ResponseWriter, r *http.Request) { - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source dialer := gorilla.Dialer{} - dialer.DialContext(context.TODO(), untrustedInput, r.Header) //SSRF + dialer.DialContext(context.TODO(), untrustedInput, r.Header) // $ Alert }) // gorilla websocket Dialer.DialContext good diff --git a/go/ql/test/experimental/CWE-918/new-tests.go b/go/ql/test/experimental/CWE-918/new-tests.go index 040bad48596..ddf94daa09e 100644 --- a/go/ql/test/experimental/CWE-918/new-tests.go +++ b/go/ql/test/experimental/CWE-918/new-tests.go @@ -23,20 +23,20 @@ func HandlerGin(c *gin.Context) { safe string `binding:"alphanum"` } - err := c.ShouldBindJSON(&body) + err := c.ShouldBindJSON(&body) // $ Source http.Get(fmt.Sprintf("http://example.com/%d", body.integer)) // OK http.Get(fmt.Sprintf("http://example.com/%v", body.float)) // OK http.Get(fmt.Sprintf("http://example.com/%v", body.boolean)) // OK - http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // SSRF - http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // SSRF + http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // $ Alert + http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // $ Alert if err == nil { - http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // SSRF + http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // $ Alert http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // OK } - taintedParam := c.Param("id") + taintedParam := c.Param("id") // $ Source validate := validator.New() err = validate.Var(taintedParam, "alpha") @@ -44,10 +44,10 @@ func HandlerGin(c *gin.Context) { http.Get("http://example.com/" + taintedParam) // OK } - http.Get("http://example.com/" + taintedParam) //SSRF + http.Get("http://example.com/" + taintedParam) // $ Alert - taintedQuery := c.Query("id") - http.Get("http://example.com/" + taintedQuery) //SSRF + taintedQuery := c.Query("id") // $ Source + http.Get("http://example.com/" + taintedQuery) // $ Alert } func HandlerHttp(req *http.Request) { @@ -59,41 +59,41 @@ func HandlerHttp(req *http.Request) { word string safe string `validate:"alphanum"` } - reqBody, _ := ioutil.ReadAll(req.Body) + reqBody, _ := ioutil.ReadAll(req.Body) // $ Source json.Unmarshal(reqBody, &body) http.Get(fmt.Sprintf("http://example.com/%d", body.integer)) // OK http.Get(fmt.Sprintf("http://example.com/%v", body.float)) // OK http.Get(fmt.Sprintf("http://example.com/%v", body.boolean)) // OK - http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // SSRF - http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // SSRF + http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // $ Alert + http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // $ Alert validate := validator.New() err := validate.Struct(body) if err == nil { - http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // SSRF + http.Get(fmt.Sprintf("http://example.com/%s", body.word)) // $ Alert http.Get(fmt.Sprintf("http://example.com/%s", body.safe)) // OK } - taintedQuery := req.URL.Query().Get("param1") - http.Get("http://example.com/" + taintedQuery) // SSRF + taintedQuery := req.URL.Query().Get("param1") // $ Source + http.Get("http://example.com/" + taintedQuery) // $ Alert - taintedParam := strings.TrimPrefix(req.URL.Path, "/example-path/") - http.Get("http://example.com/" + taintedParam) // SSRF + taintedParam := strings.TrimPrefix(req.URL.Path, "/example-path/") // $ Source + http.Get("http://example.com/" + taintedParam) // $ Alert } func HandlerMux(r *http.Request) { - vars := mux.Vars(r) + vars := mux.Vars(r) // $ Source taintedParam := vars["id"] - http.Get("http://example.com/" + taintedParam) // SSRF + http.Get("http://example.com/" + taintedParam) // $ Alert numericID, _ := strconv.Atoi(taintedParam) http.Get(fmt.Sprintf("http://example.com/%d", numericID)) // OK } func HandlerChi(r *http.Request) { - taintedParam := chi.URLParam(r, "articleID") - http.Get("http://example.com/" + taintedParam) // SSRF + taintedParam := chi.URLParam(r, "articleID") // $ Source + http.Get("http://example.com/" + taintedParam) // $ Alert b, _ := strconv.ParseBool(taintedParam) http.Get(fmt.Sprintf("http://example.com/%t", b)) // OK From c9ce2c804314ea4c3c1a7cd380218258180a069c Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 1 Oct 2025 10:18:52 +0100 Subject: [PATCH 60/70] Add test for assignment to Url.Host field --- go/ql/test/experimental/CWE-918/SSRF.expected | 71 +++++++++++-------- go/ql/test/experimental/CWE-918/builtin.go | 14 ++++ 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index a947101b354..a14339943d5 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -1,9 +1,10 @@ #select -| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value. | -| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value. | -| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value. | -| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value. | -| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:23:12:23:63 | call to Get | builtin.go:20:12:20:34 | call to FormValue | builtin.go:23:21:23:62 | ...+... | The URL of this request depends on a user-provided value. | +| builtin.go:89:12:89:53 | call to Dial | builtin.go:84:21:84:31 | call to Referer | builtin.go:89:27:89:40 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:103:13:103:40 | call to DialConfig | builtin.go:98:21:98:31 | call to Referer | builtin.go:102:36:102:49 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:115:3:115:39 | call to Dial | builtin.go:112:21:112:31 | call to Referer | builtin.go:115:15:115:28 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:133:3:133:62 | call to DialContext | builtin.go:130:21:130:31 | call to Referer | builtin.go:133:38:133:51 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:156:12:156:33 | call to Get | builtin.go:151:16:151:36 | call to FormValue | builtin.go:156:21:156:32 | call to String | The URL of this request depends on a user-provided value. | | new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. | | new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. | | new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. | @@ -17,11 +18,18 @@ | new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value. | | new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value. | edges -| builtin.go:19:12:19:34 | call to FormValue | builtin.go:22:21:22:62 | ...+... | provenance | Src:MaD:7 | -| builtin.go:83:21:83:31 | call to Referer | builtin.go:88:27:88:40 | untrustedInput | provenance | Src:MaD:8 | -| builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | provenance | Src:MaD:8 | -| builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | provenance | Src:MaD:8 | -| builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:20:12:20:34 | call to FormValue | builtin.go:23:21:23:62 | ...+... | provenance | Src:MaD:7 | +| builtin.go:84:21:84:31 | call to Referer | builtin.go:89:27:89:40 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:98:21:98:31 | call to Referer | builtin.go:102:36:102:49 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:112:21:112:31 | call to Referer | builtin.go:115:15:115:28 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:130:21:130:31 | call to Referer | builtin.go:133:38:133:51 | untrustedInput | provenance | Src:MaD:8 | +| builtin.go:151:16:151:36 | call to FormValue | builtin.go:154:13:154:22 | unsafehost | provenance | Src:MaD:7 | +| builtin.go:154:2:154:4 | implicit dereference | builtin.go:156:21:156:23 | url | provenance | | +| builtin.go:154:2:154:4 | url | builtin.go:154:2:154:4 | implicit dereference | provenance | | +| builtin.go:154:2:154:4 | url | builtin.go:156:21:156:23 | url | provenance | | +| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | implicit dereference | provenance | Config | +| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | url | provenance | Config | +| builtin.go:156:21:156:23 | url | builtin.go:156:21:156:32 | call to String | provenance | MaD:12 | | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:48:31:56 | selection of word | provenance | Src:MaD:3 | | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:32:48:32:56 | selection of safe | provenance | Src:MaD:3 | | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:35:49:35:57 | selection of word | provenance | Src:MaD:3 | @@ -37,7 +45,7 @@ edges | new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | provenance | Src:MaD:1 | | new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | provenance | Src:MaD:2 | | new-tests.go:62:2:62:39 | ... := ...[0] | new-tests.go:63:17:63:23 | reqBody | provenance | | -| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | provenance | Src:MaD:6 MaD:12 | +| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | provenance | Src:MaD:6 MaD:13 | | new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... [postupdate] | provenance | MaD:10 | | new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:68:48:68:56 | selection of word | provenance | | | new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:69:48:69:56 | selection of safe | provenance | | @@ -51,12 +59,12 @@ edges | new-tests.go:74:12:74:58 | []type{args} [array] | new-tests.go:74:12:74:58 | call to Sprintf | provenance | MaD:11 | | new-tests.go:74:49:74:57 | selection of word | new-tests.go:74:12:74:58 | []type{args} [array] | provenance | | | new-tests.go:74:49:74:57 | selection of word | new-tests.go:74:12:74:58 | call to Sprintf | provenance | FunctionModel | -| new-tests.go:78:18:78:24 | selection of URL | new-tests.go:78:18:78:32 | call to Query | provenance | Src:MaD:9 MaD:13 | -| new-tests.go:78:18:78:32 | call to Query | new-tests.go:78:18:78:46 | call to Get | provenance | MaD:14 | +| new-tests.go:78:18:78:24 | selection of URL | new-tests.go:78:18:78:32 | call to Query | provenance | Src:MaD:9 MaD:14 | +| new-tests.go:78:18:78:32 | call to Query | new-tests.go:78:18:78:46 | call to Get | provenance | MaD:15 | | new-tests.go:78:18:78:46 | call to Get | new-tests.go:79:11:79:46 | ...+... | provenance | | | new-tests.go:81:18:81:67 | call to TrimPrefix | new-tests.go:82:11:82:46 | ...+... | provenance | | | new-tests.go:81:37:81:43 | selection of URL | new-tests.go:81:37:81:48 | selection of Path | provenance | Src:MaD:9 | -| new-tests.go:81:37:81:48 | selection of Path | new-tests.go:81:18:81:67 | call to TrimPrefix | provenance | MaD:15 | +| new-tests.go:81:37:81:48 | selection of Path | new-tests.go:81:18:81:67 | call to TrimPrefix | provenance | MaD:16 | | new-tests.go:86:10:86:20 | call to Vars | new-tests.go:88:11:88:46 | ...+... | provenance | Src:MaD:5 | | new-tests.go:95:18:95:45 | call to URLParam | new-tests.go:96:11:96:46 | ...+... | provenance | Src:MaD:4 | models @@ -71,21 +79,28 @@ models | 9 | Source: net/http; Request; true; URL; ; ; ; remote; manual | | 10 | Summary: encoding/json; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual | | 11 | Summary: fmt; ; false; Sprintf; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual | -| 12 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual | -| 13 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual | -| 14 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | -| 15 | Summary: strings; ; false; TrimPrefix; ; ; Argument[0]; ReturnValue; taint; manual | +| 12 | Summary: fmt; Stringer; true; String; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 13 | Summary: io/ioutil; ; false; ReadAll; ; ; Argument[0]; ReturnValue[0]; taint; manual | +| 14 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 15 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | +| 16 | Summary: strings; ; false; TrimPrefix; ; ; Argument[0]; ReturnValue; taint; manual | nodes -| builtin.go:19:12:19:34 | call to FormValue | semmle.label | call to FormValue | -| builtin.go:22:21:22:62 | ...+... | semmle.label | ...+... | -| builtin.go:83:21:83:31 | call to Referer | semmle.label | call to Referer | -| builtin.go:88:27:88:40 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:97:21:97:31 | call to Referer | semmle.label | call to Referer | -| builtin.go:101:36:101:49 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:111:21:111:31 | call to Referer | semmle.label | call to Referer | -| builtin.go:114:15:114:28 | untrustedInput | semmle.label | untrustedInput | -| builtin.go:129:21:129:31 | call to Referer | semmle.label | call to Referer | -| builtin.go:132:38:132:51 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:20:12:20:34 | call to FormValue | semmle.label | call to FormValue | +| builtin.go:23:21:23:62 | ...+... | semmle.label | ...+... | +| builtin.go:84:21:84:31 | call to Referer | semmle.label | call to Referer | +| builtin.go:89:27:89:40 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:98:21:98:31 | call to Referer | semmle.label | call to Referer | +| builtin.go:102:36:102:49 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:112:21:112:31 | call to Referer | semmle.label | call to Referer | +| builtin.go:115:15:115:28 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:130:21:130:31 | call to Referer | semmle.label | call to Referer | +| builtin.go:133:38:133:51 | untrustedInput | semmle.label | untrustedInput | +| builtin.go:151:16:151:36 | call to FormValue | semmle.label | call to FormValue | +| builtin.go:154:2:154:4 | implicit dereference | semmle.label | implicit dereference | +| builtin.go:154:2:154:4 | url | semmle.label | url | +| builtin.go:154:13:154:22 | unsafehost | semmle.label | unsafehost | +| builtin.go:156:21:156:23 | url | semmle.label | url | +| builtin.go:156:21:156:32 | call to String | semmle.label | call to String | | new-tests.go:26:26:26:30 | &... [postupdate] | semmle.label | &... [postupdate] | | new-tests.go:31:11:31:57 | []type{args} [array] | semmle.label | []type{args} [array] | | new-tests.go:31:11:31:57 | call to Sprintf | semmle.label | call to Sprintf | diff --git a/go/ql/test/experimental/CWE-918/builtin.go b/go/ql/test/experimental/CWE-918/builtin.go index 463f4b3d09b..6c39f24dc47 100644 --- a/go/ql/test/experimental/CWE-918/builtin.go +++ b/go/ql/test/experimental/CWE-918/builtin.go @@ -8,6 +8,7 @@ import ( "fmt" "log" "net/http" + "net/url" "regexp" "strings" @@ -145,3 +146,16 @@ func test() { log.Println(http.ListenAndServe(":80", nil)) } + +func handler2(w http.ResponseWriter, req *http.Request) { + unsafehost := req.FormValue("host") // $ Source + + url, _ := url.Parse("http://example.com/data") + url.Host = unsafehost + // BAD: `target` is controlled by the attacker + _, err := http.Get(url.String()) // $ Alert + if err != nil { + // error handling + } + // process request response +} From f0f5fc7eac40fc5dc0ce35a3fe7cc5e320921f4f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 1 Oct 2025 10:03:20 +0100 Subject: [PATCH 61/70] Improve SSRF additional flow step --- go/ql/src/experimental/CWE-918/SSRF.qll | 5 ++--- go/ql/test/experimental/CWE-918/SSRF.expected | 13 ++++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index ae041415dfe..f0d3cc935a1 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -22,9 +22,8 @@ module ServerSideRequestForgery { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesFieldPreUpdate(v.getAUse(), f, node1) and - node2 = v.getAUse() + exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | + w.writesField(node2, f, node1) ) } diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index a14339943d5..5c8d1832ac1 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -24,11 +24,10 @@ edges | builtin.go:112:21:112:31 | call to Referer | builtin.go:115:15:115:28 | untrustedInput | provenance | Src:MaD:8 | | builtin.go:130:21:130:31 | call to Referer | builtin.go:133:38:133:51 | untrustedInput | provenance | Src:MaD:8 | | builtin.go:151:16:151:36 | call to FormValue | builtin.go:154:13:154:22 | unsafehost | provenance | Src:MaD:7 | -| builtin.go:154:2:154:4 | implicit dereference | builtin.go:156:21:156:23 | url | provenance | | -| builtin.go:154:2:154:4 | url | builtin.go:154:2:154:4 | implicit dereference | provenance | | -| builtin.go:154:2:154:4 | url | builtin.go:156:21:156:23 | url | provenance | | -| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | implicit dereference | provenance | Config | -| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | url | provenance | Config | +| builtin.go:154:2:154:4 | implicit dereference [postupdate] | builtin.go:154:2:154:4 | url [postupdate] | provenance | | +| builtin.go:154:2:154:4 | url [postupdate] | builtin.go:156:21:156:23 | url | provenance | | +| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | implicit dereference [postupdate] | provenance | Config | +| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | url [postupdate] | provenance | Config | | builtin.go:156:21:156:23 | url | builtin.go:156:21:156:32 | call to String | provenance | MaD:12 | | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:48:31:56 | selection of word | provenance | Src:MaD:3 | | new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:32:48:32:56 | selection of safe | provenance | Src:MaD:3 | @@ -96,8 +95,8 @@ nodes | builtin.go:130:21:130:31 | call to Referer | semmle.label | call to Referer | | builtin.go:133:38:133:51 | untrustedInput | semmle.label | untrustedInput | | builtin.go:151:16:151:36 | call to FormValue | semmle.label | call to FormValue | -| builtin.go:154:2:154:4 | implicit dereference | semmle.label | implicit dereference | -| builtin.go:154:2:154:4 | url | semmle.label | url | +| builtin.go:154:2:154:4 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| builtin.go:154:2:154:4 | url [postupdate] | semmle.label | url [postupdate] | | builtin.go:154:13:154:22 | unsafehost | semmle.label | unsafehost | | builtin.go:156:21:156:23 | url | semmle.label | url | | builtin.go:156:21:156:32 | call to String | semmle.label | call to String | From 6d6852fb8d38f5a1aa44270b87a41a94fc7b50a1 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 1 Oct 2025 12:36:16 +0100 Subject: [PATCH 62/70] Test PathAssignmentBarrier for OpenUrlRedirect --- .../OpenUrlRedirect/OpenUrlRedirect.expected | 24 +++++++++++++++++++ .../CWE-601/OpenUrlRedirect/stdlib.go | 22 +++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index 1d302f911cd..d9f24369ca2 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -12,6 +12,7 @@ | stdlib.go:198:23:198:42 | call to EscapedPath | stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:198:23:198:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:194:36:194:56 | call to FormValue | user-provided value | | stdlib.go:212:23:212:28 | selection of Path | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:212:23:212:28 | selection of Path | This path to an untrusted URL redirection depends on a $@. | stdlib.go:210:12:210:30 | call to FormValue | user-provided value | | stdlib.go:214:23:214:32 | call to String | stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:214:23:214:32 | call to String | This path to an untrusted URL redirection depends on a $@. | stdlib.go:210:12:210:30 | call to FormValue | user-provided value | +| stdlib.go:261:23:261:32 | call to String | stdlib.go:257:12:257:30 | call to FormValue | stdlib.go:261:23:261:32 | call to String | This path to an untrusted URL redirection depends on a $@. | stdlib.go:257:12:257:30 | call to FormValue | user-provided value | edges | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | provenance | Src:MaD:2 Config Sink:MaD:1 | | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:13:13:13:32 | call to Get | provenance | Src:MaD:2 Config | @@ -75,6 +76,19 @@ edges | stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:212:23:212:23 | implicit dereference | provenance | Config | | stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:214:23:214:23 | u | provenance | | | stdlib.go:214:23:214:23 | u | stdlib.go:214:23:214:32 | call to String | provenance | Config Sink:MaD:1 | +| stdlib.go:257:3:257:3 | implicit dereference [postupdate] | stdlib.go:257:3:257:3 | u [postupdate] | provenance | Config | +| stdlib.go:257:3:257:3 | implicit dereference [postupdate] | stdlib.go:257:3:257:3 | u [postupdate] [pointer] | provenance | | +| stdlib.go:257:3:257:3 | u [postupdate] | stdlib.go:260:3:260:3 | u | provenance | | +| stdlib.go:257:3:257:3 | u [postupdate] [pointer] | stdlib.go:260:3:260:3 | u [pointer] | provenance | | +| stdlib.go:257:12:257:30 | call to FormValue | stdlib.go:257:3:257:3 | implicit dereference [postupdate] | provenance | Src:MaD:3 Config | +| stdlib.go:257:12:257:30 | call to FormValue | stdlib.go:257:3:257:3 | u [postupdate] | provenance | Src:MaD:3 Config | +| stdlib.go:260:3:260:3 | implicit dereference | stdlib.go:260:3:260:3 | u [postupdate] | provenance | Config | +| stdlib.go:260:3:260:3 | u | stdlib.go:260:3:260:3 | implicit dereference | provenance | Config | +| stdlib.go:260:3:260:3 | u | stdlib.go:261:23:261:23 | u | provenance | | +| stdlib.go:260:3:260:3 | u [pointer] | stdlib.go:260:3:260:3 | implicit dereference | provenance | | +| stdlib.go:260:3:260:3 | u [postupdate] | stdlib.go:260:3:260:3 | implicit dereference | provenance | Config | +| stdlib.go:260:3:260:3 | u [postupdate] | stdlib.go:261:23:261:23 | u | provenance | | +| stdlib.go:261:23:261:23 | u | stdlib.go:261:23:261:32 | call to String | provenance | Config Sink:MaD:1 | models | 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual | | 2 | Source: net/http; Request; true; Form; ; ; ; remote; manual | @@ -147,4 +161,14 @@ nodes | stdlib.go:212:23:212:28 | selection of Path | semmle.label | selection of Path | | stdlib.go:214:23:214:23 | u | semmle.label | u | | stdlib.go:214:23:214:32 | call to String | semmle.label | call to String | +| stdlib.go:257:3:257:3 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| stdlib.go:257:3:257:3 | u [postupdate] | semmle.label | u [postupdate] | +| stdlib.go:257:3:257:3 | u [postupdate] [pointer] | semmle.label | u [postupdate] [pointer] | +| stdlib.go:257:12:257:30 | call to FormValue | semmle.label | call to FormValue | +| stdlib.go:260:3:260:3 | implicit dereference | semmle.label | implicit dereference | +| stdlib.go:260:3:260:3 | u | semmle.label | u | +| stdlib.go:260:3:260:3 | u [pointer] | semmle.label | u [pointer] | +| stdlib.go:260:3:260:3 | u [postupdate] | semmle.label | u [postupdate] | +| stdlib.go:261:23:261:23 | u | semmle.label | u | +| stdlib.go:261:23:261:32 | call to String | semmle.label | call to String | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go index c32661f6688..57f2964288c 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go @@ -239,5 +239,27 @@ func serveStdlib() { http.Redirect(w, r, string(buf), 301) }) + http.HandleFunc("/ex13", func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + + u, _ := url.Parse("http://example.com") + u.Host = r.FormValue("host") + // GOOD: Path field is assigned a value with a hostname-sanitizing substring, + // so subsequent uses of u are sanitized by PathAssignmentBarrier + u.Path = "/safe/" + r.FormValue("path") + http.Redirect(w, r, u.String(), 301) + }) + + http.HandleFunc("/ex14", func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + + u, _ := url.Parse("http://example.com") + u.Host = r.FormValue("host") // $ Source + // BAD: Path field is assigned but without a hostname-sanitizing substring, + // so the Host field remains untrusted + u.Path = r.FormValue("path") + http.Redirect(w, r, u.String(), 301) // $ Alert + }) + http.ListenAndServe(":80", nil) } From c006777714409119d256be5ba076cef0aa3904b4 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 1 Oct 2025 13:06:24 +0100 Subject: [PATCH 63/70] Simplify PathAssignmentBarrier --- .../OpenUrlRedirectCustomizations.qll | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index da5110a2ef5..248276ba396 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -75,25 +75,18 @@ module OpenUrlRedirect { } } - bindingset[var, w] - pragma[inline_late] - private predicate useIsDominated(SsaWithFields var, Write w, DataFlow::ReadNode sanitizedRead) { - w.dominatesNode(sanitizedRead.asInstruction()) and - sanitizedRead = var.getAUse() - } - /** - * An access to a variable that is preceded by an assignment to its `Path` field. + * An assignment of a safe value to the field `Path`, considered as a barrier for sanitizing + * untrusted URLs. * * This is overapproximate; this will currently remove flow through all `Url.Path` assignments * which contain a substring that could sanitize data. */ - class PathAssignmentBarrier extends Barrier, Read { + class PathAssignmentBarrier extends Barrier { PathAssignmentBarrier() { - exists(Write w, SsaWithFields var | - hasHostnameSanitizingSubstring(w.getRhs()) and - w.writesFieldPreUpdate(var.getAUse(), any(Field f | f.getName() = "Path"), _) and - useIsDominated(var, w, this) + exists(Write w, DataFlow::Node rhs | + hasHostnameSanitizingSubstring(rhs) and + w.writesFieldPreUpdate(this, any(Field f | f.getName() = "Path"), rhs) ) } } From 2629369c9358c320a72a0ee104392f32889e31ef Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 1 Oct 2025 13:12:24 +0100 Subject: [PATCH 64/70] Improve additional flow step for Host field --- go/ql/lib/semmle/go/security/RequestForgery.qll | 5 ++--- .../Security/CWE-918/RequestForgery.expected | 10 ++++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/go/ql/lib/semmle/go/security/RequestForgery.qll b/go/ql/lib/semmle/go/security/RequestForgery.qll index 0cd86b12abb..03b6f9ac0b0 100644 --- a/go/ql/lib/semmle/go/security/RequestForgery.qll +++ b/go/ql/lib/semmle/go/security/RequestForgery.qll @@ -27,9 +27,8 @@ module RequestForgery { predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesFieldPreUpdate(v.getAUse(), f, pred) and - succ = v.getAUse() + exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | + w.writesField(succ, f, pred) ) } diff --git a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 188abc9c7f9..129613a3f1a 100644 --- a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -37,9 +37,10 @@ edges | tst.go:10:13:10:35 | call to FormValue | tst.go:38:11:38:29 | ...+... | provenance | Src:MaD:1 | | tst.go:10:13:10:35 | call to FormValue | tst.go:40:11:40:40 | ...+... | provenance | Src:MaD:1 | | tst.go:10:13:10:35 | call to FormValue | tst.go:47:11:47:18 | tainted2 | provenance | Src:MaD:1 | -| tst.go:47:2:47:2 | u | tst.go:48:11:48:11 | u | provenance | | -| tst.go:47:11:47:18 | tainted2 | tst.go:47:2:47:2 | u | provenance | Config | -| tst.go:47:11:47:18 | tainted2 | tst.go:48:11:48:11 | u | provenance | Config | +| tst.go:47:2:47:2 | implicit dereference [postupdate] | tst.go:47:2:47:2 | u [postupdate] | provenance | | +| tst.go:47:2:47:2 | u [postupdate] | tst.go:48:11:48:11 | u | provenance | | +| tst.go:47:11:47:18 | tainted2 | tst.go:47:2:47:2 | implicit dereference [postupdate] | provenance | Config | +| tst.go:47:11:47:18 | tainted2 | tst.go:47:2:47:2 | u [postupdate] | provenance | Config | | tst.go:48:11:48:11 | u | tst.go:48:11:48:20 | call to String | provenance | MaD:3 | | websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | provenance | Src:MaD:2 | | websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | provenance | Src:MaD:2 | @@ -70,7 +71,8 @@ nodes | tst.go:36:18:36:24 | tainted | semmle.label | tainted | | tst.go:38:11:38:29 | ...+... | semmle.label | ...+... | | tst.go:40:11:40:40 | ...+... | semmle.label | ...+... | -| tst.go:47:2:47:2 | u | semmle.label | u | +| tst.go:47:2:47:2 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] | +| tst.go:47:2:47:2 | u [postupdate] | semmle.label | u [postupdate] | | tst.go:47:11:47:18 | tainted2 | semmle.label | tainted2 | | tst.go:48:11:48:11 | u | semmle.label | u | | tst.go:48:11:48:20 | call to String | semmle.label | call to String | From 7fdda87b06ab34bf4ff8cc083d42cbaf7df005eb Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 2 Oct 2025 12:34:58 +0100 Subject: [PATCH 65/70] Fix `go/impossible-interface-nil-check` for separate post-update nodes When tracing back from nil checks on interfaces, ignore post-update nodes. There will always be a corresponding pre-update node that contains the information we want. --- go/ql/src/RedundantCode/ImpossibleInterfaceNilCheck.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go/ql/src/RedundantCode/ImpossibleInterfaceNilCheck.ql b/go/ql/src/RedundantCode/ImpossibleInterfaceNilCheck.ql index c5aeb287358..c8ff9c345f6 100644 --- a/go/ql/src/RedundantCode/ImpossibleInterfaceNilCheck.ql +++ b/go/ql/src/RedundantCode/ImpossibleInterfaceNilCheck.ql @@ -35,7 +35,9 @@ predicate flowsToInterfaceNilCheck(DataFlow::Node nd) { */ predicate nonNilWrapper(DataFlow::Node nd) { flowsToInterfaceNilCheck(nd) and - forex(DataFlow::Node pred | pred = nd.getAPredecessor() | + forex(DataFlow::Node pred | + pred = nd.getAPredecessor() and not pred instanceof DataFlow::PostUpdateNode + | exists(Type predtp | predtp = pred.getType().getUnderlyingType() | not predtp instanceof InterfaceType and not predtp instanceof NilLiteralType and From d8891e34d10fd7bf374f7c38cd5dfa55b7c06811 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 2 Oct 2025 15:15:51 +0100 Subject: [PATCH 66/70] Small improvement to `go/unhandled-writable-file-close` --- go/ql/src/InconsistentCode/UnhandledCloseWritableHandle.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/ql/src/InconsistentCode/UnhandledCloseWritableHandle.ql b/go/ql/src/InconsistentCode/UnhandledCloseWritableHandle.ql index 3fd09ac040e..48e4f98fdb2 100644 --- a/go/ql/src/InconsistentCode/UnhandledCloseWritableHandle.ql +++ b/go/ql/src/InconsistentCode/UnhandledCloseWritableHandle.ql @@ -70,8 +70,8 @@ predicate unhandledCall(DataFlow::CallNode call) { */ predicate isWritableFileHandle(DataFlow::Node source, DataFlow::CallNode call) { exists(OpenFileFun f, DataFlow::Node flags, QualifiedName flag | - // check that the source is a result of the call - source = call.getAResult() and + // check that the source is the first result of the call + source = call.getResult(0) and // find a call to the os.OpenFile function f.getACall() = call and // get the flags expression used for opening the file From 4d4862899e36dafdf32c6a7686f01bacdf23b2e0 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 2 Oct 2025 16:50:18 +0100 Subject: [PATCH 67/70] Preserve old behaviour of `Write.writesComponent` --- go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll index d527a650b9d..1e66bc61dc4 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraph.qll @@ -225,12 +225,14 @@ module ControlFlow { } /** - * DEPRECATED: Use the disjunct of `writesElement` and `writesField` instead. + * DEPRECATED: Use the disjunct of `writesElement` and `writesField`, or `writesFieldPreUpdate` + * and `writesElementPreUpdate`, instead. * - * Holds if this node sets any field or element of `base` to `rhs`. + * Holds if this node sets any field or element of `base` (or its implicit dereference) to + * `rhs`, where `base` represents the pre-update value. */ deprecated predicate writesComponent(DataFlow::Node base, DataFlow::Node rhs) { - this.writesElement(base, _, rhs) or this.writesField(base, _, rhs) + this.writesElementPreUpdate(base, _, rhs) or this.writesFieldPreUpdate(base, _, rhs) } /** From cce44b1f5486130ac3b4486b4d35657598875717 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 2 Oct 2025 16:52:16 +0100 Subject: [PATCH 68/70] Update change notes for api changes --- go/ql/lib/change-notes/2025-09-19-api-changes.md | 5 ++--- .../2025-10-02-writenode-writescomponent-deprecated.md | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 go/ql/lib/change-notes/2025-10-02-writenode-writescomponent-deprecated.md diff --git a/go/ql/lib/change-notes/2025-09-19-api-changes.md b/go/ql/lib/change-notes/2025-09-19-api-changes.md index 44f070fb1d7..071ec2719b3 100644 --- a/go/ql/lib/change-notes/2025-09-19-api-changes.md +++ b/go/ql/lib/change-notes/2025-09-19-api-changes.md @@ -1,6 +1,5 @@ --- category: breaking --- -* The member predicate `writesField(DataFlow::Node base, Field f, DataFlow::Node rhs)` on `DataFlow::Write` now uses the post-update node for `base` when that is the node being updated, which is in all cases except initializing a struct literal. A new member predicate `writesFieldOnSsaWithFields(SsaWithFields v, Field f, DataFlow::Node rhs)` has been added for the case of writes to a SsaWithFields node. -* The member predicate `writesElement(DataFlow::Node base, DataFlow::Node index, DataFlow::Node rhs)` on `DataFlow::Write` now uses the post-update node for `base` when that is the node being updated, which is in all cases except initializing an array/slice/map literal. -* The member predicate `writesComponent(DataFlow::Node base, DataFlow::Node rhs)` on `DataFlow::Write` now uses the post-update node for `base` when that is the node being updated, which is in all cases except initializing a struct/array/slice/map literal. +* The member predicate `writesField` on `DataFlow::Write` now uses the post-update node for `base` when that is the node being updated, which is in all cases except initializing a struct literal. A new member predicate `writesFieldPreUpdate` has been added for cases where this behaviour is not desired. +* The member predicate `writesElement` on `DataFlow::Write` now uses the post-update node for `base` when that is the node being updated, which is in all cases except initializing an array/slice/map literal. A new member predicate `writesElementPreUpdate` has been added for cases where this behaviour is not desired. diff --git a/go/ql/lib/change-notes/2025-10-02-writenode-writescomponent-deprecated.md b/go/ql/lib/change-notes/2025-10-02-writenode-writescomponent-deprecated.md new file mode 100644 index 00000000000..834266e36b9 --- /dev/null +++ b/go/ql/lib/change-notes/2025-10-02-writenode-writescomponent-deprecated.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The member predicate `writesComponent` on `DataFlow::Write` has been deprecated. Instead, use `writesFieldPreUpdate` and `writesElementPreUpdate`, or their new versions `writesField` and `writesElement`. From f35d28de45b540b1f9e90a8ff54f555ad87fbb5f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 2 Oct 2025 17:03:55 +0100 Subject: [PATCH 69/70] Change note for bug fix in `go/unvalidated-url-redirection` --- .../2025-10-02-unvalidated-url-redirection-struct-init-fix.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/lib/change-notes/2025-10-02-unvalidated-url-redirection-struct-init-fix.md diff --git a/go/ql/lib/change-notes/2025-10-02-unvalidated-url-redirection-struct-init-fix.md b/go/ql/lib/change-notes/2025-10-02-unvalidated-url-redirection-struct-init-fix.md new file mode 100644 index 00000000000..9e5d5aa14a2 --- /dev/null +++ b/go/ql/lib/change-notes/2025-10-02-unvalidated-url-redirection-struct-init-fix.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* For the query `go/unvalidated-url-redirection`, when untrusted data is assigned to the `Host` field of a `url.URL` struct, we consider the whole struct untrusted. We now also include the case when this happens during struct initialization, for example `&url.URL{Host: untrustedData}`. From bc0b87632dab87a12f4f7cb0b413f3719d875e99 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 2 Oct 2025 17:36:21 +0100 Subject: [PATCH 70/70] C++: Fix bad magic on `Element.getFile` when running on InconsistentCheckReturnNull.qll: Evaluated non-recursive predicate Element::Element.getFile/0#dispred#536cb5f3#bb@f6f5329i in 182326ms (size: 50437). Evaluated relational algebra for predicate Element::Element.getFile/0#dispred#536cb5f3#bb@f6f5329i with tuple counts: 2029351 ~0% {2} r1 = SCAN `Expr::Expr.getLocation/0#dispred#0a3d90c6` OUTPUT In.1, In.0 2029351 ~0% {2} | JOIN WITH `Location::Location.getStartLine/0#d54f9e6c` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 1168789 ~0% {2} | JOIN WITH `InconsistentCheckReturnNull::assertInvocation/2#b2a4c9e3_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 5533128288 ~0% {3} | JOIN WITH `Location::Location.getContainer/0#9edabfb6_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.0 50413 ~0% {2} | JOIN WITH `Element::Element.getLocation/0#dispred#6c3f5b09#bf` ON FIRST 2 OUTPUT Lhs.0, Lhs.2 3043 ~0% {2} r2 = JOIN `project#InconsistentCheckReturnNull::relevantFunctionCall/2#d18cd566` WITH `Expr::Expr.getLocation/0#dispred#0a3d90c6` ON FIRST 1 OUTPUT Rhs.1, Lhs.0 3043 ~0% {2} r3 = JOIN r2 WITH locations_default ON FIRST 1 OUTPUT Rhs.4, Lhs.1 1945 ~3% {2} | JOIN WITH `InconsistentCheckReturnNull::assertInvocation/2#b2a4c9e3_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 9106248 ~2% {3} | JOIN WITH `Location::Location.getContainer/0#9edabfb6_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.0 0 ~0% {2} | JOIN WITH `Element::Element.getLocation/0#dispred#6c3f5b09#bf` ON FIRST 2 OUTPUT Lhs.0, Lhs.2 3043 ~0% {3} r4 = JOIN r2 WITH locations_default ON FIRST 1 OUTPUT _, Lhs.1, Rhs.4 3043 ~0% {2} | REWRITE WITH Tmp.0 := 1, Out.0 := (In.2 + Tmp.0) KEEPING 2 2013 ~0% {2} | JOIN WITH `InconsistentCheckReturnNull::assertInvocation/2#b2a4c9e3_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 9621327 ~0% {3} | JOIN WITH `Location::Location.getContainer/0#9edabfb6_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.0 24 ~3% {2} | JOIN WITH `Element::Element.getLocation/0#dispred#6c3f5b09#bf` ON FIRST 2 OUTPUT Lhs.0, Lhs.2 50437 ~0% {2} r5 = r1 UNION r3 UNION r4 return r5 --- cpp/ql/lib/semmle/code/cpp/Element.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/lib/semmle/code/cpp/Element.qll b/cpp/ql/lib/semmle/code/cpp/Element.qll index 1cf75aa8a84..b30503d2c94 100644 --- a/cpp/ql/lib/semmle/code/cpp/Element.qll +++ b/cpp/ql/lib/semmle/code/cpp/Element.qll @@ -87,6 +87,7 @@ class ElementBase extends @element { */ class Element extends ElementBase { /** Gets the primary file where this element occurs. */ + pragma[nomagic] File getFile() { result = this.getLocation().getFile() } /**