File tree Expand file tree Collapse file tree 6 files changed +43
-7
lines changed
lib/semmle/code/powershell
test/query-tests/security/cwe-078/CommandInjection Expand file tree Collapse file tree 6 files changed +43
-7
lines changed Original file line number Diff line number Diff line change @@ -76,14 +76,14 @@ class CmdCall extends CallExpr, TCmd {
7676class CallOperator extends CmdCall {
7777 CallOperator ( ) { getRawAst ( this ) instanceof Raw:: CallOperator }
7878
79- Expr getCommand ( ) { result = this .getArgument ( 0 ) }
79+ Expr getCommand ( ) { result = this .getCallee ( ) }
8080}
8181
8282/** A call to the dot-sourcing `.`. */
8383class DotSourcingOperator extends CmdCall {
8484 DotSourcingOperator ( ) { getRawAst ( this ) instanceof Raw:: DotSourcingOperator }
8585
86- Expr getPath ( ) { result = this .getArgument ( 0 ) }
86+ Expr getCommand ( ) { result = this .getCallee ( ) }
8787}
8888
8989class JoinPath extends CmdCall {
Original file line number Diff line number Diff line change @@ -605,7 +605,22 @@ module ExprNodes {
605605
606606 override CallOperator getExpr ( ) { result = e }
607607
608- ExprCfgNode getCommand ( ) { result = this .getArgument ( 0 ) }
608+ ExprCfgNode getCommand ( ) { result = this .getCallee ( ) }
609+ }
610+
611+ private class DotSourcingOperatorChildMapping extends CallExprChildMapping instanceof DotSourcingOperator
612+ {
613+ override predicate relevantChild ( Ast child ) { super .relevantChild ( child ) }
614+ }
615+
616+ class DotSourcingOperatorCfgNode extends CallExprCfgNode {
617+ override string getAPrimaryQlClass ( ) { result = "DotSourcingOperatorCfgNode" }
618+
619+ override DotSourcingOperatorChildMapping e ;
620+
621+ override DotSourcingOperator getExpr ( ) { result = e }
622+
623+ ExprCfgNode getCommand ( ) { result = this .getCallee ( ) }
609624 }
610625
611626 private class ToStringCallChildmapping extends CallExprChildMapping instanceof ToStringCall {
Original file line number Diff line number Diff line change @@ -540,11 +540,18 @@ class CallNode extends ExprNode {
540540 Node getCallee ( ) { result .asExpr ( ) = call .getCallee ( ) }
541541}
542542
543- /** A call to operator `&`, viwed as a node in a data flow graph. */
543+ /** A call to operator `&`, viewed as a node in a data flow graph. */
544544class CallOperatorNode extends CallNode {
545545 override CfgNodes:: ExprNodes:: CallOperatorCfgNode call ;
546546
547- Node getCommand ( ) { result .asExpr ( ) = call .getCommand ( ) } // TODO: Alternatively, we could remap calls to & as command expressions.
547+ Node getCommand ( ) { result .asExpr ( ) = call .getCommand ( ) }
548+ }
549+
550+ /** A call to operator `.`, viewed as a node in a data flow graph. */
551+ class DotSourcingOperatorNode extends CallNode {
552+ override CfgNodes:: ExprNodes:: DotSourcingOperatorCfgNode call ;
553+
554+ Node getCommand ( ) { result .asExpr ( ) = call .getCommand ( ) }
548555}
549556
550557/**
Original file line number Diff line number Diff line change @@ -46,8 +46,10 @@ module CommandInjection {
4646 call .getAnArgument ( ) = this
4747 )
4848 or
49- // Or the call command itself in case it's a use of operator &.
49+ // Or the call command itself in case it's a use of " operator &" or "operator ." .
5050 any ( DataFlow:: CallOperatorNode call ) .getCommand ( ) = this
51+ or
52+ any ( DataFlow:: DotSourcingOperatorNode call ) .getCommand ( ) = this
5153 }
5254
5355 override string getSinkType ( ) { result = "call to Invoke-Expression" }
Original file line number Diff line number Diff line change 5353| test.ps1:170:36:170:41 | input | test.ps1:129:11:129:20 | userinput | provenance | |
5454| test.ps1:172:42:172:47 | input | test.ps1:136:11:136:20 | userinput | provenance | |
5555| test.ps1:173:42:173:47 | input | test.ps1:144:11:144:20 | userinput | provenance | |
56+ | test.ps1:214:10:214:32 | Call to read-host | test.ps1:217:7:217:10 | $o | provenance | Src:MaD:0 |
5657nodes
5758| test.ps1:3:11:3:20 | userinput | semmle.label | userinput |
5859| test.ps1:4:23:4:52 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
@@ -109,6 +110,8 @@ nodes
109110| test.ps1:170:36:170:41 | input | semmle.label | input |
110111| test.ps1:172:42:172:47 | input | semmle.label | input |
111112| test.ps1:173:42:173:47 | input | semmle.label | input |
113+ | test.ps1:214:10:214:32 | Call to read-host | semmle.label | Call to read-host |
114+ | test.ps1:217:7:217:10 | $o | semmle.label | $o |
112115subpaths
113116#select
114117| test.ps1:4:23:4:52 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to read-host | test.ps1:4:23:4:52 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to read-host | user-provided value |
@@ -129,3 +132,4 @@ subpaths
129132| test.ps1:131:28:131:37 | UserInput | test.ps1:152:10:152:32 | Call to read-host | test.ps1:131:28:131:37 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to read-host | user-provided value |
130133| test.ps1:139:50:139:59 | UserInput | test.ps1:152:10:152:32 | Call to read-host | test.ps1:139:50:139:59 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to read-host | user-provided value |
131134| test.ps1:147:63:147:72 | UserInput | test.ps1:152:10:152:32 | Call to read-host | test.ps1:147:63:147:72 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to read-host | user-provided value |
135+ | test.ps1:217:7:217:10 | $o | test.ps1:214:10:214:32 | Call to read-host | test.ps1:217:7:217:10 | $o | This command depends on a $@. | test.ps1:214:10:214:32 | Call to read-host | user-provided value |
Original file line number Diff line number Diff line change @@ -207,4 +207,12 @@ function Invoke-InvokeExpressionInjectionSafe4
207207Invoke-InvokeExpressionInjectionSafe1 - UserInput $input
208208Invoke-InvokeExpressionInjectionSafe2 - UserInput $input
209209Invoke-InvokeExpressionInjectionSafe3 - UserInput $input
210- Invoke-InvokeExpressionInjectionSafe4 - UserInput $input
210+ Invoke-InvokeExpressionInjectionSafe4 - UserInput $input
211+
212+ function false-positive-in-call-operator ($d )
213+ {
214+ $o = Read-Host " enter input"
215+ & unzip - o " $o " - d $d # GOOD
216+
217+ . " $o " # BAD
218+ }
You can’t perform that action at this time.
0 commit comments