From 1e1e4c6743f4ec488f4435a2af37304af4c013f1 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 15 Oct 2025 11:33:42 +0100 Subject: [PATCH 1/5] PS: Prettify. --- .../code/powershell/security/SqlInjectionCustomizations.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/powershell/ql/lib/semmle/code/powershell/security/SqlInjectionCustomizations.qll b/powershell/ql/lib/semmle/code/powershell/security/SqlInjectionCustomizations.qll index ac63a3267871..0ddf496f7562 100644 --- a/powershell/ql/lib/semmle/code/powershell/security/SqlInjectionCustomizations.qll +++ b/powershell/ql/lib/semmle/code/powershell/security/SqlInjectionCustomizations.qll @@ -79,8 +79,7 @@ module SqlInjection { override string getSinkType() { result = "call to Invoke-Sqlcmd" } override predicate allowImplicitRead(DataFlow::ContentSet cs) { - cs.getAStoreContent().(DataFlow::Content::KnownKeyContent).getIndex().asString().toLowerCase() = - query() + cs.getAStoreContent().(DataFlow::Content::KnownKeyContent).getIndex().stringMatches(query()) } } From 2fba40f89213a9d306a1c24252c5f3b321591669 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 15 Oct 2025 12:34:45 +0100 Subject: [PATCH 2/5] PS: Add a test demonstrating missing a variable. --- powershell/ql/test/library-tests/ast/Variables/test.ps1 | 5 +++++ .../ql/test/library-tests/ast/Variables/variables.expected | 1 + powershell/ql/test/library-tests/ast/Variables/variables.ql | 3 +++ 3 files changed, 9 insertions(+) create mode 100644 powershell/ql/test/library-tests/ast/Variables/test.ps1 create mode 100644 powershell/ql/test/library-tests/ast/Variables/variables.expected create mode 100644 powershell/ql/test/library-tests/ast/Variables/variables.ql diff --git a/powershell/ql/test/library-tests/ast/Variables/test.ps1 b/powershell/ql/test/library-tests/ast/Variables/test.ps1 new file mode 100644 index 000000000000..c4558f7f9d29 --- /dev/null +++ b/powershell/ql/test/library-tests/ast/Variables/test.ps1 @@ -0,0 +1,5 @@ +$x = 42 +$x + +[int]$y = 42 +$y \ No newline at end of file diff --git a/powershell/ql/test/library-tests/ast/Variables/variables.expected b/powershell/ql/test/library-tests/ast/Variables/variables.expected new file mode 100644 index 000000000000..7b149853650a --- /dev/null +++ b/powershell/ql/test/library-tests/ast/Variables/variables.expected @@ -0,0 +1 @@ +| test.ps1:1:1:1:2 | x | test.ps1:2:1:2:2 | x | diff --git a/powershell/ql/test/library-tests/ast/Variables/variables.ql b/powershell/ql/test/library-tests/ast/Variables/variables.ql new file mode 100644 index 000000000000..f1e676ad7195 --- /dev/null +++ b/powershell/ql/test/library-tests/ast/Variables/variables.ql @@ -0,0 +1,3 @@ +import powershell + +query predicate variables(Variable v, VarReadAccess va) { va.getVariable() = v } From 294af54e27ddf12cdc64f61ea6c8aa945c7214cb Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 15 Oct 2025 12:35:20 +0100 Subject: [PATCH 3/5] PS: Autoformat. --- .../ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll b/powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll index dc2ec0858a38..9bcf170b772a 100644 --- a/powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll +++ b/powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll @@ -193,7 +193,9 @@ private module EnvironmentVariableAccessSynth { ) } - private predicate envVarAccess(Raw::Ast parent, ChildIndex i, Child child, Raw::VarAccess va, string var) { + private predicate envVarAccess( + Raw::Ast parent, ChildIndex i, Child child, Raw::VarAccess va, string var + ) { va = parent.getChild(toRawChildIndex(i)) and Raw::isEnvVariableAccess(va, var) and child = SynthChild(VarAccessSynthKind(TVariableSynth(_, EnvVar(var)))) From 6a7c1e9b68662dbd6a8650da0e50ce08d33f6f86 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 15 Oct 2025 12:37:27 +0100 Subject: [PATCH 4/5] PS: Ensure that variables whose only assignment is behind a conversion also generate AST variables. --- .../code/powershell/ast/internal/Variable.qll | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll b/powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll index 57537682fa4d..402de8684510 100644 --- a/powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll +++ b/powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll @@ -140,10 +140,22 @@ module Private { predicate explicitAssignment(Raw::Ast dest, Raw::Ast assignment) { assignment.(Raw::AssignStmt).getLeftHandSide() = dest or + exists(Raw::ConvertExpr convert | + convert.getExpr() = dest and + explicitAssignment(convert, assignment) + ) + or any(Synthesis s).explicitAssignment(dest, _, assignment) } - predicate implicitAssignment(Raw::Ast n) { any(Synthesis s).implicitAssignment(n, _) } + predicate implicitAssignment(Raw::Ast n) { + any(Synthesis s).implicitAssignment(n, _) + or + exists(Raw::ConvertExpr convert | + convert.getExpr() = n and + implicitAssignment(convert) + ) + } } private import Private From 0e3913989c5c3e4a3a4ef3d89cf2ba14f80a8e96 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 15 Oct 2025 12:38:21 +0100 Subject: [PATCH 5/5] PS: Accept test changes. --- .../ast/Variables/variables.expected | 1 + .../ql/test/library-tests/ast/parent.expected | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/powershell/ql/test/library-tests/ast/Variables/variables.expected b/powershell/ql/test/library-tests/ast/Variables/variables.expected index 7b149853650a..ebd238a5c011 100644 --- a/powershell/ql/test/library-tests/ast/Variables/variables.expected +++ b/powershell/ql/test/library-tests/ast/Variables/variables.expected @@ -1 +1,2 @@ | test.ps1:1:1:1:2 | x | test.ps1:2:1:2:2 | x | +| test.ps1:4:6:4:7 | y | test.ps1:5:1:5:2 | y | diff --git a/powershell/ql/test/library-tests/ast/parent.expected b/powershell/ql/test/library-tests/ast/parent.expected index 00622cf4c19c..50615ae0edac 100644 --- a/powershell/ql/test/library-tests/ast/parent.expected +++ b/powershell/ql/test/library-tests/ast/parent.expected @@ -451,3 +451,19 @@ | Strings/String.ps1:6:10:8:0 | '@\nkl | Strings/String.ps1:6:10:8:0 | Call to kl\n'@\n | | Strings/String.ps1:6:10:8:0 | Call to kl\n'@\n | Strings/String.ps1:6:10:8:0 | [Stmt] Call to kl\n'@\n | | Strings/String.ps1:6:10:8:0 | [Stmt] Call to kl\n'@\n | Strings/String.ps1:1:1:8:0 | {...} | +| Variables/test.ps1:1:1:1:2 | x | Variables/test.ps1:1:1:1:7 | ...=... | +| Variables/test.ps1:1:1:1:2 | x | Variables/test.ps1:1:1:5:2 | {...} | +| Variables/test.ps1:1:1:1:7 | ...=... | Variables/test.ps1:1:1:5:2 | {...} | +| Variables/test.ps1:1:1:5:2 | {...} | Variables/test.ps1:1:1:5:2 | toplevel function for test.ps1 | +| Variables/test.ps1:1:1:5:2 | {...} | Variables/test.ps1:1:1:5:2 | {...} | +| Variables/test.ps1:1:6:1:7 | 42 | Variables/test.ps1:1:1:1:7 | ...=... | +| Variables/test.ps1:2:1:2:2 | [Stmt] x | Variables/test.ps1:1:1:5:2 | {...} | +| Variables/test.ps1:2:1:2:2 | x | Variables/test.ps1:2:1:2:2 | [Stmt] x | +| Variables/test.ps1:4:1:4:5 | int | Variables/test.ps1:4:1:4:7 | [...]... | +| Variables/test.ps1:4:1:4:7 | [...]... | Variables/test.ps1:4:1:4:12 | ...=... | +| Variables/test.ps1:4:1:4:12 | ...=... | Variables/test.ps1:1:1:5:2 | {...} | +| Variables/test.ps1:4:6:4:7 | y | Variables/test.ps1:1:1:5:2 | {...} | +| Variables/test.ps1:4:6:4:7 | y | Variables/test.ps1:4:1:4:7 | [...]... | +| Variables/test.ps1:4:11:4:12 | 42 | Variables/test.ps1:4:1:4:12 | ...=... | +| Variables/test.ps1:5:1:5:2 | [Stmt] y | Variables/test.ps1:1:1:5:2 | {...} | +| Variables/test.ps1:5:1:5:2 | y | Variables/test.ps1:5:1:5:2 | [Stmt] y |