Skip to content

Commit 9b8d94d

Browse files
authored
Merge pull request github#5148 from erik-krogh/apollo
Approved by esbena
2 parents f0ce524 + 91f2776 commit 9b8d94d

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
lgtm,codescanning
2+
* URIs used in the Apollo-link libraries are now recognized as sinks for `js/request-forgery`.
3+
Affected packages are
4+
[apollo-link-http](https://www.npmjs.com/package/apollo-link-http),
5+
[apollo-client](https://www.npmjs.com/package/apollo-client),
6+
[apollo-boost](https://www.npmjs.com/package/apollo-boost),
7+
[apollo-client-preset](https://www.npmjs.com/package/apollo-client-preset), and
8+
[apollo-link-ws](https://www.npmjs.com/package/apollo-link-ws)

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,4 +823,35 @@ module ClientRequest {
823823

824824
override DataFlow::Node getADataNode() { none() }
825825
}
826+
827+
/**
828+
* Classes and predicates modelling the `apollo-client` library.
829+
*/
830+
private module ApolloClient {
831+
/**
832+
* A function from `apollo-client` that accepts an options object that may contain a `uri` property.
833+
*/
834+
API::Node apolloUriCallee() {
835+
result = API::moduleImport("apollo-link-http").getMember(["HttpLink", "createHttpLink"])
836+
or
837+
result =
838+
API::moduleImport(["apollo-boost", "apollo-client", "apollo-client-preset"])
839+
.getMember(["ApolloClient", "HttpLink", "createNetworkInterface"])
840+
or
841+
result = API::moduleImport("apollo-link-ws").getMember("WebSocketLink")
842+
}
843+
844+
/**
845+
* A model of a URL request made using apollo-client.
846+
*/
847+
class ApolloClientRequest extends ClientRequest::Range, API::InvokeNode {
848+
ApolloClientRequest() { this = apolloUriCallee().getAnInvocation() }
849+
850+
override DataFlow::Node getUrl() { result = getParameter(0).getMember("uri").getARhs() }
851+
852+
override DataFlow::Node getHost() { none() }
853+
854+
override DataFlow::Node getADataNode() { none() }
855+
}
856+
}
826857
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
test_ClientRequest
2+
| apollo.js:5:18:5:78 | new cre ... hql' }) |
3+
| apollo.js:10:1:10:54 | new Htt ... hql' }) |
4+
| apollo.js:14:16:14:69 | new Apo ... .com'}) |
5+
| apollo.js:17:1:17:34 | new Pre ... yurl"}) |
6+
| apollo.js:20:1:20:77 | createN ... phql'}) |
7+
| apollo.js:23:1:23:31 | new Web ... wsUri}) |
28
| tst.js:11:5:11:16 | request(url) |
39
| tst.js:13:5:13:20 | request.get(url) |
410
| tst.js:15:5:15:23 | request.delete(url) |
@@ -111,6 +117,12 @@ test_getHost
111117
| tst.js:93:5:93:35 | net.req ... host }) | tst.js:93:29:93:32 | host |
112118
| tst.js:219:5:219:41 | data.so ... Host"}) | tst.js:219:32:219:39 | "myHost" |
113119
test_getUrl
120+
| apollo.js:5:18:5:78 | new cre ... hql' }) | apollo.js:5:44:5:75 | 'https: ... raphql' |
121+
| apollo.js:10:1:10:54 | new Htt ... hql' }) | apollo.js:10:21:10:51 | 'http:/ ... raphql' |
122+
| apollo.js:14:16:14:69 | new Apo ... .com'}) | apollo.js:14:39:14:67 | 'https: ... le.com' |
123+
| apollo.js:17:1:17:34 | new Pre ... yurl"}) | apollo.js:17:26:17:32 | "myurl" |
124+
| apollo.js:20:1:20:77 | createN ... phql'}) | apollo.js:20:30:20:75 | 'https: ... raphql' |
125+
| apollo.js:23:1:23:31 | new Web ... wsUri}) | apollo.js:23:25:23:29 | wsUri |
114126
| tst.js:11:5:11:16 | request(url) | tst.js:11:13:11:15 | url |
115127
| tst.js:13:5:13:20 | request.get(url) | tst.js:13:17:13:19 | url |
116128
| tst.js:15:5:15:23 | request.delete(url) | tst.js:15:20:15:22 | url |
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ApolloClient } from 'apollo-client'
2+
import { HttpLink } from 'apollo-link-http'
3+
import { createHttpLink } from 'apollo-link-http'
4+
5+
const httpLink = new createHttpLink({ uri: 'https://api.github.com/graphql' }) // url 1
6+
7+
const ApolloClient = require('apollo-client-preset').ApolloClient;
8+
const HttpLink = require('apollo-link-http').HttpLink;
9+
10+
new HttpLink({ uri: 'http://localhost:8080/graphql' }); // url 2
11+
12+
import ApolloClient from 'apollo-boost'; // / 'apollo-client'
13+
14+
const client = new ApolloClient({uri: 'https://graphql.example.com'}); // url 3
15+
16+
let PresetHttpLink = require('apollo-client-preset').HttpLink;
17+
new PresetHttpLink({uri: "myurl"}); // url 4
18+
19+
import { createNetworkInterface } from 'apollo-client';
20+
createNetworkInterface({uri: 'https://web-go-demo.herokuapp.com/__/graphql'}) // url 5
21+
22+
const { WebSocketLink } = require('apollo-link-ws')
23+
new WebSocketLink({uri: wsUri}) // url 6

0 commit comments

Comments
 (0)