Skip to content

Commit 60fe017

Browse files
author
Esben Sparre Andreasen
committed
JS: add ClientRequest::getHost
1 parent 3a5962a commit 60fe017

File tree

9 files changed

+85
-2
lines changed

9 files changed

+85
-2
lines changed

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

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ abstract class CustomClientRequest extends DataFlow::InvokeNode {
2121
*/
2222
abstract DataFlow::Node getUrl();
2323

24+
/**
25+
* Gets the host of the request.
26+
*/
27+
abstract DataFlow::Node getHost();
28+
2429
/**
2530
* Gets a node that contributes to the data-part this request.
2631
*/
@@ -50,6 +55,13 @@ class ClientRequest extends DataFlow::InvokeNode {
5055
result = custom.getUrl()
5156
}
5257

58+
/**
59+
* Gets the host of the request.
60+
*/
61+
DataFlow::Node getHost() {
62+
result = custom.getHost()
63+
}
64+
5365
/**
5466
* Gets a node that contributes to the data-part this request.
5567
*/
@@ -102,6 +114,10 @@ private class RequestUrlRequest extends CustomClientRequest {
102114
result = getOptionArgument(0, urlPropertyName())
103115
}
104116

117+
override DataFlow::Node getHost() {
118+
none()
119+
}
120+
105121
override DataFlow::Node getADataNode() {
106122
result = getArgument(1)
107123
}
@@ -126,10 +142,18 @@ private class AxiosUrlRequest extends CustomClientRequest {
126142
)
127143
}
128144

145+
private DataFlow::Node getOptionArgument(string name) {
146+
// depends on the method name and the call arity, over-approximating slightly in the name of simplicity
147+
result = getOptionArgument([0..2], name)
148+
}
149+
129150
override DataFlow::Node getUrl() {
130151
result = getArgument(0) or
131-
// depends on the method name and the call arity, over-approximating slightly in the name of simplicity
132-
result = getOptionArgument([0..2], urlPropertyName())
152+
result = getOptionArgument(urlPropertyName())
153+
}
154+
155+
override DataFlow::Node getHost() {
156+
result = getOptionArgument("host")
133157
}
134158

135159
override DataFlow::Node getADataNode() {
@@ -176,6 +200,8 @@ private class FetchUrlRequest extends CustomClientRequest {
176200
result = url
177201
}
178202

203+
override DataFlow::Node getHost() { none() }
204+
179205
override DataFlow::Node getADataNode() {
180206
exists (string name |
181207
name = "headers" or name = "body" |
@@ -206,6 +232,14 @@ private class GotUrlRequest extends CustomClientRequest {
206232
not exists (getOptionArgument(1, "baseUrl"))
207233
}
208234

235+
override DataFlow::Node getHost() {
236+
exists (string name |
237+
name = "host" or
238+
name = "hostname" |
239+
result = getOptionArgument(1, name)
240+
)
241+
}
242+
209243
override DataFlow::Node getADataNode() {
210244
exists (string name |
211245
name = "headers" or name = "body" or name = "query" |
@@ -235,6 +269,8 @@ private class SuperAgentUrlRequest extends CustomClientRequest {
235269
result = url
236270
}
237271

272+
override DataFlow::Node getHost() { none() }
273+
238274
override DataFlow::Node getADataNode() {
239275
exists (string name |
240276
name = "set" or name = "send" or name = "query" |
@@ -252,5 +288,6 @@ private class XMLHttpRequest extends CustomClientRequest {
252288

253289
override DataFlow::Node getUrl() { result = getAMethodCall("open").getArgument(1) }
254290

291+
override DataFlow::Node getHost() { none() }
255292
override DataFlow::Node getADataNode() { result = getAMethodCall("send").getArgument(0) }
256293
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ module Electron {
6464
result = getOptionArgument(0, "url")
6565
}
6666

67+
override DataFlow::Node getHost() {
68+
exists (string name |
69+
name = "host" or
70+
name = "hostname" |
71+
result = getOptionArgument(0, name)
72+
)
73+
}
74+
6775
override DataFlow::Node getADataNode() {
6876
exists (string name |
6977
name = "write" or name = "end" |

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,14 @@ module NodeJSLib {
737737
result = url
738738
}
739739

740+
override DataFlow::Node getHost() {
741+
exists (string name |
742+
name = "host" or
743+
name = "hostname" |
744+
result = getOptionArgument(1, name)
745+
)
746+
}
747+
740748
override DataFlow::Node getADataNode() {
741749
exists (string name |
742750
name = "write" or name = "end" |

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,5 +359,7 @@ private class JQueryClientRequest extends CustomClientRequest {
359359
result = getOptionArgument([0 .. 1], "url")
360360
}
361361

362+
override DataFlow::Node getHost() { none() }
363+
362364
override DataFlow::Node getADataNode() { result = getOptionArgument([0 .. 1], "data") }
363365
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@
3232
| tst.js:77:5:77:32 | $.getJS ... data}) |
3333
| tst.js:78:5:78:38 | $.getJS ... data}) |
3434
| tst.js:80:15:80:34 | new XMLHttpRequest() |
35+
| tst.js:87:5:87:39 | http.ge ... host}) |
36+
| tst.js:89:5:89:23 | axios({host: host}) |
37+
| tst.js:91:5:91:34 | got(rel ... host}) |
38+
| tst.js:93:5:93:35 | net.req ... host }) |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host |
2+
| tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host |
3+
| tst.js:91:5:91:34 | got(rel ... host}) | tst.js:91:29:91:32 | host |
4+
| tst.js:93:5:93:35 | net.req ... host }) | tst.js:93:29:93:32 | host |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from ClientRequest r
4+
select r, r.getHost()

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@
3838
| tst.js:78:5:78:38 | $.getJS ... data}) | tst.js:78:15:78:37 | {url: u ... : data} |
3939
| tst.js:78:5:78:38 | $.getJS ... data}) | tst.js:78:21:78:23 | url |
4040
| tst.js:80:15:80:34 | new XMLHttpRequest() | tst.js:81:17:81:19 | url |
41+
| tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:14:87:24 | relativeUrl |
42+
| tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:11:89:22 | {host: host} |
43+
| tst.js:91:5:91:34 | got(rel ... host}) | tst.js:91:9:91:19 | relativeUrl |
44+
| tst.js:93:5:93:35 | net.req ... host }) | tst.js:93:17:93:34 | { hostname: host } |

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,15 @@ import {ClientRequest, net} from 'electron';
8181
xhr.open(_, url);
8282
xhr.send(data);
8383
});
84+
85+
(function() {
86+
87+
http.get(relativeUrl, {host: host});
88+
89+
axios({host: host});
90+
91+
got(relativeUrl, {host: host});
92+
93+
net.request({ hostname: host });
94+
95+
});

0 commit comments

Comments
 (0)