Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 017ae49

Browse files
author
Max Schaefer
committed
JavaScript: Use custom flow labels in ClientSideUrlRedirect.
1 parent f4ea8bc commit 017ae49

2 files changed

Lines changed: 34 additions & 40 deletions

File tree

javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirect.qll

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ module ClientSideUrlRedirect {
2323
*/
2424
abstract class Sanitizer extends DataFlow::Node { }
2525

26+
/**
27+
* A flow label for values that represent the URL of the current document, and
28+
* hence are only partially user-controlled.
29+
*/
30+
class DocumentUrl extends DataFlow::FlowLabel {
31+
DocumentUrl() { this = "document.url" }
32+
}
33+
2634
/**
2735
* A taint-tracking configuration for reasoning about unvalidated URL redirections.
2836
*/
@@ -35,24 +43,37 @@ module ClientSideUrlRedirect {
3543
source instanceof Source
3644
}
3745

46+
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) {
47+
source instanceof RemoteFlowSource and
48+
lbl = DataFlow::FlowLabel::taint()
49+
or
50+
isDocumentURL(source.asExpr()) and
51+
lbl instanceof DocumentUrl
52+
}
53+
3854
override predicate isSink(DataFlow::Node sink) {
3955
sink instanceof Sink
4056
}
4157

58+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel f) {
59+
sink instanceof UrlSink and
60+
f = DataFlow::FlowLabel::taint()
61+
}
62+
4263
override predicate isSanitizer(DataFlow::Node node) {
4364
super.isSanitizer(node) or
44-
isSafeLocationProperty(node.asExpr()) or
4565
node instanceof Sanitizer
4666
}
4767

4868
override predicate isSanitizer(DataFlow::Node source, DataFlow::Node sink) {
4969
sanitizingPrefixEdge(source, sink)
5070
}
51-
}
5271

53-
/** A source of remote user input, considered as a flow source for unvalidated URL redirects. */
54-
class RemoteFlowSourceAsSource extends Source {
55-
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
72+
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel f, DataFlow::FlowLabel g) {
73+
queryAccess(pred, succ) and
74+
f instanceof DocumentUrl and
75+
g = DataFlow::FlowLabel::taint()
76+
}
5677
}
5778

5879
/**
@@ -84,39 +105,13 @@ module ClientSideUrlRedirect {
84105
)
85106
}
86107

87-
/**
88-
* A taint tracking configuration for identifying accesses of the query string of the current URL.
89-
*/
90-
private class LocationHrefDataFlowConfiguration extends TaintTracking::Configuration {
91-
LocationHrefDataFlowConfiguration() {
92-
this = "LocationHrefDataFlowConfiguration"
93-
}
94-
95-
override predicate isSource(DataFlow::Node source) {
96-
isDocumentURL(source.asExpr())
97-
}
98-
99-
override predicate isSink(DataFlow::Node sink) {
100-
queryAccess(sink, _)
101-
}
102-
}
103-
104-
/**
105-
* An access of the query string of the current URL.
106-
*/
107-
class LocationSearchSource extends Source {
108-
LocationSearchSource() {
109-
exists(LocationHrefDataFlowConfiguration cfg, DataFlow::Node nd |
110-
cfg.hasFlow(_, nd) and
111-
queryAccess(nd, this)
112-
)
113-
}
108+
abstract class UrlSink extends DataFlow::Node {
114109
}
115110

116111
/**
117112
* A sink which is used to set the window location.
118113
*/
119-
class LocationSink extends Sink, DataFlow::ValueNode {
114+
class LocationSink extends UrlSink, DataFlow::ValueNode {
120115
LocationSink() {
121116
// A call to a `window.navigate` or `window.open`
122117
exists (string name |
@@ -157,7 +152,7 @@ module ClientSideUrlRedirect {
157152
/**
158153
* An expression that may be interpreted as the URL of a script.
159154
*/
160-
abstract class ScriptUrlSink extends Sink {
155+
abstract class ScriptUrlSink extends UrlSink {
161156
}
162157

163158
/**
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
| tst2.js:4:21:4:55 | href.su ... '?')+1) | Untrusted URL redirection due to $@. | tst2.js:4:21:4:55 | href.su ... '?')+1) | user-provided value |
1+
| tst2.js:4:21:4:55 | href.su ... '?')+1) | Untrusted URL redirection due to $@. | tst2.js:2:14:2:28 | window.location | user-provided value |
22
| tst6.js:4:21:4:28 | redirect | Untrusted URL redirection due to $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value |
33
| tst6.js:6:17:6:24 | redirect | Untrusted URL redirection due to $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value |
44
| tst6.js:8:21:8:56 | $locati ... + "foo" | Untrusted URL redirection due to $@. | tst6.js:8:21:8:48 | $locati ... irect') | user-provided value |
5-
| tst7.js:2:12:2:35 | documen ... .search | Untrusted URL redirection due to $@. | tst7.js:2:12:2:35 | documen ... .search | user-provided value |
6-
| tst7.js:5:27:5:50 | documen ... .search | Untrusted URL redirection due to $@. | tst7.js:5:27:5:50 | documen ... .search | user-provided value |
7-
| tst9.js:2:21:2:55 | documen ... ring(1) | Untrusted URL redirection due to $@. | tst9.js:2:21:2:42 | documen ... on.hash | user-provided value |
8-
| tst9.js:2:21:2:55 | documen ... ring(1) | Untrusted URL redirection due to $@. | tst9.js:2:21:2:55 | documen ... ring(1) | user-provided value |
9-
| tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:2:19:2:69 | /.*redi ... n.href) | user-provided value |
5+
| tst7.js:2:12:2:35 | documen ... .search | Untrusted URL redirection due to $@. | tst7.js:2:12:2:28 | document.location | user-provided value |
6+
| tst7.js:5:27:5:50 | documen ... .search | Untrusted URL redirection due to $@. | tst7.js:5:27:5:43 | document.location | user-provided value |
7+
| tst9.js:2:21:2:55 | documen ... ring(1) | Untrusted URL redirection due to $@. | tst9.js:2:21:2:37 | document.location | user-provided value |
8+
| tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:2:47:2:63 | document.location | user-provided value |

0 commit comments

Comments
 (0)