Skip to content

Commit 8590042

Browse files
committed
JS: customizable window, document, DOM value
1 parent fe920ec commit 8590042

File tree

4 files changed

+85
-8
lines changed

4 files changed

+85
-8
lines changed

javascript/ql/src/semmle/javascript/DOM.qll

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,25 @@ module DOM {
284284
)
285285
}
286286

287+
module DomValueSource {
288+
/**
289+
* A data flow node that should be considered a source of DOM values.
290+
*/
291+
abstract class Range extends DataFlow::Node {}
292+
293+
private class DefaultRange extends Range {
294+
DefaultRange() {
295+
this.asExpr().(VarAccess).getVariable() instanceof DOMGlobalVariable or
296+
this = domValueRef().getAPropertyRead() or
297+
this = domElementCreationOrQuery() or
298+
this = domElementCollection()
299+
}
300+
}
301+
}
302+
287303
/** Gets a data flow node that refers directly to a value from the DOM. */
288304
DataFlow::SourceNode domValueSource() {
289-
result.asExpr().(VarAccess).getVariable() instanceof DOMGlobalVariable or
290-
result = domValueRef().getAPropertyRead() or
291-
result = domElementCreationOrQuery() or
292-
result = domElementCollection()
305+
result instanceof DomValueSource::Range
293306
}
294307

295308
/** Gets a data flow node that may refer to a value from the DOM. */
@@ -303,11 +316,26 @@ module DOM {
303316
/** Gets a data flow node that may refer to a value from the DOM. */
304317
DataFlow::SourceNode domValueRef() { result = domValueRef(DataFlow::TypeTracker::end()) }
305318

319+
module LocationSource {
320+
/**
321+
* A data flow node that should be considered a source of the DOM `location` object.
322+
*
323+
* Can be subclassed to add additional such nodes.
324+
*/
325+
abstract class Range extends DataFlow::Node {}
326+
327+
private class DefaultRange extends Range {
328+
DefaultRange() {
329+
this = domValueRef().getAPropertyRead("location")
330+
or
331+
this = DataFlow::globalVarRef("location")
332+
}
333+
}
334+
}
335+
306336
/** Gets a data flow node that directly refers to a DOM `location` object. */
307337
DataFlow::SourceNode locationSource() {
308-
result = domValueRef().getAPropertyRead("location")
309-
or
310-
result = DataFlow::globalVarRef("location")
338+
result instanceof LocationSource::Range
311339
}
312340

313341
/** Gets a reference to a DOM `location` object. */
@@ -321,12 +349,32 @@ module DOM {
321349
/** Gets a reference to a DOM `location` object. */
322350
DataFlow::SourceNode locationRef() { result = locationRef(DataFlow::TypeTracker::end()) }
323351

352+
module DocumentSource {
353+
/**
354+
* A data flow node that should be considered a source of the `document` object.
355+
*
356+
* Can be subclassed to add additional such nodes.
357+
*/
358+
abstract class Range extends DataFlow::Node {}
359+
360+
private class DefaultRange extends Range {
361+
DefaultRange() { this = DataFlow::globalVarRef("document") }
362+
}
363+
}
364+
365+
/**
366+
* Gets a direct reference to the `document` object.
367+
*/
368+
DataFlow::SourceNode documentSource() {
369+
result instanceof DocumentSource::Range
370+
}
371+
324372
/**
325373
* Gets a reference to the `document` object.
326374
*/
327375
private DataFlow::SourceNode documentRef(DataFlow::TypeTracker t) {
328376
t.start() and
329-
result = DataFlow::globalVarRef("document")
377+
result instanceof DocumentSource::Range
330378
or
331379
exists(DataFlow::TypeTracker t2 | result = documentRef(t2).track(t2, t))
332380
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
test_documentRef
2+
| customization.js:2:13:2:31 | customGetDocument() |
3+
test_locationRef
4+
test_domValueRef
5+
| customization.js:4:3:4:28 | doc.get ... 'test') |
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import javascript
2+
3+
class CustomDocument extends DOM::DocumentSource::Range, DataFlow::CallNode {
4+
CustomDocument() {
5+
getCalleeName() = "customGetDocument"
6+
}
7+
}
8+
9+
query DataFlow::Node test_documentRef() {
10+
result = DOM::documentRef()
11+
}
12+
13+
query DataFlow::Node test_locationRef() {
14+
result = DOM::locationRef()
15+
}
16+
17+
query DataFlow::Node test_domValueRef() {
18+
result = DOM::domValueRef()
19+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function test() {
2+
let doc = customGetDocument();
3+
doc.location;
4+
doc.getElementById('test');
5+
}

0 commit comments

Comments
 (0)