Skip to content

Commit 57ae070

Browse files
author
bananabr
committed
adds the Selection API as a new DOM text source
1 parent 811a2c0 commit 57ae070

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added the `Selection` api as a DOM text source in the `XssThroughDomCustomizations` library.

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,26 @@ module XssThroughDom {
216216
}
217217
}
218218
}
219+
220+
221+
/**
222+
* A source for text from the DOM from a Selection object toString method call
223+
* https://developer.mozilla.org/en-US/docs/Web/API/Selection
224+
*/
225+
DataFlow::SourceNode getSelectionCall(DataFlow::TypeTracker t) {
226+
t.start() and
227+
exists(DataFlow::CallNode call |
228+
call = DataFlow::globalVarRef("getSelection").getACall()
229+
|
230+
result = call
231+
)
232+
or
233+
exists(DataFlow::TypeTracker t2 | result = getSelectionCall(t2).track(t2, t))
234+
}
235+
236+
class SelectionSource extends Source {
237+
SelectionSource() {
238+
this = getSelectionCall(DataFlow::TypeTracker::end()).getAMethodCall("toString")
239+
}
240+
}
219241
}

javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ nodes
139139
| xss-through-dom.js:122:53:122:67 | ev.target.files |
140140
| xss-through-dom.js:122:53:122:67 | ev.target.files |
141141
| xss-through-dom.js:122:53:122:70 | ev.target.files[0] |
142+
| xss-through-dom.js:129:6:129:42 | linkText |
143+
| xss-through-dom.js:129:17:129:36 | selection.toString() |
144+
| xss-through-dom.js:129:17:129:36 | selection.toString() |
145+
| xss-through-dom.js:129:17:129:42 | selecti ... ) \|\| '' |
146+
| xss-through-dom.js:130:19:130:26 | linkText |
147+
| xss-through-dom.js:130:19:130:26 | linkText |
142148
edges
143149
| forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values |
144150
| forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values |
@@ -225,6 +231,11 @@ edges
225231
| xss-through-dom.js:122:53:122:67 | ev.target.files | xss-through-dom.js:122:53:122:70 | ev.target.files[0] |
226232
| xss-through-dom.js:122:53:122:70 | ev.target.files[0] | xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) |
227233
| xss-through-dom.js:122:53:122:70 | ev.target.files[0] | xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) |
234+
| xss-through-dom.js:129:6:129:42 | linkText | xss-through-dom.js:130:19:130:26 | linkText |
235+
| xss-through-dom.js:129:6:129:42 | linkText | xss-through-dom.js:130:19:130:26 | linkText |
236+
| xss-through-dom.js:129:17:129:36 | selection.toString() | xss-through-dom.js:129:17:129:42 | selecti ... ) \|\| '' |
237+
| xss-through-dom.js:129:17:129:36 | selection.toString() | xss-through-dom.js:129:17:129:42 | selecti ... ) \|\| '' |
238+
| xss-through-dom.js:129:17:129:42 | selecti ... ) \|\| '' | xss-through-dom.js:129:6:129:42 | linkText |
228239
#select
229240
| forms.js:9:31:9:40 | values.foo | forms.js:8:23:8:28 | values | forms.js:9:31:9:40 | values.foo | $@ is reinterpreted as HTML without escaping meta-characters. | forms.js:8:23:8:28 | values | DOM text |
230241
| forms.js:12:31:12:40 | values.bar | forms.js:11:24:11:29 | values | forms.js:12:31:12:40 | values.bar | $@ is reinterpreted as HTML without escaping meta-characters. | forms.js:11:24:11:29 | values | DOM text |
@@ -262,3 +273,4 @@ edges
262273
| xss-through-dom.js:115:16:115:18 | src | xss-through-dom.js:114:17:114:52 | documen ... k").src | xss-through-dom.js:115:16:115:18 | src | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:114:17:114:52 | documen ... k").src | DOM text |
263274
| xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | xss-through-dom.js:120:23:120:37 | ev.target.files | xss-through-dom.js:120:23:120:45 | ev.targ ... 0].name | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:120:23:120:37 | ev.target.files | DOM text |
264275
| xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | xss-through-dom.js:122:53:122:67 | ev.target.files | xss-through-dom.js:122:33:122:71 | URL.cre ... les[0]) | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:122:53:122:67 | ev.target.files | DOM text |
276+
| xss-through-dom.js:130:19:130:26 | linkText | xss-through-dom.js:129:17:129:36 | selection.toString() | xss-through-dom.js:130:19:130:26 | linkText | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:129:17:129:36 | selection.toString() | DOM text |

javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,11 @@ class Sub extends Super {
122122
$("img#id").attr("src", URL.createObjectURL(ev.target.files[0])); // NOT OK
123123
}
124124
})();
125+
126+
(function () {
127+
let elem = document.createElement('a');
128+
const selection = getSelection();
129+
let linkText = selection.toString() || '';
130+
elem.innerHTML = linkText; // NOT OK
131+
elem.innerText = linkText; // OK
132+
})();

0 commit comments

Comments
 (0)