Skip to content

Commit 435ee53

Browse files
authored
Merge pull request #87 from microsoft/powershell-port-injection-query
PS: Port `powershell/command-injection` from the internal repo
2 parents 2fe3cee + 105e19e commit 435ee53

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* @name Command Injection
3+
* @description Variable expression executed as command
4+
* @kind problem
5+
* @id powershell/tainted-command
6+
* @problem.severity warning
7+
* @precision low
8+
* @tags security
9+
*/
10+
11+
import powershell
12+
13+
predicate containsScope(VarAccess outer, VarAccess inner) {
14+
outer.getUserPath() = inner.getUserPath() and
15+
outer != inner
16+
}
17+
18+
predicate constantTernaryExpression(ConditionalExpr ternary) {
19+
onlyConstantExpressions(ternary.getIfTrue()) and onlyConstantExpressions(ternary.getIfFalse())
20+
}
21+
22+
predicate constantBinaryExpression(BinaryExpr binary) {
23+
onlyConstantExpressions(binary.getLeft()) and onlyConstantExpressions(binary.getRight())
24+
}
25+
26+
predicate onlyConstantExpressions(Expr expr){
27+
expr instanceof StringConstExpression or constantBinaryExpression(expr) or constantTernaryExpression(expr)
28+
}
29+
30+
VarAccess getNonConstantVariableAssignment(VarAccess varexpr) {
31+
(
32+
exists(AssignStmt assignment |
33+
not onlyConstantExpressions(assignment.getRightHandSide().(CmdExpr).getExpr()) and
34+
result = assignment.getLeftHandSide()
35+
)
36+
) and
37+
containsScope(result, varexpr)
38+
}
39+
40+
VarAccess getParameterWithVariableScope(VarAccess varexpr) {
41+
exists(Parameter parameter |
42+
result = parameter.getName() and
43+
containsScope(result, varexpr)
44+
)
45+
}
46+
47+
Expr getAllSubExpressions(Expr expr)
48+
{
49+
result = expr or
50+
result = getAllSubExpressions(expr.(ArrayLiteral).getAnElement()) or
51+
result = getAllSubExpressions(expr.(ArrayExpr).getStatementBlock().getAStatement().(Pipeline).getAComponent().(CmdExpr).getExpr())
52+
}
53+
54+
Expr dangerousCommandElement(Cmd command)
55+
{
56+
(
57+
command.getKind() = 28 or
58+
command.getName() = "Invoke-Expression"
59+
) and
60+
result = getAllSubExpressions(command.getAnElement())
61+
}
62+
63+
from Expr commandarg, VarAccess unknownDeclaration
64+
where
65+
exists(Cmd command |
66+
(
67+
unknownDeclaration = getNonConstantVariableAssignment(commandarg) or
68+
unknownDeclaration = getParameterWithVariableScope(commandarg)
69+
)
70+
and
71+
commandarg = dangerousCommandElement(command)
72+
)
73+
select commandarg.(VarAccess).getLocation(), "Unsafe flow to command argument from $@.",
74+
unknownDeclaration, unknownDeclaration.getUserPath()

powershell/ql/src/qlpack.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: microsoft-sdl/powershell-queries
2+
version: 0.0.1
3+
groups:
4+
- powershell
5+
- microsoft-all
6+
- queries
7+
extractor: powershell
8+
dependencies:
9+
microsoft-sdl/powershell-all: ${workspace}
10+
codeql/suite-helpers: ${workspace}
11+
warnOnImplicitThis: true

0 commit comments

Comments
 (0)