Skip to content

Commit 2e05601

Browse files
committed
PS: Add matchesName and getAName to make it easier to match case insensitively.
1 parent 7360d80 commit 2e05601

File tree

15 files changed

+98
-52
lines changed

15 files changed

+98
-52
lines changed

powershell/ql/lib/semmle/code/powershell/ast/internal/Parameter.qll

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ private import AstImport
33
class Parameter extends Variable instanceof ParameterImpl {
44
string getLowerCaseName() { result = super.getLowerCaseNameImpl() }
55

6-
final predicate hasName(string name) { name = this.getName() }
6+
bindingset[name]
7+
pragma[inline_late]
8+
final predicate matchesName(string name) { this.getLowerCaseName() = name.toLowerCase() }
9+
10+
bindingset[result]
11+
pragma[inline_late]
12+
final string getAName() { result.toLowerCase() = this.getLowerCaseName() }
713

814
override Ast getChild(ChildIndex childIndex) {
915
result = Variable.super.getChild(childIndex)

powershell/ql/lib/semmle/code/powershell/ast/internal/Raw/Command.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ class Cmd extends @command, CmdBase {
3232
/** Gets the name of the command without any qualifiers. */
3333
string getLowerCaseName() { parseCommandName(this, _, result) }
3434

35+
bindingset[name]
36+
pragma[inline_late]
37+
final predicate matchesName(string name) { this.getLowerCaseName() = name.toLowerCase() }
38+
39+
bindingset[result]
40+
pragma[inline_late]
41+
final string getAName() { result.toLowerCase() = this.getLowerCaseName() }
42+
3543
/** Holds if the command is qualified. */
3644
predicate isQualified() { parseCommandName(this, any(string s | s != ""), _) }
3745

@@ -70,7 +78,7 @@ class Cmd extends @command, CmdBase {
7078
// sourcing operator) the 0'th element is not the command name, but
7179
// rather the thing to invoke. These all appear to be commands with
7280
// an empty string as the command name.
73-
this.getCommandName() = ""
81+
this.matchesName("")
7482
) and
7583
e = this.getElement(j) and
7684
(

powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ module Public {
149149

150150
final override string toString() { result = this.getLowerCaseName() }
151151

152+
bindingset[name]
153+
pragma[inline_late]
154+
final predicate matchesName(string name) { this.getLowerCaseName() = name.toLowerCase() }
155+
156+
bindingset[result]
157+
pragma[inline_late]
158+
final string getAName() { result.toLowerCase() = this.getLowerCaseName() }
159+
152160
final override Location getLocation() { result = super.getLocationImpl() }
153161

154162
Scope getDeclaringScope() { getRawAst(result) = super.getDeclaringScopeImpl() }

powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,14 @@ module ExprNodes {
542542

543543
predicate hasLowerCaseName(string name) { this.getLowerCaseName() = name }
544544

545+
bindingset[name]
546+
pragma[inline_late]
547+
final predicate matchesName(string name) { this.getLowerCaseName() = name.toLowerCase() }
548+
549+
bindingset[result]
550+
pragma[inline_late]
551+
final string getAName() { result.toLowerCase() = this.getLowerCaseName() }
552+
545553
/** Gets the i'th positional argument to this call. */
546554
ExprCfgNode getPositionalArgument(int i) {
547555
e.hasCfgChild(e.getPositionalArgument(i), this, result)
@@ -1043,6 +1051,14 @@ module ExprNodes {
10431051

10441052
string getLowerCaseName() { result = e.getLowerCaseName() }
10451053

1054+
bindingset[name]
1055+
pragma[inline_late]
1056+
final predicate matchesName(string name) { this.getLowerCaseName() = name.toLowerCase() }
1057+
1058+
bindingset[result]
1059+
pragma[inline_late]
1060+
final string getAName() { result.toLowerCase() = this.getLowerCaseName() }
1061+
10461062
int getPosition() { result = e.getPosition() }
10471063
}
10481064

powershell/ql/lib/semmle/code/powershell/controlflow/internal/Completion.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ private newtype TCompletion =
2424

2525
private predicate commandThrows(CallExpr c, boolean unconditional) {
2626
c.getNamedArgument("ErrorAction").getValue().asString() = "Stop" and
27-
if c.getName() = "Write-Error" then unconditional = true else unconditional = false
27+
if c.matchesName("Write-Error") then unconditional = true else unconditional = false
2828
}
2929

3030
pragma[noinline]

powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ class NamedSet extends NamedSet0 {
514514

515515
/** Gets a function that has a parameter for each name in this set. */
516516
Function getAFunction() {
517-
forex(string name | name = this.getAName() | result.getAParameter().hasName(name))
517+
forex(string name | name = this.getAName() | result.getAParameter().matchesName(name))
518518
or
519519
this.isEmpty() and
520520
exists(result)

powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPublic.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,14 @@ class CallNode extends ExprNode {
508508

509509
string getLowerCaseName() { result = call.getLowerCaseName() }
510510

511+
bindingset[name]
512+
pragma[inline_late]
513+
final predicate matchesName(string name) { this.getLowerCaseName() = name.toLowerCase() }
514+
515+
bindingset[result]
516+
pragma[inline_late]
517+
final string getAName() { result.toLowerCase() = this.getLowerCaseName() }
518+
511519
Node getQualifier() { result.asExpr() = call.getQualifier() }
512520

513521
/** Gets the i'th argument to this call. */

powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/EngineIntrinsics.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module EngineIntrinsics {
66
private class EngineIntrinsicsGlobalEntry extends ModelInput::TypeModel {
77
override DataFlow::Node getASource(string type) {
88
type = "System.Management.Automation.EngineIntrinsics" and
9-
result.asExpr().getExpr().(VarReadAccess).getVariable().getName().toLowerCase() = "executioncontext"
9+
result.asExpr().getExpr().(VarReadAccess).getVariable().matchesName("ExecutionContext")
1010
}
1111
}
1212
}

powershell/ql/lib/semmle/code/powershell/frameworks/data/internal/ApiGraphModelsSpecific.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ API::Node getExtraNodeFromPath(string type, AccessPath path, int n) {
6363
n = 1 and
6464
exists(string methodName, DataFlow::CallNode call |
6565
methodMatchedByName(path, methodName) and
66-
call.getName() = methodName and
66+
call.matchesName(methodName) and
6767
result.(API::MethodAccessNode).asCall() = call
6868
)
6969
}

powershell/ql/lib/semmle/code/powershell/security/CommandInjectionCustomizations.qll

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ module CommandInjection {
4242
SystemCommandExecutionSink() {
4343
// An argument to a call
4444
exists(DataFlow::CallNode call |
45-
call.getName() = ["Invoke-Expression", "iex"] and
45+
call.matchesName(["Invoke-Expression", "iex"]) and
4646
call.getAnArgument() = this
4747
)
4848
or
@@ -57,7 +57,7 @@ module CommandInjection {
5757
class AddTypeSink extends Sink {
5858
AddTypeSink() {
5959
exists(DataFlow::CallNode call |
60-
call.getName() = "Add-Type" and
60+
call.matchesName("Add-Type") and
6161
call.getAnArgument() = this
6262
)
6363
}
@@ -94,8 +94,8 @@ class AddScriptInvokeSink extends Sink {
9494
AddScriptInvokeSink() {
9595
exists(InvokeMemberExpr addscript, InvokeMemberExpr create |
9696
this.asExpr().getExpr() = addscript.getAnArgument() and
97-
addscript.getName() = "AddScript" and
98-
create.getName() = "Create" and
97+
addscript.matchesName("AddScript") and
98+
create.matchesName("Create") and
9999

100100
addscript.getQualifier().(InvokeMemberExpr) = create and
101101
create.getQualifier().(TypeNameExpr).getName() = "PowerShell"
@@ -109,7 +109,7 @@ class AddScriptInvokeSink extends Sink {
109109
class PowershellSink extends Sink {
110110
PowershellSink() {
111111
exists( CmdCall c |
112-
c.getName() = "powershell" |
112+
c.matchesName("powershell") |
113113
(
114114
this.asExpr().getExpr() = c.getArgument(1) and
115115
c.getArgument(0).getValue().asString() = "-command"
@@ -125,28 +125,28 @@ class PowershellSink extends Sink {
125125
}
126126

127127
class CmdSink extends Sink {
128-
CmdSink() {
129-
exists(CmdCall c |
130-
this.asExpr().getExpr() = c.getArgument(1) and
131-
c.getName() = "cmd" and
132-
c.getArgument(0).getValue().asString() = "/c"
133-
)
134-
}
135-
override string getSinkType(){
136-
result = "call to Cmd"
137-
}
128+
CmdSink() {
129+
exists(CmdCall c |
130+
this.asExpr().getExpr() = c.getArgument(1) and
131+
c.matchesName("cmd") and
132+
c.getArgument(0).getValue().asString() = "/c"
133+
)
134+
}
135+
override string getSinkType(){
136+
result = "call to Cmd"
137+
}
138138
}
139139

140140
class ForEachObjectSink extends Sink {
141-
ForEachObjectSink() {
142-
exists(CmdCall c |
143-
this.asExpr().getExpr() = c.getAnArgument() and
144-
c.getName() = "Foreach-Object"
145-
)
146-
}
147-
override string getSinkType(){
148-
result = "call to ForEach-Object"
149-
}
141+
ForEachObjectSink() {
142+
exists(CmdCall c |
143+
this.asExpr().getExpr() = c.getAnArgument() and
144+
c.matchesName("Foreach-Object")
145+
)
146+
}
147+
override string getSinkType(){
148+
result = "call to ForEach-Object"
149+
}
150150
}
151151

152152
class InvokeSink extends Sink {
@@ -162,17 +162,17 @@ class InvokeSink extends Sink {
162162
}
163163

164164
class CreateScriptBlockSink extends Sink {
165-
CreateScriptBlockSink() {
166-
exists(InvokeMemberExpr ie |
167-
this.asExpr().getExpr() = ie.getAnArgument() and
168-
ie.getName() = "Create" and
169-
ie.getQualifier().(TypeNameExpr).getName() = "ScriptBlock"
170-
)
171-
}
172-
override string getSinkType(){
173-
result = "call to CreateScriptBlock"
174-
}
175-
}
165+
CreateScriptBlockSink() {
166+
exists(InvokeMemberExpr ie |
167+
this.asExpr().getExpr() = ie.getAnArgument() and
168+
ie.matchesName("Create") and
169+
ie.getQualifier().(TypeNameExpr).getName() = "ScriptBlock"
170+
)
171+
}
172+
override string getSinkType(){
173+
result = "call to CreateScriptBlock"
174+
}
175+
}
176176

177177
class NewScriptBlockSink extends Sink {
178178
NewScriptBlockSink() {
@@ -219,12 +219,12 @@ class ExpandStringSink extends Sink {
219219
}
220220

221221
class SingleQuoteSanitizer extends Sanitizer {
222-
SingleQuoteSanitizer() {
223-
exists(ExpandableStringExpr e, VarReadAccess v |
224-
v = this.asExpr().getExpr() and
225-
e.getUnexpandedValue().toLowerCase().matches("%'$" + v.getVariable().getLowerCaseName() + "'%") and
226-
e.getAnExpr() = v
227-
)
222+
SingleQuoteSanitizer() {
223+
exists(ExpandableStringExpr e, VarReadAccess v |
224+
v = this.asExpr().getExpr() and
225+
e.getUnexpandedValue().toLowerCase().matches("%'$" + v.getVariable().getLowerCaseName() + "'%") and
226+
e.getAnExpr() = v
227+
)
228228
}
229229
}
230230
}

0 commit comments

Comments
 (0)