@@ -25,33 +25,17 @@ class Configuration extends TaintTracking::Configuration {
25
25
}
26
26
}
27
27
28
- /** TODO add comment */
29
- class TernaryOperatorSanitizerGuard extends TaintTracking:: SanitizerGuardNode {
30
- TaintTracking:: SanitizerGuardNode originalGuard ;
31
-
32
- TernaryOperatorSanitizerGuard ( ) {
33
- this .getAPredecessor + ( ) .asExpr ( ) .( BooleanLiteral ) .mayHaveBooleanValue ( false ) and
34
- this .getAPredecessor + ( ) = originalGuard and
35
- not this .asExpr ( ) instanceof LogicalBinaryExpr
36
- }
37
-
38
- override predicate sanitizes ( boolean outcome , Expr e ) {
39
- not this .asExpr ( ) instanceof LogNotExpr and
40
- originalGuard .sanitizes ( outcome , e )
41
- or
42
- exists ( boolean originalOutcome |
43
- this .asExpr ( ) instanceof LogNotExpr and
44
- originalGuard .sanitizes ( originalOutcome , e ) and
45
- (
46
- originalOutcome = true and outcome = false
47
- or
48
- originalOutcome = false and outcome = true
49
- )
50
- )
51
- }
52
- }
53
-
54
- /** TODO add comment */
28
+ /**
29
+ * This sanitizers models the next example:
30
+ * let valid = req.params.id ? Number.isInteger(req.params.id) : false
31
+ * if (valid) { sink(req.params.id) }
32
+ *
33
+ * This sanitizer models this way of using ternary operators,
34
+ * when the sanitizer guard is used as any of the branches
35
+ * instead of being used as the condition.
36
+ *
37
+ * This sanitizer sanitize the corresponding if statement branch.
38
+ */
55
39
class TernaryOperatorSanitizer extends RequestForgery:: Sanitizer {
56
40
TernaryOperatorSanitizer ( ) {
57
41
exists (
@@ -80,6 +64,45 @@ class TernaryOperatorSanitizer extends RequestForgery::Sanitizer {
80
64
}
81
65
}
82
66
67
+ /**
68
+ * This sanitizer guard is another way of modeling the example from above
69
+ * In this case:
70
+ * let valid = req.params.id ? Number.isInteger(req.params.id) : false
71
+ * if (!valid) { return }
72
+ * sink(req.params.id)
73
+ *
74
+ * The previous sanitizer is not enough,
75
+ * because we are sanitizing the entire if statement branch
76
+ * but we need to sanitize the use of this variable from now on.
77
+ *
78
+ * Thats why we model this sanitizer guard which says that
79
+ * the result of the ternary operator execution is a sanitizer guard.
80
+ */
81
+ class TernaryOperatorSanitizerGuard extends TaintTracking:: SanitizerGuardNode {
82
+ TaintTracking:: SanitizerGuardNode originalGuard ;
83
+
84
+ TernaryOperatorSanitizerGuard ( ) {
85
+ this .getAPredecessor + ( ) .asExpr ( ) .( BooleanLiteral ) .mayHaveBooleanValue ( false ) and
86
+ this .getAPredecessor + ( ) = originalGuard and
87
+ not this .asExpr ( ) instanceof LogicalBinaryExpr
88
+ }
89
+
90
+ override predicate sanitizes ( boolean outcome , Expr e ) {
91
+ not this .asExpr ( ) instanceof LogNotExpr and
92
+ originalGuard .sanitizes ( outcome , e )
93
+ or
94
+ exists ( boolean originalOutcome |
95
+ this .asExpr ( ) instanceof LogNotExpr and
96
+ originalGuard .sanitizes ( originalOutcome , e ) and
97
+ (
98
+ originalOutcome = true and outcome = false
99
+ or
100
+ originalOutcome = false and outcome = true
101
+ )
102
+ )
103
+ }
104
+ }
105
+
83
106
/**
84
107
* Number.isInteger is a sanitizer guard because a number can't be used to exploit a SSRF.
85
108
*/
0 commit comments