This commit is contained in:
Owen Mansel-Chan
2026-06-10 22:57:33 +02:00
parent 11e99a03d5
commit d75113de93
47 changed files with 166 additions and 157 deletions

View File

@@ -1,3 +1,8 @@
#select
| test.js:7:16:7:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:7:16:7:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value |
| test.js:10:16:10:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:10:16:10:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value |
| test.js:18:18:18:24 | payload | test.js:17:21:17:44 | req.que ... rameter | test.js:18:18:18:24 | payload | This command line depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value |
| test.js:19:18:19:30 | payload + sth | test.js:17:21:17:44 | req.que ... rameter | test.js:19:18:19:30 | payload + sth | This command line depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value |
edges
| test.js:5:11:5:17 | payload | test.js:6:30:6:36 | payload | provenance | |
| test.js:5:11:5:17 | payload | test.js:9:26:9:32 | payload | provenance | |
@@ -33,8 +38,3 @@ nodes
| test.js:19:18:19:24 | payload | semmle.label | payload |
| test.js:19:18:19:30 | payload + sth | semmle.label | payload + sth |
subpaths
#select
| test.js:7:16:7:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:7:16:7:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value |
| test.js:10:16:10:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:10:16:10:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value |
| test.js:18:18:18:24 | payload | test.js:17:21:17:44 | req.que ... rameter | test.js:18:18:18:24 | payload | This command line depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value |
| test.js:19:18:19:30 | payload + sth | test.js:17:21:17:44 | req.que ... rameter | test.js:19:18:19:30 | payload + sth | This command line depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value |

View File

@@ -1 +1,2 @@
experimental/Security/CWE-094-dataURL/CodeInjection.ql
query: experimental/Security/CWE-094-dataURL/CodeInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -2,21 +2,21 @@ const { Worker } = require('node:worker_threads');
var app = require('express')();
app.post('/path', async function (req, res) {
const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//'
const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//' // $ Source
let payloadURL = new URL(payload + sth) // NOT OK
new Worker(payloadURL);
new Worker(payloadURL); // $ Alert
payloadURL = new URL(payload + sth) // NOT OK
new Worker(payloadURL);
new Worker(payloadURL); // $ Alert
payloadURL = new URL(sth + payload) // OK
new Worker(payloadURL);
});
app.post('/path2', async function (req, res) {
const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//'
await import(payload) // NOT OK
await import(payload + sth) // NOT OK
const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//' // $ Source
await import(payload) // NOT OK // $ Alert
await import(payload + sth) // NOT OK // $ Alert
await import(sth + payload) // OK
});

View File

@@ -1,3 +1,6 @@
#select
| test.js:6:15:6:20 | EnvKey | test.js:5:32:5:39 | req.body | test.js:6:15:6:20 | EnvKey | arbitrary environment variable assignment from this $@. | test.js:5:32:5:39 | req.body | user controllable source |
| test.js:7:15:7:20 | EnvKey | test.js:5:32:5:39 | req.body | test.js:7:15:7:20 | EnvKey | arbitrary environment variable assignment from this $@. | test.js:5:32:5:39 | req.body | user controllable source |
edges
| test.js:5:9:5:28 | { EnvValue, EnvKey } | test.js:5:11:5:18 | EnvValue | provenance | |
| test.js:5:9:5:28 | { EnvValue, EnvKey } | test.js:5:21:5:26 | EnvKey | provenance | |
@@ -27,6 +30,3 @@ nodes
| test.js:15:15:15:20 | EnvKey | semmle.label | EnvKey |
| test.js:16:26:16:33 | EnvValue | semmle.label | EnvValue |
subpaths
#select
| test.js:6:15:6:20 | EnvKey | test.js:5:32:5:39 | req.body | test.js:6:15:6:20 | EnvKey | arbitrary environment variable assignment from this $@. | test.js:5:32:5:39 | req.body | user controllable source |
| test.js:7:15:7:20 | EnvKey | test.js:5:32:5:39 | req.body | test.js:7:15:7:20 | EnvKey | arbitrary environment variable assignment from this $@. | test.js:5:32:5:39 | req.body | user controllable source |

View File

@@ -1 +1,2 @@
experimental/Security/CWE-099/EnvValueAndKeyInjection.ql
query: experimental/Security/CWE-099/EnvValueAndKeyInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -2,9 +2,9 @@ const http = require('node:http');
http.createServer((req, res) => {
const { EnvValue, EnvKey } = req.body;
process.env[EnvKey] = EnvValue; // NOT OK
process.env[EnvKey] = EnvValue; // NOT OK
const { EnvValue, EnvKey } = req.body; // $ Source
process.env[EnvKey] = EnvValue; // NOT OK // $ Alert
process.env[EnvKey] = EnvValue; // NOT OK // $ Alert
res.end('env has been injected!');
});

View File

