Skip to content

Commit ede1a40

Browse files
committed
add ClientRequst models for http-proxy
1 parent b7c0d18 commit ede1a40

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

javascript/ql/src/javascript.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import semmle.javascript.frameworks.LazyCache
9494
import semmle.javascript.frameworks.LodashUnderscore
9595
import semmle.javascript.frameworks.Logging
9696
import semmle.javascript.frameworks.HttpFrameworks
97+
import semmle.javascript.frameworks.HttpProxy
9798
import semmle.javascript.frameworks.Markdown
9899
import semmle.javascript.frameworks.NoSQL
99100
import semmle.javascript.frameworks.PkgCloud
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Provides classes and predicates for working with the [http-proxy](https://www.npmjs.com/package/http-proxy) library.
3+
*/
4+
5+
import javascript
6+
7+
/**
8+
* Provides classes and predicates modelling the [http-proxy](https://www.npmjs.com/package/http-proxy) library.
9+
*/
10+
private module HttpProxy {
11+
/**
12+
* A call that creates a http proxy.
13+
*/
14+
class CreateServerCall extends API::CallNode, ClientRequest::Range {
15+
CreateServerCall() {
16+
this =
17+
API::moduleImport("http-proxy")
18+
.getMember(["createServer", "createProxyServer", "createProxy"])
19+
.getACall()
20+
}
21+
22+
override DataFlow::Node getUrl() { result = getParameter(0).getMember("target").getARhs() }
23+
24+
override DataFlow::Node getHost() { none() }
25+
26+
override DataFlow::Node getADataNode() { none() }
27+
}
28+
29+
/**
30+
* A call that proxies a request to some target.
31+
*/
32+
class ProxyCall extends API::CallNode, ClientRequest::Range {
33+
string method;
34+
35+
ProxyCall() {
36+
method = ["ws", "web"] and
37+
this = any(CreateServerCall server).getReturn().getMember(method).getACall()
38+
}
39+
40+
override DataFlow::Node getUrl() {
41+
exists(int optionsIndex |
42+
method = "web" and optionsIndex = 2
43+
or
44+
method = "ws" and optionsIndex = 3
45+
|
46+
result = getParameter(optionsIndex).getMember("target").getARhs()
47+
)
48+
}
49+
50+
override DataFlow::Node getHost() { none() }
51+
52+
override DataFlow::Node getADataNode() { none() }
53+
}
54+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ test_ClientRequest
7979
| tst.js:247:24:247:68 | request ... o.png') |
8080
| tst.js:249:1:251:2 | form.su ... e();\\n}) |
8181
| tst.js:257:1:262:2 | form.su ... rs()\\n}) |
82+
| tst.js:267:1:267:61 | httpPro ... 9000'}) |
83+
| tst.js:269:13:269:48 | httpPro ... ptions) |
84+
| tst.js:271:3:271:61 | proxy.w ... 080' }) |
8285
test_getADataNode
8386
| tst.js:53:5:53:23 | axios({data: data}) | tst.js:53:18:53:21 | data |
8487
| tst.js:57:5:57:39 | axios.p ... data2}) | tst.js:57:19:57:23 | data1 |
@@ -210,6 +213,8 @@ test_getUrl
210213
| tst.js:247:24:247:68 | request ... o.png') | tst.js:247:32:247:67 | 'http:/ ... go.png' |
211214
| tst.js:249:1:251:2 | form.su ... e();\\n}) | tst.js:249:13:249:33 | 'http:/ ... e.org/' |
212215
| tst.js:257:1:262:2 | form.su ... rs()\\n}) | tst.js:257:13:262:1 | {\\n m ... ers()\\n} |
216+
| tst.js:267:1:267:61 | httpPro ... 9000'}) | tst.js:267:37:267:59 | 'http:/ ... t:9000' |
217+
| tst.js:271:3:271:61 | proxy.w ... 080' }) | tst.js:271:33:271:58 | 'http:/ ... m:8080' |
213218
test_getAResponseDataNode
214219
| tst.js:19:5:19:23 | requestPromise(url) | tst.js:19:5:19:23 | requestPromise(url) | text | true |
215220
| tst.js:21:5:21:23 | superagent.get(url) | tst.js:21:5:21:23 | superagent.get(url) | stream | true |

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,14 @@ form.submit({
259259
host: 'example.org',
260260
path: '/upload',
261261
headers: form.getHeaders()
262-
});
262+
});
263+
264+
var httpProxy = require('http-proxy');
265+
var http = require("http");
266+
267+
httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(8000);
268+
269+
var proxy = httpProxy.createProxyServer(options);
270+
http.createServer(function(req, res) {
271+
proxy.web(req, res, { target: 'http://mytarget.com:8080' });
272+
});

0 commit comments

Comments
 (0)