Merge pull request #137 from microsoft/powershell-taint-through-string-interpolation

PS: Taint-flow through string interpolation
This commit is contained in:
Mathias Vorreiter Pedersen
2024-11-08 17:06:23 +01:00
committed by GitHub
6 changed files with 57 additions and 12 deletions

View File

@@ -565,6 +565,22 @@ module ExprNodes {
final ExprCfgNode getAnOperand() { e.hasCfgChild(this.getExpr().getAnOperand(), this, result) }
}
class ExpandableStringChildMappinig extends ExprChildMapping, ExpandableStringExpr {
override predicate relevantChild(Ast n) { n = this.getAnExpr() }
}
class ExpandableStringCfgNode extends ExprCfgNode {
override string getAPrimaryQlClass() { result = "ExpandableStringCfgNode" }
override ExpandableStringChildMappinig e;
override ExpandableStringExpr getExpr() { result = e }
ExprCfgNode getExpr(int i) { e.hasCfgChild(e.getExpr(i), this, result) }
ExprCfgNode getAnExpr() { result = this.getExpr(_) }
}
}
module StmtNodes {

View File

@@ -469,7 +469,9 @@ class CallNode extends AstNode {
/** A call to operator `&`, viwed as a node in a data flow graph. */
class CallOperatorNode extends CallNode {
CallOperatorNode() { this.getCallNode() instanceof CfgNodes::StmtNodes::CallOperatorCfgNode }
override CfgNodes::StmtNodes::CallOperatorCfgNode call;
Node getCommand() { result.asExpr() = call.getCommand() }
}
/** A use of a type name, viewed as a node in a data flow graph. */

View File

@@ -34,11 +34,18 @@ private module Cached {
cached
predicate defaultAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, string model) {
(
// Flow from an operand to an operation
exists(CfgNodes::ExprNodes::OperationCfgNode op |
op = nodeTo.asExpr() and
op.getAnOperand() = nodeFrom.asExpr()
)
or
// Flow through string interpolation
exists(CfgNodes::ExprNodes::ExpandableStringCfgNode es |
nodeFrom.asExpr() = es.getAnExpr() and
nodeTo.asExpr() = es
)
or
// Although flow through collections is modeled precisely using stores/reads, we still
// allow flow out of a _tainted_ collection. This is needed in order to support taint-
// tracking configurations where the source is a collection.

View File

@@ -3,7 +3,7 @@
| test.ps1:1:7:1:13 | call to Source | test.ps1:1:1:1:13 | ...=... |
| test.ps1:2:1:2:9 | call to Sink | test.ps1:2:1:2:9 | pre-return value for call to Sink |
| test.ps1:2:1:2:9 | call to Sink | test.ps1:2:1:2:9 | pre-return value for call to Sink |
| test.ps1:2:1:2:9 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:2:1:2:9 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:2:1:2:9 | pre-return value for call to Sink | test.ps1:2:1:2:9 | implicit unwrapping of call to Sink |
| test.ps1:4:1:4:3 | b | test.ps1:5:4:5:6 | b |
| test.ps1:4:6:4:13 | call to GetBool | test.ps1:4:1:4:3 | b |
@@ -14,7 +14,7 @@
| test.ps1:6:11:6:17 | call to Source | test.ps1:6:5:6:17 | ...=... |
| test.ps1:8:1:8:9 | call to Sink | test.ps1:8:1:8:9 | pre-return value for call to Sink |
| test.ps1:8:1:8:9 | call to Sink | test.ps1:8:1:8:9 | pre-return value for call to Sink |
| test.ps1:8:1:8:9 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:8:1:8:9 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:8:1:8:9 | pre-return value for call to Sink | test.ps1:8:1:8:9 | implicit unwrapping of call to Sink |
| test.ps1:10:1:10:3 | c | test.ps1:11:6:11:8 | c |
| test.ps1:10:6:10:16 | [...]... | test.ps1:10:1:10:3 | c |
@@ -23,7 +23,7 @@
| test.ps1:10:14:10:16 | b | test.ps1:10:6:10:16 | [...]... |
| test.ps1:11:1:11:8 | call to Sink | test.ps1:11:1:11:8 | pre-return value for call to Sink |
| test.ps1:11:1:11:8 | call to Sink | test.ps1:11:1:11:8 | pre-return value for call to Sink |
| test.ps1:11:1:11:8 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:11:1:11:8 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:11:1:11:8 | pre-return value for call to Sink | test.ps1:11:1:11:8 | implicit unwrapping of call to Sink |
| test.ps1:11:6:11:8 | [post] c | test.ps1:13:7:13:9 | c |
| test.ps1:11:6:11:8 | c | test.ps1:13:7:13:9 | c |
@@ -35,7 +35,7 @@
| test.ps1:13:7:13:9 | c | test.ps1:13:7:13:9 | c |
| test.ps1:14:1:14:8 | call to Sink | test.ps1:14:1:14:8 | pre-return value for call to Sink |
| test.ps1:14:1:14:8 | call to Sink | test.ps1:14:1:14:8 | pre-return value for call to Sink |
| test.ps1:14:1:14:8 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:14:1:14:8 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:14:1:14:8 | pre-return value for call to Sink | test.ps1:14:1:14:8 | implicit unwrapping of call to Sink |
| test.ps1:14:6:14:8 | [post] d | test.ps1:16:6:16:8 | d |
| test.ps1:14:6:14:8 | d | test.ps1:16:6:16:8 | d |
@@ -45,5 +45,12 @@
| test.ps1:16:6:16:12 | ...+... | test.ps1:16:6:16:12 | ...+... |
| test.ps1:17:1:17:8 | call to Sink | test.ps1:17:1:17:8 | pre-return value for call to Sink |
| test.ps1:17:1:17:8 | call to Sink | test.ps1:17:1:17:8 | pre-return value for call to Sink |
| test.ps1:17:1:17:8 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:17:1:17:8 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:17:1:17:8 | pre-return value for call to Sink | test.ps1:17:1:17:8 | implicit unwrapping of call to Sink |
| test.ps1:19:1:19:3 | f | test.ps1:21:25:21:27 | f |
| test.ps1:19:6:19:12 | call to Source | test.ps1:19:1:19:3 | f |
| test.ps1:19:6:19:12 | call to Source | test.ps1:19:1:19:12 | ...=... |
| test.ps1:21:1:21:28 | call to Sink | test.ps1:21:1:21:28 | pre-return value for call to Sink |
| test.ps1:21:1:21:28 | call to Sink | test.ps1:21:1:21:28 | pre-return value for call to Sink |
| test.ps1:21:1:21:28 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:21:1:21:28 | pre-return value for call to Sink | test.ps1:21:1:21:28 | implicit unwrapping of call to Sink |

View File

@@ -3,7 +3,7 @@
| test.ps1:1:7:1:13 | call to Source | test.ps1:1:1:1:13 | ...=... |
| test.ps1:2:1:2:9 | call to Sink | test.ps1:2:1:2:9 | pre-return value for call to Sink |
| test.ps1:2:1:2:9 | call to Sink | test.ps1:2:1:2:9 | pre-return value for call to Sink |
| test.ps1:2:1:2:9 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:2:1:2:9 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:2:1:2:9 | pre-return value for call to Sink | test.ps1:2:1:2:9 | implicit unwrapping of call to Sink |
| test.ps1:2:1:2:9 | pre-return value for call to Sink | test.ps1:2:1:2:9 | implicit unwrapping of call to Sink |
| test.ps1:4:1:4:3 | b | test.ps1:5:4:5:6 | b |
@@ -15,7 +15,7 @@
| test.ps1:6:11:6:17 | call to Source | test.ps1:6:5:6:17 | ...=... |
| test.ps1:8:1:8:9 | call to Sink | test.ps1:8:1:8:9 | pre-return value for call to Sink |
| test.ps1:8:1:8:9 | call to Sink | test.ps1:8:1:8:9 | pre-return value for call to Sink |
| test.ps1:8:1:8:9 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:8:1:8:9 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:8:1:8:9 | pre-return value for call to Sink | test.ps1:8:1:8:9 | implicit unwrapping of call to Sink |
| test.ps1:8:1:8:9 | pre-return value for call to Sink | test.ps1:8:1:8:9 | implicit unwrapping of call to Sink |
| test.ps1:10:1:10:3 | c | test.ps1:11:6:11:8 | c |
@@ -25,7 +25,7 @@
| test.ps1:10:14:10:16 | b | test.ps1:10:6:10:16 | [...]... |
| test.ps1:11:1:11:8 | call to Sink | test.ps1:11:1:11:8 | pre-return value for call to Sink |
| test.ps1:11:1:11:8 | call to Sink | test.ps1:11:1:11:8 | pre-return value for call to Sink |
| test.ps1:11:1:11:8 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:11:1:11:8 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:11:1:11:8 | pre-return value for call to Sink | test.ps1:11:1:11:8 | implicit unwrapping of call to Sink |
| test.ps1:11:1:11:8 | pre-return value for call to Sink | test.ps1:11:1:11:8 | implicit unwrapping of call to Sink |
| test.ps1:11:6:11:8 | [post] c | test.ps1:13:7:13:9 | c |
@@ -38,7 +38,7 @@
| test.ps1:13:7:13:9 | c | test.ps1:13:7:13:9 | c |
| test.ps1:14:1:14:8 | call to Sink | test.ps1:14:1:14:8 | pre-return value for call to Sink |
| test.ps1:14:1:14:8 | call to Sink | test.ps1:14:1:14:8 | pre-return value for call to Sink |
| test.ps1:14:1:14:8 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:14:1:14:8 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:14:1:14:8 | pre-return value for call to Sink | test.ps1:14:1:14:8 | implicit unwrapping of call to Sink |
| test.ps1:14:1:14:8 | pre-return value for call to Sink | test.ps1:14:1:14:8 | implicit unwrapping of call to Sink |
| test.ps1:14:6:14:8 | [post] d | test.ps1:16:6:16:8 | d |
@@ -51,6 +51,15 @@
| test.ps1:16:11:16:12 | 1 | test.ps1:16:6:16:12 | ...+... |
| test.ps1:17:1:17:8 | call to Sink | test.ps1:17:1:17:8 | pre-return value for call to Sink |
| test.ps1:17:1:17:8 | call to Sink | test.ps1:17:1:17:8 | pre-return value for call to Sink |
| test.ps1:17:1:17:8 | implicit unwrapping of call to Sink | test.ps1:1:1:17:8 | return value for test.ps1 |
| test.ps1:17:1:17:8 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:17:1:17:8 | pre-return value for call to Sink | test.ps1:17:1:17:8 | implicit unwrapping of call to Sink |
| test.ps1:17:1:17:8 | pre-return value for call to Sink | test.ps1:17:1:17:8 | implicit unwrapping of call to Sink |
| test.ps1:19:1:19:3 | f | test.ps1:21:25:21:27 | f |
| test.ps1:19:6:19:12 | call to Source | test.ps1:19:1:19:3 | f |
| test.ps1:19:6:19:12 | call to Source | test.ps1:19:1:19:12 | ...=... |
| test.ps1:21:1:21:28 | call to Sink | test.ps1:21:1:21:28 | pre-return value for call to Sink |
| test.ps1:21:1:21:28 | call to Sink | test.ps1:21:1:21:28 | pre-return value for call to Sink |
| test.ps1:21:1:21:28 | implicit unwrapping of call to Sink | test.ps1:1:1:21:28 | return value for test.ps1 |
| test.ps1:21:1:21:28 | pre-return value for call to Sink | test.ps1:21:1:21:28 | implicit unwrapping of call to Sink |
| test.ps1:21:1:21:28 | pre-return value for call to Sink | test.ps1:21:1:21:28 | implicit unwrapping of call to Sink |
| test.ps1:21:25:21:27 | f | test.ps1:21:6:21:28 | here is a string: $f |

View File

@@ -14,4 +14,8 @@ $d = ($c)
Sink $d
$e = $d + 1
Sink $e
Sink $e
$f = Source
Sink "here is a string: $f"