@@ -1,3 +1,7 @@
#select
| test.js:5:35:5:42 | EnvValue | test.js:4:24:4:31 | req.body | test.js:5:35:5:42 | EnvValue | this environment variable assignment is $@. | test.js:4:24:4:31 | req.body | user controllable |
| test.js:6:23:6:30 | EnvValue | test.js:4:24:4:31 | req.body | test.js:6:23:6:30 | EnvValue | this environment variable assignment is $@. | test.js:4:24:4:31 | req.body | user controllable |
| test.js:7:22:7:29 | EnvValue | test.js:4:24:4:31 | req.body | test.js:7:22:7:29 | EnvValue | this environment variable assignment is $@. | test.js:4:24:4:31 | req.body | user controllable |
edges
| test.js:4:9:4:20 | { EnvValue } | test.js:4:11:4:18 | EnvValue | provenance | |
| test.js:4:11:4:18 | EnvValue | test.js:5:35:5:42 | EnvValue | provenance | |
@@ -12,7 +16,3 @@ nodes
| test.js:6:23:6:30 | EnvValue | semmle.label | EnvValue |
| test.js:7:22:7:29 | EnvValue | semmle.label | EnvValue |
subpaths
#select
| test.js:5:35:5:42 | EnvValue | test.js:4:24:4:31 | req.body | test.js:5:35:5:42 | EnvValue | this environment variable assignment is $@. | test.js:4:24:4:31 | req.body | user controllable |
| test.js:6:23:6:30 | EnvValue | test.js:4:24:4:31 | req.body | test.js:6:23:6:30 | EnvValue | this environment variable assignment is $@. | test.js:4:24:4:31 | req.body | user controllable |
| test.js:7:22:7:29 | EnvValue | test.js:4:24:4:31 | req.body | test.js:7:22:7:29 | EnvValue | this environment variable assignment is $@. | test.js:4:24:4:31 | req.body | user controllable |

View File

@@ -1 +1,2 @@
experimental/Security/CWE-099/EnvValueInjection.ql
query: experimental/Security/CWE-099/EnvValueInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,10 +1,10 @@
const http = require('node:http');
http.createServer((req, res) => {
const { EnvValue } = req.body;
process.env["A_Critical_Env"] = EnvValue; // NOT OK
process.env[AKey] = EnvValue; // NOT OK
process.env.AKey = EnvValue; // NOT OK
const { EnvValue } = req.body; // $ Source
process.env["A_Critical_Env"] = EnvValue; // NOT OK // $ Alert
process.env[AKey] = EnvValue; // NOT OK // $ Alert
process.env.AKey = EnvValue; // NOT OK // $ Alert
res.end('env has been injected!');
});

View File

@@ -10,18 +10,18 @@ function aJWT() {
}
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// BAD: no signature verification
jwtJsonwebtoken.decode(UserToken) // NOT OK
jwtJsonwebtoken.decode(UserToken) // NOT OK // $ Sink
})();
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// BAD: no signature verification
jwtJsonwebtoken.decode(UserToken) // NOT OK
jwtJsonwebtoken.verify(UserToken, getSecret(), { algorithms: ["HS256", "none"] }) // NOT OK
jwtJsonwebtoken.decode(UserToken) // NOT OK // $ Sink
jwtJsonwebtoken.verify(UserToken, getSecret(), { algorithms: ["HS256", "none"] }) // NOT OK // $ Sink
})();
(function () {

View File

@@ -1,3 +1,10 @@
#select
| JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:16:28:16:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:16:28:16:36 | UserToken | without signature verification |
| JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:23:28:23:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:23:28:23:36 | UserToken | without signature verification |
| JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:24:28:24:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:24:28:24:36 | UserToken | without signature verification |
| jose.js:12:23:12:28 | aJwt() | jose.js:12:23:12:28 | aJwt() | jose.js:15:20:15:28 | UserToken | Decoding JWT $@. | jose.js:15:20:15:28 | UserToken | without signature verification |
| jwtDecode.js:13:23:13:28 | aJwt() | jwtDecode.js:13:23:13:28 | aJwt() | jwtDecode.js:17:16:17:24 | UserToken | Decoding JWT $@. | jwtDecode.js:17:16:17:24 | UserToken | without signature verification |
| jwtSimple.js:13:23:13:28 | aJwt() | jwtSimple.js:13:23:13:28 | aJwt() | jwtSimple.js:16:23:16:31 | UserToken | Decoding JWT $@. | jwtSimple.js:16:23:16:31 | UserToken | without signature verification |
edges
| JsonWebToken.js:13:11:13:19 | UserToken | JsonWebToken.js:16:28:16:36 | UserToken | provenance | |
| JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:13:11:13:19 | UserToken | provenance | |
@@ -73,10 +80,3 @@ nodes
| jwtSimple.js:31:23:31:31 | UserToken | semmle.label | UserToken |
| jwtSimple.js:32:23:32:31 | UserToken | semmle.label | UserToken |
subpaths
#select
| JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:13:23:13:28 | aJwt() | JsonWebToken.js:16:28:16:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:16:28:16:36 | UserToken | without signature verification |
| JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:23:28:23:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:23:28:23:36 | UserToken | without signature verification |
| JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:20:23:20:28 | aJwt() | JsonWebToken.js:24:28:24:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:24:28:24:36 | UserToken | without signature verification |
| jose.js:12:23:12:28 | aJwt() | jose.js:12:23:12:28 | aJwt() | jose.js:15:20:15:28 | UserToken | Decoding JWT $@. | jose.js:15:20:15:28 | UserToken | without signature verification |
| jwtDecode.js:13:23:13:28 | aJwt() | jwtDecode.js:13:23:13:28 | aJwt() | jwtDecode.js:17:16:17:24 | UserToken | Decoding JWT $@. | jwtDecode.js:17:16:17:24 | UserToken | without signature verification |
| jwtSimple.js:13:23:13:28 | aJwt() | jwtSimple.js:13:23:13:28 | aJwt() | jwtSimple.js:16:23:16:31 | UserToken | Decoding JWT $@. | jwtSimple.js:16:23:16:31 | UserToken | without signature verification |

View File

@@ -1 +1,2 @@
experimental/Security/CWE-347/decodeJwtWithoutVerificationLocalSource.ql
query: experimental/Security/CWE-347/decodeJwtWithoutVerificationLocalSource.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -9,10 +9,10 @@ function aJWT() {
}
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// no signature verification
jose.decodeJwt(UserToken) // NOT OK
jose.decodeJwt(UserToken) // NOT OK // $ Sink
})();
(async function () {

View File

@@ -10,9 +10,9 @@ function aJWT() {
}
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// jwt-decode
// no signature verification
jwt_decode(UserToken) // NOT OK
jwt_decode(UserToken) // NOT OK // $ Sink
})();

