Skip to content

Commit 6ac9354

Browse files
committed
move logic to qlls
1 parent cb8496b commit 6ac9354

File tree

4 files changed

+95
-36
lines changed

4 files changed

+95
-36
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Provides default sources, sinks and sanitizers for reasoning about
3+
* unsafe deserialization vulnerabilities, as well as extension points for
4+
* adding your own.
5+
*/
6+
7+
private import semmle.code.powershell.dataflow.DataFlow
8+
import semmle.code.powershell.ApiGraphs
9+
private import semmle.code.powershell.dataflow.flowsources.FlowSources
10+
private import semmle.code.powershell.Cfg
11+
12+
module UnsafeDeserialization {
13+
/**
14+
* A data flow source for SQL-injection vulnerabilities.
15+
*/
16+
abstract class Source extends DataFlow::Node {
17+
/** Gets a string that describes the type of this flow source. */
18+
abstract string getSourceType();
19+
}
20+
21+
/**
22+
* A data flow sink for SQL-injection vulnerabilities.
23+
*/
24+
abstract class Sink extends DataFlow::Node {
25+
/** Gets a description of this sink. */
26+
abstract string getSinkType();
27+
28+
}
29+
30+
/**
31+
* A sanitizer for Unsafe Deserialization vulnerabilities.
32+
*/
33+
abstract class Sanitizer extends DataFlow::Node { }
34+
35+
/** A source of user input, considered as a flow source for unsafe deserialization. */
36+
class FlowSourceAsSource extends Source instanceof SourceNode {
37+
override string getSourceType() { result = SourceNode.super.getSourceType() }
38+
}
39+
40+
class BinaryFormatterDeserializeSink extends Sink {
41+
BinaryFormatterDeserializeSink() {
42+
exists(DataFlow::ObjectCreationNode ocn, DataFlow::CallNode cn |
43+
cn.getQualifier().getALocalSource() = ocn and
44+
ocn.getExprNode().getExpr().(CallExpr).getAnArgument().getValue().asString() = "System.Runtime.Serialization.Formatters.Binary.BinaryFormatter" and
45+
cn.getLowerCaseName() = "deserialize" and
46+
cn.getAnArgument() = this
47+
)
48+
}
49+
50+
override string getSinkType() { result = "call to BinaryFormatter.Deserialize" }
51+
52+
}
53+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Provides a taint tracking configuration for reasoning about
3+
* deserialization vulnerabilities (CWE-502).
4+
*
5+
* Note, for performance reasons: only import this file if
6+
* `UnsafeDeserializationFlow` is needed, otherwise
7+
* `UnsafeDeserializationCustomizations` should be imported instead.
8+
*/
9+
10+
import powershell
11+
import semmle.code.powershell.dataflow.flowsources.FlowSources
12+
import semmle.code.powershell.dataflow.DataFlow
13+
import semmle.code.powershell.dataflow.TaintTracking
14+
import UnsafeDeserializationCustomizations::UnsafeDeserialization
15+
16+
module Config implements DataFlow::ConfigSig {
17+
predicate isSource(DataFlow::Node source) { source instanceof Source }
18+
19+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
20+
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo){
21+
exists(InvokeMemberExpr ime |
22+
nodeTo.asExpr().getExpr() = ime and
23+
nodeFrom.asExpr().getExpr() = ime.getAnArgument()
24+
)
25+
}
26+
}
27+
28+
module UnsafeDeserializationFlow = TaintTracking::Global<Config>;

powershell/ql/src/queries/security/cwe-502/BinaryFormatterDeserialization.ql

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@
1212
*/
1313

1414
import powershell
15-
import semmle.code.powershell.dataflow.DataFlow
16-
import semmle.code.powershell.dataflow.TaintTracking
15+
import semmle.code.powershell.security.UnsafeDeserializationCustomizations::UnsafeDeserialization
1716

18-
from DataFlow::ObjectCreationNode source, DataFlow::CallNode cn
19-
where
20-
source.getExprNode().getExpr().(CallExpr).getAnArgument().getValue().asString() = "System.Runtime.Serialization.Formatters.Binary.BinaryFormatter" and
21-
cn.getQualifier().getALocalSource() = source and
22-
cn.getLowerCaseName() = "deserialize"
23-
select cn, "Call to BinaryFormatter.Deserialize"
17+
from BinaryFormatterDeserializeSink sink
18+
select sink, "Call to BinaryFormatter.Deserialize"

powershell/ql/src/queries/security/cwe-502/UnsafeDeserialization.ql

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name Unsafe deserializer
33
* @description Calling an unsafe deserializer with data controlled by an attacker
44
* can lead to denial of service and other security problems.
5-
* @kind problem
5+
* @kind path-problem
66
* @problem.severity error
77
* @security-severity 8.8
88
* @precision high
@@ -13,31 +13,14 @@
1313
*/
1414

1515
import powershell
16-
import semmle.code.powershell.dataflow.flowsources.FlowSources
17-
import semmle.code.powershell.dataflow.DataFlow
18-
import semmle.code.powershell.dataflow.TaintTracking
16+
import semmle.code.powershell.security.UnsafeDeserializationQuery
17+
import UnsafeDeserializationFlow::PathGraph
1918

20-
module DeserializationConfig implements DataFlow::ConfigSig {
21-
predicate isSource(DataFlow::Node source) { source instanceof SourceNode }
22-
23-
predicate isSink(DataFlow::Node sink) {
24-
exists(DataFlow::ObjectCreationNode ocn, DataFlow::CallNode cn |
25-
cn.getQualifier().getALocalSource() = ocn and
26-
ocn.getExprNode().getExpr().(CallExpr).getAnArgument().getValue().asString() = "System.Runtime.Serialization.Formatters.Binary.BinaryFormatter" and
27-
cn.getLowerCaseName() = "deserialize" and
28-
cn.getAnArgument() = sink
29-
)
30-
}
31-
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo){
32-
exists(InvokeMemberExpr ime |
33-
nodeTo.asExpr().getExpr() = ime and
34-
nodeFrom.asExpr().getExpr() = ime.getAnArgument()
35-
)
36-
}
37-
}
38-
39-
module DeserializationFlow = TaintTracking::Global<DeserializationConfig>;
40-
41-
from DataFlow::Node source, DataFlow::Node sink
42-
where DeserializationFlow::flow(source, sink)
43-
select sink, "Unsafe deserializer is used. Make sure the value being deserialized comes from a trusted source."
19+
from
20+
UnsafeDeserializationFlow::PathNode source, UnsafeDeserializationFlow::PathNode sink,
21+
Source sourceNode
22+
where
23+
UnsafeDeserializationFlow::flowPath(source, sink) and
24+
sourceNode = source.getNode()
25+
select sink.getNode(), source, sink, "This unsafe deserializer deserializes on a $@.", sourceNode,
26+
sourceNode.getSourceType()

0 commit comments

Comments
 (0)