Skip to content

Commit 7bd1c4d

Browse files
authored
Merge pull request #19060 from Napalys/js/apollo-server
JS: model `ApolloServer`
2 parents 803aacf + 57f6225 commit 7bd1c4d

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-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 support for the `ApolloServer` class from `@apollo/server` and similar packages. In particular, the incoming data in a GraphQL resolver is now seen as a source of untrusted user input.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: sourceModel
5+
data:
6+
- ["@apollo/server", "Member[ApolloServer,ApolloServerBase].Argument[0].AnyMember.AnyMember.AnyMember.Parameter[1]", "remote"]
7+
8+
- addsTo:
9+
pack: codeql/javascript-all
10+
extensible: typeModel
11+
data:
12+
- ["@apollo/server", "@apollo/server/standalone", ""]
13+
- ["@apollo/server", "apollo-server-express", ""]
14+
- ["@apollo/server", "apollo-server-core", ""]
15+
- ["@apollo/server", "apollo-server", ""]

javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#select
2+
| apollo.serverSide.ts:8:39:8:64 | get(fil ... => {}) | apollo.serverSide.ts:7:36:7:44 | { files } | apollo.serverSide.ts:8:43:8:50 | file.url | The $@ of this request depends on a $@. | apollo.serverSide.ts:8:43:8:50 | file.url | URL | apollo.serverSide.ts:7:36:7:44 | { files } | user-provided value |
23
| serverSide.js:18:5:18:20 | request(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:18:13:18:19 | tainted | The $@ of this request depends on a $@. | serverSide.js:18:13:18:19 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
34
| serverSide.js:20:5:20:24 | request.get(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:20:17:20:23 | tainted | The $@ of this request depends on a $@. | serverSide.js:20:17:20:23 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
45
| serverSide.js:24:5:24:20 | request(options) | serverSide.js:14:29:14:35 | req.url | serverSide.js:23:19:23:25 | tainted | The $@ of this request depends on a $@. | serverSide.js:23:19:23:25 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
@@ -24,6 +25,11 @@
2425
| serverSide.js:125:5:128:6 | axios({ ... \\n }) | serverSide.js:123:29:123:35 | req.url | serverSide.js:127:14:127:20 | tainted | The $@ of this request depends on a $@. | serverSide.js:127:14:127:20 | tainted | URL | serverSide.js:123:29:123:35 | req.url | user-provided value |
2526
| serverSide.js:131:5:131:20 | axios.get(myUrl) | serverSide.js:123:29:123:35 | req.url | serverSide.js:131:15:131:19 | myUrl | The $@ of this request depends on a $@. | serverSide.js:131:15:131:19 | myUrl | URL | serverSide.js:123:29:123:35 | req.url | user-provided value |
2627
edges
28+
| apollo.serverSide.ts:7:36:7:44 | files | apollo.serverSide.ts:8:13:8:17 | files | provenance | |
29+
| apollo.serverSide.ts:7:36:7:44 | { files } | apollo.serverSide.ts:7:36:7:44 | files | provenance | |
30+
| apollo.serverSide.ts:8:13:8:17 | files | apollo.serverSide.ts:8:28:8:31 | file | provenance | |
31+
| apollo.serverSide.ts:8:28:8:31 | file | apollo.serverSide.ts:8:43:8:46 | file | provenance | |
32+
| apollo.serverSide.ts:8:43:8:46 | file | apollo.serverSide.ts:8:43:8:50 | file.url | provenance | |
2733
| serverSide.js:14:9:14:52 | tainted | serverSide.js:18:13:18:19 | tainted | provenance | |
2834
| serverSide.js:14:9:14:52 | tainted | serverSide.js:20:17:20:23 | tainted | provenance | |
2935
| serverSide.js:14:9:14:52 | tainted | serverSide.js:23:19:23:25 | tainted | provenance | |
@@ -73,6 +79,12 @@ edges
7379
| serverSide.js:130:9:130:45 | myUrl | serverSide.js:131:15:131:19 | myUrl | provenance | |
7480
| serverSide.js:130:37:130:43 | tainted | serverSide.js:130:9:130:45 | myUrl | provenance | |
7581
nodes
82+
| apollo.serverSide.ts:7:36:7:44 | files | semmle.label | files |
83+
| apollo.serverSide.ts:7:36:7:44 | { files } | semmle.label | { files } |
84+
| apollo.serverSide.ts:8:13:8:17 | files | semmle.label | files |
85+
| apollo.serverSide.ts:8:28:8:31 | file | semmle.label | file |
86+
| apollo.serverSide.ts:8:43:8:46 | file | semmle.label | file |
87+
| apollo.serverSide.ts:8:43:8:50 | file.url | semmle.label | file.url |
7688
| serverSide.js:14:9:14:52 | tainted | semmle.label | tainted |
7789
| serverSide.js:14:19:14:42 | url.par ... , true) | semmle.label | url.par ... , true) |
7890
| serverSide.js:14:29:14:35 | req.url | semmle.label | req.url |
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { ApolloServer } from '@apollo/server';
2+
import { get } from 'https';
3+
4+
function createApolloServer(typeDefs) {
5+
const resolvers = {
6+
Mutation: {
7+
downloadFiles: async (_, { files }) => { // $ Source[js/request-forgery]
8+
files.forEach((file) => { get(file.url, (res) => {}); }); // $ Alert[js/request-forgery] Sink[js/request-forgery]
9+
return true;
10+
},
11+
},
12+
};
13+
const server = new ApolloServer({typeDefs, resolvers});
14+
15+
const resolvers2 = {
16+
Mutation: {
17+
downloadFiles: async (_, { files }) => { // $ MISSING: Source[js/request-forgery]
18+
files.forEach((file) => { get(file.url, (res) => {}); }); // $ MISSING: Alert[js/request-forgery] Sink[js/request-forgery]
19+
return true;
20+
},
21+
},
22+
};
23+
24+
class CustomApollo extends ApolloServer {}
25+
26+
const srv = new CustomApollo({typeDefs, resolvers: resolvers2});
27+
}

0 commit comments

Comments
 (0)