View File

@@ -10,10 +10,10 @@ function aJWT() {
}
(function () {
const UserToken = aJwt()
const UserToken = aJwt() // $ Alert
// BAD: no signature verification
jwt_simple.decode(UserToken, getSecret(), true); // NOT OK
jwt_simple.decode(UserToken, getSecret(), true); // NOT OK // $ Sink
})();
(function () {

View File

@@ -7,18 +7,18 @@ function getSecret() {
return "A Safe generated random key"
}
app.get('/jwtJsonwebtoken1', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// BAD: no signature verification
jwtJsonwebtoken.decode(UserToken) // NOT OK
jwtJsonwebtoken.decode(UserToken) // NOT OK // $ Sink
})
app.get('/jwtJsonwebtoken2', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// BAD: no signature verification
jwtJsonwebtoken.decode(UserToken) // NOT OK
jwtJsonwebtoken.verify(UserToken, getSecret(), { algorithms: ["HS256", "none"] }) // NOT OK
jwtJsonwebtoken.decode(UserToken) // NOT OK // $ Sink
jwtJsonwebtoken.verify(UserToken, getSecret(), { algorithms: ["HS256", "none"] }) // NOT OK // $ Sink
})
app.get('/jwtJsonwebtoken3', (req, res) => {

View File

@@ -1,3 +1,10 @@
#select
| JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:13:28:13:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:13:28:13:36 | UserToken | without signature verification |
| JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:20:28:20:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:20:28:20:36 | UserToken | without signature verification |
| JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:21:28:21:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:21:28:21:36 | UserToken | without signature verification |
| jose.js:11:23:11:47 | req.hea ... ization | jose.js:11:23:11:47 | req.hea ... ization | jose.js:13:20:13:28 | UserToken | Decoding JWT $@. | jose.js:13:20:13:28 | UserToken | without signature verification |
| jwtDecode.js:11:23:11:47 | req.hea ... ization | jwtDecode.js:11:23:11:47 | req.hea ... ization | jwtDecode.js:15:16:15:24 | UserToken | Decoding JWT $@. | jwtDecode.js:15:16:15:24 | UserToken | without signature verification |
| jwtSimple.js:10:23:10:47 | req.hea ... ization | jwtSimple.js:10:23:10:47 | req.hea ... ization | jwtSimple.js:13:23:13:31 | UserToken | Decoding JWT $@. | jwtSimple.js:13:23:13:31 | UserToken | without signature verification |
edges
| JsonWebToken.js:10:11:10:19 | UserToken | JsonWebToken.js:13:28:13:36 | UserToken | provenance | |
| JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:10:11:10:19 | UserToken | provenance | |
@@ -48,10 +55,3 @@ nodes
| jwtSimple.js:25:23:25:47 | req.hea ... ization | semmle.label | req.hea ... ization |
| jwtSimple.js:28:23:28:31 | UserToken | semmle.label | UserToken |
subpaths
#select
| JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:10:23:10:47 | req.hea ... ization | JsonWebToken.js:13:28:13:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:13:28:13:36 | UserToken | without signature verification |
| JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:20:28:20:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:20:28:20:36 | UserToken | without signature verification |
| JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:17:23:17:47 | req.hea ... ization | JsonWebToken.js:21:28:21:36 | UserToken | Decoding JWT $@. | JsonWebToken.js:21:28:21:36 | UserToken | without signature verification |
| jose.js:11:23:11:47 | req.hea ... ization | jose.js:11:23:11:47 | req.hea ... ization | jose.js:13:20:13:28 | UserToken | Decoding JWT $@. | jose.js:13:20:13:28 | UserToken | without signature verification |
| jwtDecode.js:11:23:11:47 | req.hea ... ization | jwtDecode.js:11:23:11:47 | req.hea ... ization | jwtDecode.js:15:16:15:24 | UserToken | Decoding JWT $@. | jwtDecode.js:15:16:15:24 | UserToken | without signature verification |
| jwtSimple.js:10:23:10:47 | req.hea ... ization | jwtSimple.js:10:23:10:47 | req.hea ... ization | jwtSimple.js:13:23:13:31 | UserToken | Decoding JWT $@. | jwtSimple.js:13:23:13:31 | UserToken | without signature verification |

View File

@@ -1 +1,2 @@
experimental/Security/CWE-347/decodeJwtWithoutVerification.ql
query: experimental/Security/CWE-347/decodeJwtWithoutVerification.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -8,9 +8,9 @@ function getSecret() {
}
app.get('/jose1', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// no signature verification
jose.decodeJwt(UserToken) // NOT OK
jose.decodeJwt(UserToken) // NOT OK // $ Sink
})

View File

@@ -8,11 +8,11 @@ function getSecret() {
}
app.get('/jwtDecode', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// jwt-decode
// no signature verification
jwt_decode(UserToken) // NOT OK
jwt_decode(UserToken) // NOT OK // $ Sink
})
app.listen(port, () => {

View File

@@ -7,10 +7,10 @@ function getSecret() {
return "A Safe generated random key"
}
app.get('/jwtSimple1', (req, res) => {
const UserToken = req.headers.authorization;
const UserToken = req.headers.authorization; // $ Alert
// no signature verification
jwt_simple.decode(UserToken, getSecret(), true); // NOT OK
jwt_simple.decode(UserToken, getSecret(), true); // NOT OK // $ Sink
})
app.get('/jwtSimple2', (req, res) => {

View File

@@ -1,3 +1,24 @@
#select
| check-domain.js:17:13:17:15 | url | check-domain.js:16:15:16:27 | req.query.url | check-domain.js:17:13:17:15 | url | The URL of this request depends on a user-provided value. |
| check-domain.js:26:15:26:27 | req.query.url | check-domain.js:26:15:26:27 | req.query.url | check-domain.js:26:15:26:27 | req.query.url | The URL of this request depends on a user-provided value. |
| check-middleware.js:9:13:9:43 | "test.c ... tainted | check-middleware.js:9:27:9:43 | req.query.tainted | check-middleware.js:9:13:9:43 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-path.js:19:13:19:43 | 'test.c ... tainted | check-path.js:19:27:19:43 | req.query.tainted | check-path.js:19:13:19:43 | 'test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-path.js:23:13:23:45 | `/addre ... inted}` | check-path.js:23:27:23:43 | req.query.tainted | check-path.js:23:13:23:45 | `/addre ... inted}` | The URL of this request depends on a user-provided value. |
| check-path.js:33:15:33:45 | 'test.c ... tainted | check-path.js:33:29:33:45 | req.query.tainted | check-path.js:33:15:33:45 | 'test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-path.js:37:15:37:45 | 'test.c ... tainted | check-path.js:37:29:37:45 | req.query.tainted | check-path.js:37:15:37:45 | 'test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-path.js:45:13:45:44 | `${base ... inted}` | check-path.js:45:26:45:42 | req.query.tainted | check-path.js:45:13:45:44 | `${base ... inted}` | The URL of this request depends on a user-provided value. |
| check-regex.js:16:15:16:45 | "test.c ... tainted | check-regex.js:16:29:16:45 | req.query.tainted | check-regex.js:16:15:16:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:24:15:24:42 | baseURL ... tainted | check-regex.js:24:25:24:42 | req.params.tainted | check-regex.js:24:15:24:42 | baseURL ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:31:15:31:45 | "test.c ... tainted | check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:34:15:34:42 | baseURL ... tainted | check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:41:13:41:43 | "test.c ... tainted | check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:61:15:61:42 | baseURL ... tainted | check-regex.js:61:25:61:42 | req.params.tainted | check-regex.js:61:15:61:42 | baseURL ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:15:15:15:45 | "test.c ... tainted | check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:27:15:27:45 | "test.c ... tainted | check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:50:15:50:45 | "test.c ... tainted | check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:59:15:59:45 | "test.c ... tainted | check-validator.js:59:29:59:45 | req.query.tainted | check-validator.js:59:15:59:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:62:15:62:37 | "test.c ... mberURL | check-validator.js:54:21:54:37 | req.query.tainted | check-validator.js:62:15:62:37 | "test.c ... mberURL | The URL of this request depends on a user-provided value. |
| check-validator.js:68:15:68:45 | "test.c ... tainted | check-validator.js:68:29:68:45 | req.query.tainted | check-validator.js:68:15:68:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
edges
| check-domain.js:16:9:16:11 | url | check-domain.js:17:13:17:15 | url | provenance | |
| check-domain.js:16:15:16:27 | req.query.url | check-domain.js:16:9:16:11 | url | provenance | |
@@ -65,24 +86,3 @@ nodes
| check-validator.js:68:15:68:45 | "test.c ... tainted | semmle.label | "test.c ... tainted |
| check-validator.js:68:29:68:45 | req.query.tainted | semmle.label | req.query.tainted |
subpaths
#select
| check-domain.js:17:13:17:15 | url | check-domain.js:16:15:16:27 | req.query.url | check-domain.js:17:13:17:15 | url | The URL of this request depends on a user-provided value. |
| check-domain.js:26:15:26:27 | req.query.url | check-domain.js:26:15:26:27 | req.query.url | check-domain.js:26:15:26:27 | req.query.url | The URL of this request depends on a user-provided value. |
| check-middleware.js:9:13:9:43 | "test.c ... tainted | check-middleware.js:9:27:9:43 | req.query.tainted | check-middleware.js:9:13:9:43 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-path.js:19:13:19:43 | 'test.c ... tainted | check-path.js:19:27:19:43 | req.query.tainted | check-path.js:19:13:19:43 | 'test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-path.js:23:13:23:45 | `/addre ... inted}` | check-path.js:23:27:23:43 | req.query.tainted | check-path.js:23:13:23:45 | `/addre ... inted}` | The URL of this request depends on a user-provided value. |
| check-path.js:33:15:33:45 | 'test.c ... tainted | check-path.js:33:29:33:45 | req.query.tainted | check-path.js:33:15:33:45 | 'test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-path.js:37:15:37:45 | 'test.c ... tainted | check-path.js:37:29:37:45 | req.query.tainted | check-path.js:37:15:37:45 | 'test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-path.js:45:13:45:44 | `${base ... inted}` | check-path.js:45:26:45:42 | req.query.tainted | check-path.js:45:13:45:44 | `${base ... inted}` | The URL of this request depends on a user-provided value. |
| check-regex.js:16:15:16:45 | "test.c ... tainted | check-regex.js:16:29:16:45 | req.query.tainted | check-regex.js:16:15:16:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:24:15:24:42 | baseURL ... tainted | check-regex.js:24:25:24:42 | req.params.tainted | check-regex.js:24:15:24:42 | baseURL ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:31:15:31:45 | "test.c ... tainted | check-regex.js:31:29:31:45 | req.query.tainted | check-regex.js:31:15:31:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:34:15:34:42 | baseURL ... tainted | check-regex.js:34:25:34:42 | req.params.tainted | check-regex.js:34:15:34:42 | baseURL ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:41:13:41:43 | "test.c ... tainted | check-regex.js:41:27:41:43 | req.query.tainted | check-regex.js:41:13:41:43 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-regex.js:61:15:61:42 | baseURL ... tainted | check-regex.js:61:25:61:42 | req.params.tainted | check-regex.js:61:15:61:42 | baseURL ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:15:15:15:45 | "test.c ... tainted | check-validator.js:15:29:15:45 | req.query.tainted | check-validator.js:15:15:15:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:27:15:27:45 | "test.c ... tainted | check-validator.js:27:29:27:45 | req.query.tainted | check-validator.js:27:15:27:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:50:15:50:45 | "test.c ... tainted | check-validator.js:50:29:50:45 | req.query.tainted | check-validator.js:50:15:50:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:59:15:59:45 | "test.c ... tainted | check-validator.js:59:29:59:45 | req.query.tainted | check-validator.js:59:15:59:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |
| check-validator.js:62:15:62:37 | "test.c ... mberURL | check-validator.js:54:21:54:37 | req.query.tainted | check-validator.js:62:15:62:37 | "test.c ... mberURL | The URL of this request depends on a user-provided value. |
| check-validator.js:68:15:68:45 | "test.c ... tainted | check-validator.js:68:29:68:45 | req.query.tainted | check-validator.js:68:15:68:45 | "test.c ... tainted | The URL of this request depends on a user-provided value. |

View File

@@ -1 +1,2 @@
./experimental/Security/CWE-918/SSRF.ql
query: ./experimental/Security/CWE-918/SSRF.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -13,8 +13,8 @@ const app = express();
app.get('/check-with-axios', req => {
// without validation
const url = req.query.url;
axios.get(url); //SSRF
const url = req.query.url; // $ Source
axios.get(url); //SSRF // $ Alert
// validating domain only
const decodedURI = decodeURIComponent(req.query.url);
@@ -23,7 +23,7 @@ app.get('/check-with-axios', req => {
const { hostname } = url.parse(decodedURI);
if (isValidDomain(hostname, validDomains)) {
axios.get(req.query.url); //SSRF
axios.get(req.query.url); //SSRF // $ Alert
}
});

View File

@@ -6,7 +6,7 @@ const express = require('express');
const app = express();
app.get('/check-with-axios', validationMiddleware, req => {
axios.get("test.com/" + req.query.tainted); // OK is sanitized by the middleware - False Positive
axios.get("test.com/" + req.query.tainted); // OK is sanitized by the middleware - False Positive // $ Alert
});

View File

@@ -16,11 +16,11 @@ app.get('/check-with-axios', req => {
const hardcoded = 'hardcodeado';
axios.get('test.com/' + hardcoded); // OK
axios.get('test.com/' + req.query.tainted); // SSRF
axios.get('test.com/' + req.query.tainted); // SSRF // $ Alert
axios.get('test.com/' + Number(req.query.tainted)); // OK
axios.get('test.com/' + req.user.id); // OK
axios.get('test.com/' + encodeURIComponent(req.query.tainted)); // OK
axios.get(`/addresses/${req.query.tainted}`); // SSRF
axios.get(`/addresses/${req.query.tainted}`); // SSRF // $ Alert
axios.get(`/addresses/${encodeURIComponent(req.query.tainted)}`); // OK
if (Number.isInteger(req.query.tainted)) {
@@ -30,11 +30,11 @@ app.get('/check-with-axios', req => {
if (isValidInput(req.query.tainted)){
axios.get('test.com/' + req.query.tainted); // OK
} else {
axios.get('test.com/' + req.query.tainted); // SSRF
axios.get('test.com/' + req.query.tainted); // SSRF // $ Alert
}
if (doesntCheckAnything(req.query.tainted)) {
axios.get('test.com/' + req.query.tainted); // SSRF
axios.get('test.com/' + req.query.tainted); // SSRF // $ Alert
}
if (isValidPath(req.query.tainted, VALID_PATHS)) {
@@ -42,7 +42,7 @@ app.get('/check-with-axios', req => {
}
let baseURL = require('config').base
axios.get(`${baseURL}${req.query.tainted}`); // SSRF
axios.get(`${baseURL}${req.query.tainted}`); // SSRF // $ Alert
if(!isValidInput(req.query.tainted)) {
return;

View File

@@ -13,7 +13,7 @@ app.get('/check-with-axios', req => {
axios.get("test.com/" + req.query.tainted); // OK
}
if (req.query.tainted.match(/^.*$/)) { // anything
axios.get("test.com/" + req.query.tainted); // SSRF - False Negative
axios.get("test.com/" + req.query.tainted); // SSRF - False Negative // $ Alert
}
const baseURL = "test.com/"
@@ -21,24 +21,24 @@ app.get('/check-with-axios', req => {
axios.get(baseURL + req.params.tainted); // OK
}
if (!isValidPath(req.params.tainted) ) {
axios.get(baseURL + req.params.tainted); // SSRF
axios.get(baseURL + req.params.tainted); // SSRF // $ Alert
} else {
axios.get(baseURL + req.params.tainted); // OK
}
// Blacklists are not safe
if (!req.query.tainted.match(/^[/\.%]+$/)) {
axios.get("test.com/" + req.query.tainted); // SSRF
axios.get("test.com/" + req.query.tainted); // SSRF // $ Alert
}
if (!isInBlacklist(req.params.tainted) ) {
axios.get(baseURL + req.params.tainted); // SSRF
axios.get(baseURL + req.params.tainted); // SSRF // $ Alert
}
if (!isValidPath(req.params.tainted)) {
return;
}
axios.get("test.com/" + req.query.tainted); // OK - False Positive
axios.get("test.com/" + req.query.tainted); // OK - False Positive // $ Alert
if (req.query.tainted.matchAll(/^[0-9a-z]+$/g)) { // letters and numbers
axios.get("test.com/" + req.query.tainted); // OK
@@ -58,7 +58,7 @@ app.get('/check-with-axios', req => {
axios.get(baseURL + req.params.tainted); // OK
}
if (!isValidPathMatchAll(req.params.tainted) ) {
axios.get(baseURL + req.params.tainted); // NOT OK - SSRF
axios.get(baseURL + req.params.tainted); // NOT OK - SSRF // $ Alert
} else {
axios.get(baseURL + req.params.tainted); // OK
}

View File

@@ -12,7 +12,7 @@ app.get("/check-with-axios", req => {
axios.get("test.com/" + req.query.tainted); // OK
}
if (isAlphanumeric(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // SSRF
axios.get("test.com/" + req.query.tainted); // SSRF // $ Alert
}
if (validAlphanumeric(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // OK
@@ -24,7 +24,7 @@ app.get("/check-with-axios", req => {
axios.get("test.com/" + req.query.tainted); // OK
}
if (wrongValidation(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // SSRF
axios.get("test.com/" + req.query.tainted); // SSRF // $ Alert
}
// numbers
@@ -47,25 +47,25 @@ app.get("/check-with-axios", req => {
axios.get("test.com/" + req.query.tainted); // OK
}
if (validHexa(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // OK. False Positive
axios.get("test.com/" + req.query.tainted); // OK. False Positive // $ Alert
}
// with simple assignation
const numberURL = req.query.tainted;
const numberURL = req.query.tainted; // $ Source
if (validNumber(numberURL)) {
axios.get("test.com/" + numberURL); // OK
}
if (validNumber(numberURL)) {
axios.get("test.com/" + req.query.tainted); // OK. False Positive
axios.get("test.com/" + req.query.tainted); // OK. False Positive // $ Alert
}
if (validNumber(req.query.tainted)) {
axios.get("test.com/" + numberURL); // OK. False Positive
axios.get("test.com/" + numberURL); // OK. False Positive // $ Alert
}
if (validHexadecimal(req.query.tainted) || validHexaColor(req.query.tainted) ||
validDecimal(req.query.tainted) || validFloat(req.query.tainted) || validInt(req.query.tainted) ||
validNumber(req.query.tainted) || validOctal(req.query.tainted)) {
axios.get("test.com/" + req.query.tainted); // OK. False Positive
axios.get("test.com/" + req.query.tainted); // OK. False Positive // $ Alert
}
});

View File

@@ -1 +1,2 @@
experimental/StandardLibrary/MultipleArgumentsToSetConstructor.ql
query: experimental/StandardLibrary/MultipleArgumentsToSetConstructor.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,4 +1,4 @@
const vowels = new Set('a', 'e', 'i', 'o', 'u');
const vowels = new Set('a', 'e', 'i', 'o', 'u'); // $ Alert
function isVowel(char) {
return vowels.has(char.toLowerCase());

View File

@@ -1,6 +1,6 @@
let xs = [1, 2, 3];
let ys = [4, 5, 6];
new Set(...xs, ...ys); // NOT OK
new Set(...xs, ...ys); // NOT OK // $ Alert
new Set([...xs, ...ys]); // OK
new Set(xs); // OK
new Set(); // OK

View File

@@ -1 +1,2 @@
meta/analysis-quality/UnpromotedRouteHandlerCandidate.ql
query: meta/analysis-quality/UnpromotedRouteHandlerCandidate.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1,2 @@
meta/analysis-quality/UnpromotedRouteSetupCandidate.ql
query: meta/analysis-quality/UnpromotedRouteSetupCandidate.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1 @@
function handler(request, h){}
function handler(request, h){} // $ Alert[js/unpromoted-route-handler-candidate]

View File

@@ -2,14 +2,14 @@ var http = require('http');
http.createServer(function(req, res){});
unknown.createServer(function(req, res){});
unknown.createServer(function(req, res){}); // $ Alert[js/unpromoted-route-setup-candidate]
var createServer = http.createServer;
createServer(function(req, res){});
http.createServer().on("request", function(req, res){});
unknown.on("request", function(req, res){});
unknown.once("request", function(req, res){});
unknown.on("request", function(req, res){}); // $ Alert[js/unpromoted-route-setup-candidate]
unknown.once("request", function(req, res){}); // $ Alert[js/unpromoted-route-setup-candidate]
function getHandler(){
return function(req, res){};

View File

@@ -4,10 +4,10 @@ var app = express();
var route1 = {
method: 'post',
url: '/foo',
middleWares: [function(req, res){}],
middleWares: [function(req, res){}], // $ Alert[js/unpromoted-route-handler-candidate]
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
};
app[route1.method](route1.url, route1.middleWares, route1.handler);
@@ -19,14 +19,14 @@ var routes = [
url: '/foo',
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
},
{
method: 'post',
url: '/foo',
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
}
];
routes.forEach((route) => {
@@ -39,7 +39,7 @@ var route2 = {
url: '/foo',
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
};
app[route2.method.toLowerCase()](route2.url, route2.handler);
@@ -49,13 +49,13 @@ var route3 = {
url: '/foo',
handler(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
};
function wrap(f){
return function(req, res){
f(req);
}
} // $ Alert[js/unpromoted-route-handler-candidate]
}
app[route3.method](route3.url, wrap(route3.handler));
confuse(wrap); // confuse the type inference

View File

@@ -3,9 +3,9 @@ var app = express();
app.get('/some/path', function(req, res) {})
someOtherApp.get('/some/path', function(req, res) {})
someOtherApp.get('/some/path', function(req, res) {}) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path', function(request, response) {})
someOtherApp.get('/some/path', function(request, response) {}) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path', function(r) {
r.acceptsCharsets()
@@ -27,23 +27,23 @@ someOtherApp.get('/some/path', function(r, s, n) {
n('route')
})
someOtherApp.delete('/some/path', function(req, res) {})
someOtherApp.delete('/some/path', function(req, res) {}) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path',
function(req, res) {},
function(req, res) {})
function(req, res) {}) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path', [
function(req, res) {},
function(req, res) {}
])
]) // $ Alert[js/unpromoted-route-setup-candidate]
someOtherApp.get('/some/path',
function() {},
function(req, res) {})
function(req, res) {}) // $ Alert[js/unpromoted-route-setup-candidate]
function f(req, res) {}
function f(req, res) {} // $ Alert[js/unpromoted-route-handler-candidate]
function f(ctx, next) {
ctx.acceptsCharsets()
@@ -51,25 +51,25 @@ function f(ctx, next) {
function f(req, res) {
req()
}
} // $ Alert[js/unpromoted-route-handler-candidate]
function called(req,res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
called()
function f(req,res) {
return;
}
} // $ Alert[js/unpromoted-route-handler-candidate]
function f(req,res) {
return x;
}
} // $ Alert[js/unpromoted-route-handler-candidate]
function adHocTestsFor_HeuristicRouteHandler() {
function rh_dead(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
function rh_flowToSetup(req, res) {
@@ -84,7 +84,7 @@ function adHocTestsFor_HeuristicRouteHandler() {
function rh_flowToHeuristicSetup(req, res) {
}
unknownApp.get('/some/path', rh_flowToHeuristicSetup)
unknownApp.get('/some/path', rh_flowToHeuristicSetup) // $ Alert[js/unpromoted-route-setup-candidate]
}
function adHocTestsFor_HeuristicRouteSetups() {
@@ -93,22 +93,22 @@ function adHocTestsFor_HeuristicRouteSetups() {
}
app.get('/some/path', rh);
unknownApp.get('/some/path', rh);
unknownApp.get('/some/path', rh); // $ Alert[js/unpromoted-route-setup-candidate]
unknownApp.get('/some/path', [rh]);
unknownApp.get('/some/path', [rh]); // $ Alert[js/unpromoted-route-setup-candidate]
unknownApp.get('/some/path', unknown);
unknownApp.get('/some/path', [unknown]);
unknownApp.get('/some/path', unknown, rh);
unknownApp.get('/some/path', unknown, rh); // $ Alert[js/unpromoted-route-setup-candidate]
}
function adHocTestsFor_HeuristicRouteHandler_withTracking() {
function get_rh_dead() {
return function rh_dead(req, res) {
}
} // $ Alert[js/unpromoted-route-handler-candidate]
}
var rh_dead = get_rh_dead();
@@ -134,7 +134,7 @@ function adHocTestsFor_HeuristicRouteHandler_withTracking() {
}
}
var rh_flowToHeuristicSetup = get_rh_flowToHeuristicSetup();
unknownApp.get('/some/path', rh_flowToHeuristicSetup)
unknownApp.get('/some/path', rh_flowToHeuristicSetup) // $ Alert[js/unpromoted-route-setup-candidate]
}
function adHocTestsFor_HeuristicRouteSetups_withTracking() {
@@ -146,13 +146,13 @@ function adHocTestsFor_HeuristicRouteSetups_withTracking() {
var rh = get_rh();
app.get('/some/path', rh);
unknownApp.get('/some/path', rh);
unknownApp.get('/some/path', rh); // $ Alert[js/unpromoted-route-setup-candidate]
unknownApp.get('/some/path', [rh]);
unknownApp.get('/some/path', [rh]); // $ Alert[js/unpromoted-route-setup-candidate]
unknownApp.get('/some/path', unknown);
unknownApp.get('/some/path', [unknown]);
unknownApp.get('/some/path', unknown, rh);
unknownApp.get('/some/path', unknown, rh); // $ Alert[js/unpromoted-route-setup-candidate]
}

View File

@@ -1 +1 @@
Security/CWE-094/CodeInjection.ql
query: Security/CWE-094/CodeInjection.ql

View File

@@ -1 +1 @@
AlertSuppression.ql
query: AlertSuppression.ql

View File

@@ -1 +1 @@
Diagnostics/ExtractedFiles.ql
query: Diagnostics/ExtractedFiles.ql

View File

@@ -1 +1 @@
Diagnostics/ExtractionErrors.ql
query: Diagnostics/ExtractionErrors.ql

View File

@@ -1 +1 @@
Metrics/Dependencies/ExternalDependencies.ql
query: Metrics/Dependencies/ExternalDependencies.ql

View File

@@ -1 +1 @@
Metrics/FLinesOfCode.ql
query: Metrics/FLinesOfCode.ql

View File

@@ -1 +1 @@
Summary/LinesOfCode.ql
query: Summary/LinesOfCode.ql

View File

@@ -1 +1 @@
Summary/LinesOfUserCode.ql
query: Summary/LinesOfUserCode.ql

View File

@@ -1 +1 @@
definitions.ql
query: definitions.ql

View File

@@ -1 +1 @@
filters/ClassifyFiles.ql
query: filters/ClassifyFiles.ql