Skip to content

Commit d661f7f

Browse files
committed
Add Flow Labels
1 parent acac534 commit d661f7f

File tree

3 files changed

+89
-36
lines changed

3 files changed

+89
-36
lines changed

javascript/ql/lib/semmle/javascript/security/dataflow/CorsPermissiveConfigurationCustomizations.qll

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,28 @@ module CorsPermissiveConfiguration {
2828
RemoteFlowSourceAsSource() { not this instanceof ClientSideRemoteFlowSource }
2929
}
3030

31-
/** An overfly permissive value for `origin` */
32-
class BadValues extends Source {
33-
BadValues() { this.mayHaveBooleanValue(true) or this.asExpr() instanceof NullLiteral }
31+
/** A flow label representing `true` and `null` values. */
32+
abstract class TrueAndNull extends DataFlow::FlowLabel {
33+
TrueAndNull() { this = "TrueAndNull" }
34+
}
35+
36+
TrueAndNull truenullLabel() { any() }
37+
38+
/** A flow label representing `*` value. */
39+
abstract class Wildcard extends DataFlow::FlowLabel {
40+
Wildcard() { this = "Wildcard" }
41+
}
42+
43+
Wildcard wildcardLabel() { any() }
44+
45+
/** An overly permissive value for `origin` (Apollo) */
46+
class TrueNullValue extends Source {
47+
TrueNullValue() { this.mayHaveBooleanValue(true) or this.asExpr() instanceof NullLiteral }
48+
}
49+
50+
/** An overly permissive value for `origin` (Express) */
51+
class WildcardValue extends Source {
52+
WildcardValue() { this.mayHaveStringValue("*") }
3453
}
3554

3655
/**

javascript/ql/lib/semmle/javascript/security/dataflow/CorsPermissiveConfigurationQuery.qll

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,30 @@ import CorsPermissiveConfigurationCustomizations::CorsPermissiveConfiguration
1717
class Configuration extends TaintTracking::Configuration {
1818
Configuration() { this = "CorsPermissiveConfiguration" }
1919

20-
override predicate isSource(DataFlow::Node source) { source instanceof Source }
20+
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
21+
source instanceof TrueNullValue and label = truenullLabel()
22+
or
23+
source instanceof WildcardValue and label = wildcardLabel()
24+
or
25+
source instanceof RemoteFlowSource and label = DataFlow::FlowLabel::taint()
26+
}
2127

22-
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
28+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
29+
sink instanceof CorsApolloServer and label = [DataFlow::FlowLabel::taint(), truenullLabel()]
30+
or
31+
sink instanceof ExpressCors and label = [DataFlow::FlowLabel::taint(), wildcardLabel()]
32+
}
2333

2434
override predicate isSanitizer(DataFlow::Node node) {
2535
super.isSanitizer(node) or
2636
node instanceof Sanitizer
2737
}
2838
}
39+
40+
private class WildcardActivated extends DataFlow::FlowLabel, Wildcard {
41+
WildcardActivated() { this = this }
42+
}
43+
44+
private class TrueAndNullActivated extends DataFlow::FlowLabel, TrueAndNull {
45+
TrueAndNullActivated() { this = this }
46+
}
Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,50 @@
11
nodes
2-
| tst.js:8:9:8:59 | user_origin |
3-
| tst.js:8:23:8:46 | url.par ... , true) |
4-
| tst.js:8:23:8:52 | url.par ... ).query |
5-
| tst.js:8:23:8:59 | url.par ... .origin |
6-
| tst.js:8:33:8:39 | req.url |
7-
| tst.js:8:33:8:39 | req.url |
8-
| tst.js:8:42:8:45 | true |
9-
| tst.js:8:42:8:45 | true |
10-
| tst.js:11:25:11:28 | true |
11-
| tst.js:11:25:11:28 | true |
12-
| tst.js:11:25:11:28 | true |
13-
| tst.js:21:25:21:28 | null |
14-
| tst.js:21:25:21:28 | null |
15-
| tst.js:21:25:21:28 | null |
16-
| tst.js:26:25:26:35 | user_origin |
17-
| tst.js:26:25:26:35 | user_origin |
2+
| apollo-test.js:8:9:8:59 | user_origin |
3+
| apollo-test.js:8:23:8:46 | url.par ... , true) |
4+
| apollo-test.js:8:23:8:52 | url.par ... ).query |
5+
| apollo-test.js:8:23:8:59 | url.par ... .origin |
6+
| apollo-test.js:8:33:8:39 | req.url |
7+
| apollo-test.js:8:33:8:39 | req.url |
8+
| apollo-test.js:11:25:11:28 | true |
9+
| apollo-test.js:11:25:11:28 | true |
10+
| apollo-test.js:11:25:11:28 | true |
11+
| apollo-test.js:21:25:21:28 | null |
12+
| apollo-test.js:21:25:21:28 | null |
13+
| apollo-test.js:21:25:21:28 | null |
14+
| apollo-test.js:26:25:26:35 | user_origin |
15+
| apollo-test.js:26:25:26:35 | user_origin |
16+
| express-test.js:10:9:10:59 | user_origin |
17+
| express-test.js:10:23:10:46 | url.par ... , true) |
18+
| express-test.js:10:23:10:52 | url.par ... ).query |
19+
| express-test.js:10:23:10:59 | url.par ... .origin |
20+
| express-test.js:10:33:10:39 | req.url |
21+
| express-test.js:10:33:10:39 | req.url |
22+
| express-test.js:26:17:26:19 | '*' |
23+
| express-test.js:26:17:26:19 | '*' |
24+
| express-test.js:26:17:26:19 | '*' |
25+
| express-test.js:33:17:33:27 | user_origin |
26+
| express-test.js:33:17:33:27 | user_origin |
1827
edges
19-
| tst.js:8:9:8:59 | user_origin | tst.js:26:25:26:35 | user_origin |
20-
| tst.js:8:9:8:59 | user_origin | tst.js:26:25:26:35 | user_origin |
21-
| tst.js:8:23:8:46 | url.par ... , true) | tst.js:8:23:8:52 | url.par ... ).query |
22-
| tst.js:8:23:8:52 | url.par ... ).query | tst.js:8:23:8:59 | url.par ... .origin |
23-
| tst.js:8:23:8:59 | url.par ... .origin | tst.js:8:9:8:59 | user_origin |
24-
| tst.js:8:33:8:39 | req.url | tst.js:8:23:8:46 | url.par ... , true) |
25-
| tst.js:8:33:8:39 | req.url | tst.js:8:23:8:46 | url.par ... , true) |
26-
| tst.js:8:42:8:45 | true | tst.js:8:23:8:46 | url.par ... , true) |
27-
| tst.js:8:42:8:45 | true | tst.js:8:23:8:46 | url.par ... , true) |
28-
| tst.js:11:25:11:28 | true | tst.js:11:25:11:28 | true |
29-
| tst.js:21:25:21:28 | null | tst.js:21:25:21:28 | null |
28+
| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin |
29+
| apollo-test.js:8:9:8:59 | user_origin | apollo-test.js:26:25:26:35 | user_origin |
30+
| apollo-test.js:8:23:8:46 | url.par ... , true) | apollo-test.js:8:23:8:52 | url.par ... ).query |
31+
| apollo-test.js:8:23:8:52 | url.par ... ).query | apollo-test.js:8:23:8:59 | url.par ... .origin |
32+
| apollo-test.js:8:23:8:59 | url.par ... .origin | apollo-test.js:8:9:8:59 | user_origin |
33+
| apollo-test.js:8:33:8:39 | req.url | apollo-test.js:8:23:8:46 | url.par ... , true) |
34+
| apollo-test.js:8:33:8:39 | req.url | apollo-test.js:8:23:8:46 | url.par ... , true) |
35+
| apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true |
36+
| apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null |
37+
| express-test.js:10:9:10:59 | user_origin | express-test.js:33:17:33:27 | user_origin |
38+
| express-test.js:10:9:10:59 | user_origin | express-test.js:33:17:33:27 | user_origin |
39+
| express-test.js:10:23:10:46 | url.par ... , true) | express-test.js:10:23:10:52 | url.par ... ).query |
40+
| express-test.js:10:23:10:52 | url.par ... ).query | express-test.js:10:23:10:59 | url.par ... .origin |
41+
| express-test.js:10:23:10:59 | url.par ... .origin | express-test.js:10:9:10:59 | user_origin |
42+
| express-test.js:10:33:10:39 | req.url | express-test.js:10:23:10:46 | url.par ... , true) |
43+
| express-test.js:10:33:10:39 | req.url | express-test.js:10:23:10:46 | url.par ... , true) |
44+
| express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' |
3045
#select
31-
| tst.js:11:25:11:28 | true | tst.js:11:25:11:28 | true | tst.js:11:25:11:28 | true | CORS Origin misconfiguration due to a $@. | tst.js:11:25:11:28 | true | too permissive or user controlled value |
32-
| tst.js:21:25:21:28 | null | tst.js:21:25:21:28 | null | tst.js:21:25:21:28 | null | CORS Origin misconfiguration due to a $@. | tst.js:21:25:21:28 | null | too permissive or user controlled value |
33-
| tst.js:26:25:26:35 | user_origin | tst.js:8:33:8:39 | req.url | tst.js:26:25:26:35 | user_origin | CORS Origin misconfiguration due to a $@. | tst.js:8:33:8:39 | req.url | too permissive or user controlled value |
34-
| tst.js:26:25:26:35 | user_origin | tst.js:8:42:8:45 | true | tst.js:26:25:26:35 | user_origin | CORS Origin misconfiguration due to a $@. | tst.js:8:42:8:45 | true | too permissive or user controlled value |
46+
| apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true | apollo-test.js:11:25:11:28 | true | CORS Origin misconfiguration due to a $@. | apollo-test.js:11:25:11:28 | true | too permissive or user controlled value |
47+
| apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null | apollo-test.js:21:25:21:28 | null | CORS Origin misconfiguration due to a $@. | apollo-test.js:21:25:21:28 | null | too permissive or user controlled value |
48+
| apollo-test.js:26:25:26:35 | user_origin | apollo-test.js:8:33:8:39 | req.url | apollo-test.js:26:25:26:35 | user_origin | CORS Origin misconfiguration due to a $@. | apollo-test.js:8:33:8:39 | req.url | too permissive or user controlled value |
49+
| express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' | express-test.js:26:17:26:19 | '*' | CORS Origin misconfiguration due to a $@. | express-test.js:26:17:26:19 | '*' | too permissive or user controlled value |
50+
| express-test.js:33:17:33:27 | user_origin | express-test.js:10:33:10:39 | req.url | express-test.js:33:17:33:27 | user_origin | CORS Origin misconfiguration due to a $@. | express-test.js:10:33:10:39 | req.url | too permissive or user controlled value |

0 commit comments

Comments
 (0)