Skip to content

Commit 1342089

Browse files
committed
JS: Block flow into window.location
1 parent c9f2328 commit 1342089

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,14 @@ predicate clearsContent(Node n, ContentSet c) {
846846
// We implement this rule by clearing any captured-content before storing into another captured-content.
847847
VariableCaptureOutput::storeStep(getClosureNode(n), _, _) and
848848
c = MkAnyCapturedContent()
849+
or
850+
// Block flow into the "window.location" property, as any assignment/mutation to this causes a page load and stops execution.
851+
// The use of clearsContent here ensures we also block assignments like `window.location.href = ...`
852+
exists(DataFlow::PropRef ref |
853+
ref = DataFlow::globalObjectRef().getAPropertyReference("location") and
854+
n = ref.getBase().getPostUpdateNode() and
855+
c = ContentSet::property("location")
856+
)
849857
}
850858

851859
/**

javascript/ql/test/library-tests/InterProceduralFlow/global.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ function g(x) {
99
let sink1 = g(source1);
1010
let sink2 = g(source2);
1111

12-
document.location = source1; // should not flow to `global2.js` in spite of assignment
12+
document.someProp = source1; // should not flow to `global2.js` in spite of assignment
1313
// `document = {}` in `fake-document.js`
1414

15-
window.location = source1;
15+
window.someProp = source1;
1616
let win = window;
17-
let sink3 = window.location;
18-
let sink4 = win.location;
19-
let sink5 = location;
17+
let sink3 = window.someProp;
18+
let sink4 = win.someProp;
19+
let sink5 = someProp;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
let remote_sink = source1;
2-
let other_remote_sink = document.location;
2+
let other_remote_sink = document.someProp;

0 commit comments

Comments
 (0)