Skip to content

Commit 4fdfbb7

Browse files
author
Max Schaefer
authored
Merge pull request #444 from esben-semmle/js/browser-based-client-requests
JS: add models of $.ajax, $.getJSON and XMLHttpRequst
2 parents cd874f7 + 37b7b39 commit 4fdfbb7

File tree

7 files changed

+67
-7
lines changed

7 files changed

+67
-7
lines changed

change-notes/1.19/analysis-javascript.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,20 @@
3030

3131
| **Query** | **Expected impact** | **Change** |
3232
|--------------------------------|----------------------------|----------------------------------------------|
33-
| Useless assignment to local variable | Fewer false-positive results | This rule now recognizes additional ways default values can be set. |
33+
| Client side cross-site scripting | More results | This rule now also flags HTML injection in the body of an email. |
34+
| Information exposure through a stack trace | More results | This rule now also flags cases where the entire exception object (including the stack trace) may be exposed. |
35+
| Missing CSRF middleware | Fewer false-positive results | This rule now recognizes additional CSRF protection middlewares. |
3436
| Regular expression injection | Fewer false-positive results | This rule now identifies calls to `String.prototype.search` with more precision. |
35-
| Unbound event handler receiver | Fewer false-positive results | This rule now recognizes additional ways class methods can be bound. |
3637
| Remote property injection | Fewer results | The precision of this rule has been revised to "medium". Results are no longer shown on LGTM by default. |
37-
| Missing CSRF middleware | Fewer false-positive results | This rule now recognizes additional CSRF protection middlewares. |
38+
| Self assignment | Fewer false-positive results | This rule now ignores self-assignments preceded by a JSDoc comment with a `@type` tag. |
3839
| Server-side URL redirect | More results | This rule now recognizes redirection calls in more cases. |
40+
| Unbound event handler receiver | Fewer false-positive results | This rule now recognizes additional ways class methods can be bound. |
41+
| Uncontrolled data used in remote request | More results | This rule now recognizes additional kinds of requests. |
42+
| Unused import | Fewer false-positive results | This rule no longer flags imports used by the `transform-react-jsx` Babel plugin. |
3943
| Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that may be used by `eval` calls. |
4044
| Unused variable, import, function or class | Fewer results | This rule now flags import statements with multiple unused imports once. |
45+
| Useless assignment to local variable | Fewer false-positive results | This rule now recognizes additional ways default values can be set. |
4146
| Whitespace contradicts operator precedence | Fewer false-positive results | This rule no longer flags operators with asymmetric whitespace. |
42-
| Unused import | Fewer false-positive results | This rule no longer flags imports used by the `transform-react-jsx` Babel plugin. |
43-
| Self assignment | Fewer false-positive results | This rule now ignores self-assignments preceded by a JSDoc comment with a `@type` tag. |
44-
| Client side cross-site scripting | More results | This rule now also flags HTML injection in the body of an email. |
45-
| Information exposure through a stack trace | More results | This rule now also flags cases where the entire exception object (including the stack trace) may be exposed. |
4647

4748
## Changes to QL libraries
4849

javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,14 @@ private class SuperAgentUrlRequest extends CustomClientRequest {
246246
}
247247

248248
}
249+
250+
/**
251+
* A model of a URL request made using the `XMLHttpRequest` browser class.
252+
*/
253+
private class XMLHttpRequest extends CustomClientRequest {
254+
XMLHttpRequest() { this = DataFlow::globalVarRef("XMLHttpRequest").getAnInstantiation() }
255+
256+
override DataFlow::Node getUrl() { result = getAMethodCall("open").getArgument(1) }
257+
258+
override DataFlow::Node getADataNode() { result = getAMethodCall("send").getArgument(0) }
259+
}

javascript/ql/src/semmle/javascript/frameworks/jQuery.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,24 @@ private class JQueryChainedElement extends DOM::Element {
340340
)
341341
}
342342
}
343+
344+
/**
345+
* A model of a URL request made using the `jQuery.ajax` or `jQuery.getJSON`.
346+
*/
347+
private class JQueryClientRequest extends CustomClientRequest {
348+
JQueryClientRequest() {
349+
exists(string name |
350+
name = "ajax" or
351+
name = "getJSON"
352+
|
353+
this = jquery().getAMemberCall(name)
354+
)
355+
}
356+
357+
override DataFlow::Node getUrl() {
358+
result = getArgument(0) or
359+
result = getOptionArgument([0 .. 1], "url")
360+
}
361+
362+
override DataFlow::Node getADataNode() { result = getOptionArgument([0 .. 1], "data") }
363+
}

javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@
2727
| tst.js:67:5:67:24 | superagent.post(url) |
2828
| tst.js:68:5:68:23 | superagent.get(url) |
2929
| tst.js:69:5:69:23 | superagent.get(url) |
30+
| tst.js:74:5:74:29 | $.ajax( ... data}) |
31+
| tst.js:75:5:75:35 | $.ajax( ... data}) |
32+
| tst.js:77:5:77:32 | $.getJS ... data}) |
33+
| tst.js:78:5:78:38 | $.getJS ... data}) |
34+
| tst.js:80:15:80:34 | new XMLHttpRequest() |

javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getADataNode.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@
1515
| tst.js:68:5:68:23 | superagent.get(url) | tst.js:68:34:68:43 | headerData |
1616
| tst.js:68:5:68:23 | superagent.get(url) | tst.js:68:52:68:60 | queryData |
1717
| tst.js:69:5:69:23 | superagent.get(url) | tst.js:69:48:69:56 | queryData |
18+
| tst.js:74:5:74:29 | $.ajax( ... data}) | tst.js:74:24:74:27 | data |
19+
| tst.js:77:5:77:32 | $.getJS ... data}) | tst.js:77:27:77:30 | data |
20+
| tst.js:80:15:80:34 | new XMLHttpRequest() | tst.js:82:14:82:17 | data |

javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getUrl.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,10 @@
3131
| tst.js:67:5:67:24 | superagent.post(url) | tst.js:67:21:67:23 | url |
3232
| tst.js:68:5:68:23 | superagent.get(url) | tst.js:68:20:68:22 | url |
3333
| tst.js:69:5:69:23 | superagent.get(url) | tst.js:69:20:69:22 | url |
34+
| tst.js:74:5:74:29 | $.ajax( ... data}) | tst.js:74:12:74:14 | url |
35+
| tst.js:75:5:75:35 | $.ajax( ... data}) | tst.js:75:12:75:34 | {url: u ... : data} |
36+
| tst.js:75:5:75:35 | $.ajax( ... data}) | tst.js:75:18:75:20 | url |
37+
| tst.js:77:5:77:32 | $.getJS ... data}) | tst.js:77:15:77:17 | url |
38+
| tst.js:78:5:78:38 | $.getJS ... data}) | tst.js:78:15:78:37 | {url: u ... : data} |
39+
| tst.js:78:5:78:38 | $.getJS ... data}) | tst.js:78:21:78:23 | url |
40+
| tst.js:80:15:80:34 | new XMLHttpRequest() | tst.js:81:17:81:19 | url |

javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,15 @@ import {ClientRequest, net} from 'electron';
6969
superagent.get(url).unknown(nonData).query(queryData);
7070

7171
});
72+
73+
(function() {
74+
$.ajax(url, {data: data});
75+
$.ajax({url: url, tdata: data});
76+
77+
$.getJSON(url, {data: data});
78+
$.getJSON({url: url, tdata: data});
79+
80+
var xhr = new XMLHttpRequest();
81+
xhr.open(_, url);
82+
xhr.send(data);
83+
});

0 commit comments

Comments
 (0)