4
4
*/
5
5
6
6
import csharp
7
+ private import codeql.util.Unit
7
8
private import semmle.code.csharp.controlflow.Guards
8
9
private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks
9
10
private import semmle.code.csharp.security.dataflow.flowsources.FlowSources
@@ -26,21 +27,62 @@ abstract class Sink extends ApiSinkExprNode { }
26
27
*/
27
28
abstract class Sanitizer extends DataFlow:: ExprNode { }
28
29
30
+ /** A path normalization step. */
31
+ private class PathNormalizationStep extends Unit {
32
+ /**
33
+ * Holds if the flow step from `n1` to `n2` transforms the path into an
34
+ * absolute path.
35
+ *
36
+ * For example, the argument-to-return-value step through a call
37
+ * to `System.IO.Path.GetFullPath` is a normalization step.
38
+ */
39
+ abstract predicate isAdditionalFlowStep ( DataFlow:: Node n1 , DataFlow:: Node n2 ) ;
40
+ }
41
+
42
+ private class GetFullPathStep extends PathNormalizationStep {
43
+ override predicate isAdditionalFlowStep ( DataFlow:: Node n1 , DataFlow:: Node n2 ) {
44
+ exists ( Call call |
45
+ call .getARuntimeTarget ( ) .hasFullyQualifiedName ( "System.IO.Path" , "GetFullPath" ) and
46
+ n1 .asExpr ( ) = call .getArgument ( 0 ) and
47
+ n2 .asExpr ( ) = call
48
+ )
49
+ }
50
+ }
51
+
29
52
/**
30
53
* A taint-tracking configuration for uncontrolled data in path expression vulnerabilities.
31
54
*/
32
- private module TaintedPathConfig implements DataFlow:: ConfigSig {
33
- predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
55
+ private module TaintedPathConfig implements DataFlow:: StateConfigSig {
56
+ newtype FlowState =
57
+ additional NotNormalized ( ) or
58
+ additional Normalized ( )
34
59
35
- predicate isSink ( DataFlow:: Node sink ) { sink instanceof Sink }
60
+ predicate isSource ( DataFlow:: Node source , FlowState state ) {
61
+ source instanceof Source and state = NotNormalized ( )
62
+ }
36
63
37
- predicate isBarrier ( DataFlow:: Node node ) { node instanceof Sanitizer }
64
+ predicate isSink ( DataFlow:: Node sink , FlowState state ) {
65
+ sink instanceof Sink and
66
+ exists ( state )
67
+ }
68
+
69
+ predicate isAdditionalFlowStep ( DataFlow:: Node n1 , FlowState s1 , DataFlow:: Node n2 , FlowState s2 ) {
70
+ any ( PathNormalizationStep step ) .isAdditionalFlowStep ( n1 , n2 ) and
71
+ s1 = NotNormalized ( ) and
72
+ s2 = Normalized ( )
73
+ }
74
+
75
+ predicate isBarrier ( DataFlow:: Node node , FlowState state ) { node .( Sanitizer ) .isBarrier ( state ) }
76
+
77
+ predicate isBarrierOut ( DataFlow:: Node node , FlowState state ) {
78
+ isAdditionalFlowStep ( node , state , _, _)
79
+ }
38
80
}
39
81
40
82
/**
41
83
* A taint-tracking module for uncontrolled data in path expression vulnerabilities.
42
84
*/
43
- module TaintedPath = TaintTracking:: Global < TaintedPathConfig > ;
85
+ module TaintedPath = TaintTracking:: GlobalWithState < TaintedPathConfig > ;
44
86
45
87
/**
46
88
* DEPRECATED: Use `ThreatModelSource` instead.
0 commit comments