mirror of
https://github.com/github/codeql.git
synced 2026-05-05 05:35:13 +02:00
Merge branch 'main' into htmlReg
This commit is contained in:
185
javascript/ql/test/experimental/Security/CWE-918/SSRF.expected
Normal file
185
javascript/ql/test/experimental/Security/CWE-918/SSRF.expected
Normal file
@@ -0,0 +1,185 @@
|
||||
nodes
|
||||
| check-domain.js:16:9:16:27 | url |
|
||||
| check-domain.js:16:15:16:27 | req.query.url |
|
||||
| check-domain.js:16:15:16:27 | req.query.url |
|
||||
| check-domain.js:17:13:17:15 | url |
|
||||
| check-domain.js:17:13:17:15 | url |
|
||||
| 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 |
|
||||
| check-middleware.js:9:13:9:43 | "test.c ... tainted |
|
||||
| check-middleware.js:9:13:9:43 | "test.c ... tainted |
|
||||
| check-middleware.js:9:27:9:43 | req.query.tainted |
|
||||
| check-middleware.js:9:27:9:43 | req.query.tainted |
|
||||
| check-path.js:19:13:19:43 | 'test.c ... tainted |
|
||||
| check-path.js:19:13:19:43 | 'test.c ... tainted |
|
||||
| check-path.js:19:27:19:43 | req.query.tainted |
|
||||
| check-path.js:19:27:19:43 | req.query.tainted |
|
||||
| check-path.js:22:13:22:63 | 'test.c ... ainted) |
|
||||
| check-path.js:22:13:22:63 | 'test.c ... ainted) |
|
||||
| check-path.js:22:27:22:63 | encodeU ... ainted) |
|
||||
| check-path.js:22:46:22:62 | req.query.tainted |
|
||||
| check-path.js:22:46:22:62 | req.query.tainted |
|
||||
| check-path.js:23:13:23:45 | `/addre ... inted}` |
|
||||
| check-path.js:23:13:23:45 | `/addre ... inted}` |
|
||||
| check-path.js:23:27:23:43 | req.query.tainted |
|
||||
| check-path.js:23:27:23:43 | req.query.tainted |
|
||||
| check-path.js:24:13:24:65 | `/addre ... nted)}` |
|
||||
| check-path.js:24:13:24:65 | `/addre ... nted)}` |
|
||||
| check-path.js:24:27:24:63 | encodeU ... ainted) |
|
||||
| check-path.js:24:46:24:62 | req.query.tainted |
|
||||
| check-path.js:24:46:24:62 | req.query.tainted |
|
||||
| check-path.js:33:15:33:45 | 'test.c ... tainted |
|
||||
| check-path.js:33:15:33:45 | 'test.c ... tainted |
|
||||
| check-path.js:33:29:33:45 | req.query.tainted |
|
||||
| check-path.js:33:29:33:45 | req.query.tainted |
|
||||
| check-path.js:37:15:37:45 | 'test.c ... tainted |
|
||||
| check-path.js:37:15:37:45 | 'test.c ... tainted |
|
||||
| check-path.js:37:29:37:45 | req.query.tainted |
|
||||
| check-path.js:37:29:37:45 | req.query.tainted |
|
||||
| check-path.js:45:13:45:44 | `${base ... inted}` |
|
||||
| check-path.js:45:13:45:44 | `${base ... inted}` |
|
||||
| check-path.js:45:26:45:42 | req.query.tainted |
|
||||
| check-path.js:45:26:45:42 | req.query.tainted |
|
||||
| check-regex.js:24:15:24:42 | baseURL ... tainted |
|
||||
| check-regex.js:24:15:24:42 | baseURL ... tainted |
|
||||
| check-regex.js:24:25:24:42 | req.params.tainted |
|
||||
| check-regex.js:24:25:24:42 | req.params.tainted |
|
||||
| check-regex.js:31:15:31:45 | "test.c ... tainted |
|
||||
| check-regex.js:31:15:31:45 | "test.c ... tainted |
|
||||
| check-regex.js:31:29:31:45 | req.query.tainted |
|
||||
| check-regex.js:31:29:31:45 | req.query.tainted |
|
||||
| check-regex.js:34:15:34:42 | baseURL ... tainted |
|
||||
| check-regex.js:34:15:34:42 | baseURL ... tainted |
|
||||
| check-regex.js:34:25:34:42 | req.params.tainted |
|
||||
| check-regex.js:34:25:34:42 | req.params.tainted |
|
||||
| check-regex.js:41:13:41:43 | "test.c ... tainted |
|
||||
| check-regex.js:41:13:41:43 | "test.c ... tainted |
|
||||
| check-regex.js:41:27:41:43 | req.query.tainted |
|
||||
| check-regex.js:41:27:41:43 | req.query.tainted |
|
||||
| check-validator.js:15:15:15:45 | "test.c ... tainted |
|
||||
| check-validator.js:15:15:15:45 | "test.c ... tainted |
|
||||
| check-validator.js:15:29:15:45 | req.query.tainted |
|
||||
| check-validator.js:15:29:15:45 | req.query.tainted |
|
||||
| check-validator.js:27:15:27:45 | "test.c ... tainted |
|
||||
| check-validator.js:27:15:27:45 | "test.c ... tainted |
|
||||
| check-validator.js:27:29:27:45 | req.query.tainted |
|
||||
| check-validator.js:27:29:27:45 | req.query.tainted |
|
||||
| check-validator.js:50:15:50:45 | "test.c ... tainted |
|
||||
| check-validator.js:50:15:50:45 | "test.c ... tainted |
|
||||
| check-validator.js:50:29:50:45 | req.query.tainted |
|
||||
| check-validator.js:50:29:50:45 | req.query.tainted |
|
||||
| check-validator.js:54:9:54:37 | numberURL |
|
||||
| check-validator.js:54:21:54:37 | req.query.tainted |
|
||||
| check-validator.js:54:21:54:37 | req.query.tainted |
|
||||
| check-validator.js:59:15:59:45 | "test.c ... tainted |
|
||||
| check-validator.js:59:15:59:45 | "test.c ... tainted |
|
||||
| check-validator.js:59:29:59:45 | req.query.tainted |
|
||||
| check-validator.js:59:29:59:45 | req.query.tainted |
|
||||
| check-validator.js:62:15:62:37 | "test.c ... mberURL |
|
||||
| check-validator.js:62:15:62:37 | "test.c ... mberURL |
|
||||
| check-validator.js:62:29:62:37 | numberURL |
|
||||
| check-validator.js:68:15:68:45 | "test.c ... tainted |
|
||||
| check-validator.js:68:15:68:45 | "test.c ... tainted |
|
||||
| check-validator.js:68:29:68:45 | req.query.tainted |
|
||||
| check-validator.js:68:29:68:45 | req.query.tainted |
|
||||
edges
|
||||
| check-domain.js:16:9:16:27 | url | check-domain.js:17:13:17:15 | url |
|
||||
| check-domain.js:16:9:16:27 | url | check-domain.js:17:13:17:15 | url |
|
||||
| check-domain.js:16:15:16:27 | req.query.url | check-domain.js:16:9:16:27 | url |
|
||||
| check-domain.js:16:15:16:27 | req.query.url | check-domain.js:16:9:16:27 | url |
|
||||
| check-domain.js:26:15:26:27 | req.query.url | check-domain.js:26:15:26:27 | req.query.url |
|
||||
| check-middleware.js:9:27:9:43 | req.query.tainted | 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 |
|
||||
| check-middleware.js:9:27:9:43 | req.query.tainted | 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 |
|
||||
| check-path.js:19:27:19:43 | req.query.tainted | 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 |
|
||||
| check-path.js:19:27:19:43 | req.query.tainted | 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 |
|
||||
| check-path.js:22:27:22:63 | encodeU ... ainted) | check-path.js:22:13:22:63 | 'test.c ... ainted) |
|
||||
| check-path.js:22:27:22:63 | encodeU ... ainted) | check-path.js:22:13:22:63 | 'test.c ... ainted) |
|
||||
| check-path.js:22:46:22:62 | req.query.tainted | check-path.js:22:27:22:63 | encodeU ... ainted) |
|
||||
| check-path.js:22:46:22:62 | req.query.tainted | check-path.js:22:27:22:63 | encodeU ... ainted) |
|
||||
| check-path.js:23:27:23:43 | req.query.tainted | 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}` |
|
||||
| check-path.js:23:27:23:43 | req.query.tainted | 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}` |
|
||||
| check-path.js:24:27:24:63 | encodeU ... ainted) | check-path.js:24:13:24:65 | `/addre ... nted)}` |
|
||||
| check-path.js:24:27:24:63 | encodeU ... ainted) | check-path.js:24:13:24:65 | `/addre ... nted)}` |
|
||||
| check-path.js:24:46:24:62 | req.query.tainted | check-path.js:24:27:24:63 | encodeU ... ainted) |
|
||||
| check-path.js:24:46:24:62 | req.query.tainted | check-path.js:24:27:24:63 | encodeU ... ainted) |
|
||||
| check-path.js:33:29:33:45 | req.query.tainted | 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 |
|
||||
| check-path.js:33:29:33:45 | req.query.tainted | 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 |
|
||||
| check-path.js:37:29:37:45 | req.query.tainted | 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 |
|
||||
| check-path.js:37:29:37:45 | req.query.tainted | 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 |
|
||||
| check-path.js:45:26:45:42 | req.query.tainted | 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}` |
|
||||
| check-path.js:45:26:45:42 | req.query.tainted | 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}` |
|
||||
| check-regex.js:24:25:24:42 | req.params.tainted | 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 |
|
||||
| check-regex.js:24:25:24:42 | req.params.tainted | 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 |
|
||||
| check-regex.js:31:29:31:45 | req.query.tainted | 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 |
|
||||
| check-regex.js:31:29:31:45 | req.query.tainted | 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 |
|
||||
| check-regex.js:34:25:34:42 | req.params.tainted | 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 |
|
||||
| check-regex.js:34:25:34:42 | req.params.tainted | 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 |
|
||||
| check-regex.js:41:27:41:43 | req.query.tainted | 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 |
|
||||
| check-regex.js:41:27:41:43 | req.query.tainted | 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 |
|
||||
| check-validator.js:15:29:15:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:15:29:15:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:27:29:27:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:27:29:27:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:50:29:50:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:50:29:50:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:54:9:54:37 | numberURL | check-validator.js:62:29:62:37 | numberURL |
|
||||
| check-validator.js:54:21:54:37 | req.query.tainted | check-validator.js:54:9:54:37 | numberURL |
|
||||
| check-validator.js:54:21:54:37 | req.query.tainted | check-validator.js:54:9:54:37 | numberURL |
|
||||
| check-validator.js:59:29:59:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:59:29:59:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:62:29:62:37 | numberURL | check-validator.js:62:15:62:37 | "test.c ... mberURL |
|
||||
| check-validator.js:62:29:62:37 | numberURL | check-validator.js:62:15:62:37 | "test.c ... mberURL |
|
||||
| check-validator.js:68:29:68:45 | req.query.tainted | 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 |
|
||||
| check-validator.js:68:29:68:45 | req.query.tainted | 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 |
|
||||
#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:22:13:22:63 | 'test.c ... ainted) | check-path.js:22:46:22:62 | req.query.tainted | check-path.js:22:13:22:63 | 'test.c ... ainted) | 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:24:13:24:65 | `/addre ... nted)}` | check-path.js:24:46:24:62 | req.query.tainted | check-path.js:24:13:24:65 | `/addre ... nted)}` | 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: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-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 |
|
||||
@@ -0,0 +1 @@
|
||||
./experimental/Security/CWE-918/SSRF.ql
|
||||
@@ -0,0 +1,34 @@
|
||||
// native modules
|
||||
const url = require('url');
|
||||
|
||||
// dependencies
|
||||
const axios = require('axios');
|
||||
const express = require('express');
|
||||
|
||||
// constants
|
||||
const VALID_DOMAINS = ['example.com', 'example-2.com'];
|
||||
|
||||
// start
|
||||
const app = express();
|
||||
|
||||
app.get('/check-with-axios', req => {
|
||||
// without validation
|
||||
const url = req.query.url;
|
||||
axios.get(url); //SSRF
|
||||
|
||||
// validating domain only
|
||||
const decodedURI = decodeURIComponent(req.query.url);
|
||||
const { hostname } = url.parse(decodedURI);
|
||||
|
||||
const { hostname } = url.parse(decodedURI);
|
||||
|
||||
if (isValidDomain(hostname, validDomains)) {
|
||||
axios.get(req.query.url); //SSRF
|
||||
}
|
||||
});
|
||||
|
||||
const isValidDomain = (hostname, validDomains) => (
|
||||
validDomains.some(domain => (
|
||||
hostname === domain || hostname.endsWith(`.${domain}`))
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,19 @@
|
||||
// dependencies
|
||||
const axios = require('axios');
|
||||
const express = require('express');
|
||||
|
||||
// start
|
||||
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
|
||||
});
|
||||
|
||||
|
||||
const validationMiddleware = (req, res, next) => {
|
||||
if (!Number.isInteger(req.query.tainted)) {
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// native modules
|
||||
const path = require('path');
|
||||
const url = require('url');
|
||||
|
||||
// dependencies
|
||||
const axios = require('axios');
|
||||
const express = require('express');
|
||||
|
||||
// constants
|
||||
const VALID_PATHS = ['/api/users/me', '/help', '/system/health'];
|
||||
|
||||
// start
|
||||
const app = express();
|
||||
|
||||
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/' + Number(req.query.tainted)); // OK
|
||||
axios.get('test.com/' + req.user.id); // OK
|
||||
axios.get('test.com/' + encodeURIComponent(req.query.tainted)); // SSRF
|
||||
axios.get(`/addresses/${req.query.tainted}`); // SSRF
|
||||
axios.get(`/addresses/${encodeURIComponent(req.query.tainted)}`); // SSRF
|
||||
|
||||
if (Number.isInteger(req.query.tainted)) {
|
||||
axios.get('test.com/' + req.query.tainted); // OK
|
||||
}
|
||||
|
||||
if (isValidInput(req.query.tainted)){
|
||||
axios.get('test.com/' + req.query.tainted); // OK
|
||||
} else {
|
||||
axios.get('test.com/' + req.query.tainted); // SSRF
|
||||
}
|
||||
|
||||
if (doesntCheckAnything(req.query.tainted)) {
|
||||
axios.get('test.com/' + req.query.tainted); // SSRF
|
||||
}
|
||||
|
||||
if (isValidPath(req.query.tainted, VALID_PATHS)) {
|
||||
axios.get('test.com/' + req.query.tainted) // OK
|
||||
}
|
||||
|
||||
let baseURL = require('config').base
|
||||
axios.get(`${baseURL}${req.query.tainted}`); // SSRF
|
||||
|
||||
if(!isValidInput(req.query.tainted)) {
|
||||
return;
|
||||
}
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
});
|
||||
|
||||
const isValidPath = (path, validPaths) => validPaths.includes(path);
|
||||
|
||||
const isValidInput = (path) => Number.isInteger(path);
|
||||
|
||||
const doesntCheckAnything = (path) => true;
|
||||
@@ -0,0 +1,46 @@
|
||||
// dependencies
|
||||
const axios = require('axios');
|
||||
const express = require('express');
|
||||
|
||||
// start
|
||||
const app = express();
|
||||
|
||||
app.get('/check-with-axios', req => {
|
||||
if (req.query.tainted.match(/^[0-9a-z]+$/)) { // letters and numbers
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (req.query.tainted.match(/^[0-9a-z\-_]+$/)) { // letters, numbers, - and _
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (req.query.tainted.match(/^.*$/)) { // anything
|
||||
axios.get("test.com/" + req.query.tainted); // SSRF - False Negative
|
||||
}
|
||||
|
||||
const baseURL = "test.com/"
|
||||
if (isValidPath(req.params.tainted) ) {
|
||||
axios.get(baseURL + req.params.tainted); // OK
|
||||
}
|
||||
if (!isValidPath(req.params.tainted) ) {
|
||||
axios.get(baseURL + req.params.tainted); // SSRF
|
||||
} 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
|
||||
}
|
||||
if (!isInBlacklist(req.params.tainted) ) {
|
||||
axios.get(baseURL + req.params.tainted); // SSRF
|
||||
}
|
||||
|
||||
if (!isValidPath(req.params.tainted)) {
|
||||
return;
|
||||
}
|
||||
|
||||
axios.get("test.com/" + req.query.tainted); // OK - False Positive
|
||||
});
|
||||
|
||||
const isValidPath = path => path.match(/^[0-9a-z]+$/);
|
||||
|
||||
const isInBlackList = path => path.match(/^[/\.%]+$/);
|
||||
@@ -0,0 +1,98 @@
|
||||
// dependencies
|
||||
const axios = require('axios');
|
||||
const express = require('express');
|
||||
const validator = require('validator');
|
||||
|
||||
// start
|
||||
const app = express();
|
||||
|
||||
app.get("/check-with-axios", req => {
|
||||
// alphanumeric
|
||||
if (validator.isAlphanumeric(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (isAlphanumeric(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // SSRF
|
||||
}
|
||||
if (validAlphanumeric(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (validAlpha(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (validNumber(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (wrongValidation(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // SSRF
|
||||
}
|
||||
|
||||
// numbers
|
||||
if (validHexadecimal(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (validHexaColor(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (validDecimal(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (validFloat(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (validInt(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (validOctal(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK
|
||||
}
|
||||
if (validHexa(req.query.tainted)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK. False Positive
|
||||
}
|
||||
|
||||
// with simple assignation
|
||||
const numberURL = req.query.tainted;
|
||||
if (validNumber(numberURL)) {
|
||||
axios.get("test.com/" + numberURL); // OK
|
||||
}
|
||||
if (validNumber(numberURL)) {
|
||||
axios.get("test.com/" + req.query.tainted); // OK. False Positive
|
||||
}
|
||||
if (validNumber(req.query.tainted)) {
|
||||
axios.get("test.com/" + numberURL); // OK. False Positive
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
// safe validators
|
||||
const validAlphanumeric = url => validator.isAlphanumeric(url);
|
||||
|
||||
const validAlpha = url => validator.isAlpha(url);
|
||||
|
||||
const validDecimal = url => validator.isDecimal(url);
|
||||
|
||||
const validFloat = url => validator.isFloat(url);
|
||||
|
||||
const validInt = url => validator.isInt(url);
|
||||
|
||||
const validNumber = url => validator.isNumeric(url);
|
||||
|
||||
const validOctal = url => validator.isOctal(url);
|
||||
|
||||
const validHexa = url => validator.isHexadecimal(url) || validator.isHexColor(url);
|
||||
|
||||
const validHexadecimal = url => validator.isHexadecimal(url);
|
||||
|
||||
const validHexaColor = url => validator.isHexColor(url);
|
||||
|
||||
const validUUID = url => validator.isUUID(url);
|
||||
|
||||
// unsafe validators
|
||||
const wrongValidation = url => validator.isByteLength(url, {min:4,max:8});
|
||||
|
||||
const isAlphanumeric = url => true;
|
||||
@@ -0,0 +1,182 @@
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
app.get('/direct-ternary-operator', function (req, res) {
|
||||
let taintedURL = req.params.url
|
||||
|
||||
let v = req.params.url ? req.params.url == "someURL" : false
|
||||
if (v) {
|
||||
req_frontend_restclient.get(req.params.url) // OK
|
||||
}
|
||||
|
||||
let v1 = taintedURL ? taintedURL == "someURL" : false
|
||||
if (v1) {
|
||||
req_frontend_restclient.get(taintedURL) // OK
|
||||
}
|
||||
|
||||
let v2 = taintedURL ? valid(taintedURL) : false
|
||||
if (v2) {
|
||||
req_frontend_restclient.get(taintedURL) // OK
|
||||
}
|
||||
|
||||
let v3 = req.params.url ? valid(req.params.url) : false
|
||||
if (v3) {
|
||||
req_frontend_restclient.get(req.params.url) // OK
|
||||
}
|
||||
|
||||
let v4 = req.params.url == undefined ? false : valid(req.params.url)
|
||||
if (v4) {
|
||||
req_frontend_restclient.get(req.params.url) // OK
|
||||
}
|
||||
|
||||
let v5 = req.params.url == undefined ? true : valid(req.params.url)
|
||||
if (v5) {
|
||||
req_frontend_restclient.get(req.params.url) // SSRF
|
||||
}
|
||||
|
||||
let v6 = req.params.url ? valid(req.params.url) : true
|
||||
if (v6) {
|
||||
req_frontend_restclient.get(req.params.url) // SSRF
|
||||
}
|
||||
|
||||
let f = false
|
||||
let v7 = req.params.url ? valid(req.params.url) : true
|
||||
if (v7) {
|
||||
req_frontend_restclient.get(req.params.url) // SSRF
|
||||
}
|
||||
|
||||
let v8 = req.params.url == undefined ? false : valid(req.params.url)
|
||||
if (!v8) {
|
||||
return
|
||||
}
|
||||
req_frontend_restclient.get(req.params.url) // OK
|
||||
})
|
||||
|
||||
app.get('/functions', function (req, res) {
|
||||
let taintedURL = req.params.url
|
||||
|
||||
if (valid2(taintedURL)) {
|
||||
req_frontend_restclient.get(taintedURL) // OK
|
||||
}
|
||||
|
||||
if (!invalid(taintedURL)) {
|
||||
req_frontend_restclient.get(taintedURL) // False positive
|
||||
}
|
||||
|
||||
if (valid2(req.params.url)){
|
||||
req_frontend_restclient.get(req.params.url) // OK
|
||||
}
|
||||
|
||||
if (!assertAlphanumeric(req.params.url)) {
|
||||
return
|
||||
}
|
||||
req_frontend_restclient.get(req.params.url); // OK
|
||||
})
|
||||
|
||||
app.get('/normal-use-of-ternary-operator', function (req, res) {
|
||||
let taintedURL = req.params.url
|
||||
|
||||
let url = valid(req.params.url) ? req.params.url : undefined
|
||||
req_frontend_restclient.get(url) // OK
|
||||
|
||||
let url = valid(taintedURL) ? taintedURL : undefined
|
||||
req_frontend_restclient.get(url) // OK
|
||||
|
||||
let url4 = req.params.url.match(/^[\w.-]+$/) ? req.params.url : undefined
|
||||
req_frontend_restclient.get(url4) // OK
|
||||
})
|
||||
|
||||
app.get('/throw-errors', function (req, res) {
|
||||
req_frontend_restclient.get(valid3(req.params.url)) // False positive
|
||||
|
||||
req_frontend_restclient.get(assertOther(req.params.url)); // False positive
|
||||
|
||||
req_frontend_restclient.get(assertOther2(req.params.url)); // False positive
|
||||
});
|
||||
|
||||
app.get('/bad-endpoint', function (req, res) {
|
||||
req_frontend_restclient.get(req.params.url); // SSRF
|
||||
|
||||
const valid = req.params.url ? req.params.url == "someURL" : false
|
||||
if (!valid) {
|
||||
throw new Error(`Invalid parameter: "${req.params.url}", must be alphanumeric`);
|
||||
}
|
||||
req_frontend_restclient.get(req.params.url); // OK
|
||||
})
|
||||
|
||||
|
||||
app.get('/bad-endpoint-variable', function (req, res) {
|
||||
let taintedURL = req.params.url
|
||||
req_frontend_restclient.get(taintedURL); // SSRF
|
||||
|
||||
const valid = taintedURL ? taintedURL == "someURL" : false
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
req_frontend_restclient.get(taintedURL); // False positive
|
||||
})
|
||||
|
||||
app.get('/not-invalid', function (req, res) {
|
||||
const invalidParam = req.params.url ? !Number.isInteger(req.params.url) : false
|
||||
if (invalidParam) {
|
||||
return
|
||||
}
|
||||
req_frontend_restclient.get(req.params.url); // False positive
|
||||
})
|
||||
|
||||
|
||||
app.get('/bad-endpoint-2', function (req, res) {
|
||||
other(req.params.url)
|
||||
})
|
||||
|
||||
function other(taintedURL) {
|
||||
req_frontend_restclient.get(taintedURL); // SSRF
|
||||
|
||||
const valid = taintedURL ? taintedURL == "someURL" : false
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
req_frontend_restclient.get(taintedURL); // False positive
|
||||
}
|
||||
|
||||
function assertAlphanumeric(value) {
|
||||
return value ? value.match(/^[\w.-]+$/) : false;
|
||||
}
|
||||
|
||||
function assertOther(value) {
|
||||
const valid = value ? !!value.match(/^[\w.-]+$/) : false;
|
||||
if (!valid) {
|
||||
throw new Error(`Invalid parameter: "${value}", must be alphanumeric`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function assertOther2(value) {
|
||||
const valid = value ? value.match(/^[\w.-]+$/) : false;
|
||||
if (!valid) {
|
||||
throw new Error(`Invalid parameter: "${value}", must be alphanumeric`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function invalid(value) {
|
||||
return value ? !Number.isInteger(value) : true
|
||||
}
|
||||
|
||||
function valid(value) {
|
||||
return value.match(/^[\w.-]+$/)
|
||||
}
|
||||
|
||||
function valid2(value) {
|
||||
return value ? value == "someURL" : false
|
||||
}
|
||||
|
||||
function valid3(value) {
|
||||
const valid = value ? value == "someURL" : false
|
||||
if (!valid) {
|
||||
throw new Error(`Invalid parameter: "${value}", must be alphanumeric`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -4,5 +4,5 @@ from ClassDefinition class_, FieldDefinition field
|
||||
where
|
||||
class_.getAField() = field and
|
||||
field.isStatic() and
|
||||
field.getInit().getFirstControlFlowNode().getAPredecessor*() = class_.(ControlFlowNode)
|
||||
field.getInit().getFirstControlFlowNode().getAPredecessor*() = class_
|
||||
select field, "Field initializer occurs after its class is created"
|
||||
|
||||
@@ -4,4 +4,4 @@ from FunctionWithAnalyzedParameters f, SimpleParameter p, AnalyzedVarDef var
|
||||
where
|
||||
f.argumentPassing(p, _) and
|
||||
var.getAVariable() = p.getVariable()
|
||||
select p, var.(AnalyzedVarDef).getAnAssignedValue()
|
||||
select p, var.getAnAssignedValue()
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
abstract class Q {
|
||||
abstract test();
|
||||
static test() {}
|
||||
|
||||
method() {
|
||||
this.test(); // OK
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,35 @@ nodes
|
||||
| json-schema-validator.js:59:22:59:26 | query |
|
||||
| json-schema-validator.js:61:22:61:26 | query |
|
||||
| json-schema-validator.js:61:22:61:26 | query |
|
||||
| ldap.js:20:7:20:34 | q |
|
||||
| ldap.js:20:11:20:34 | url.par ... , true) |
|
||||
| ldap.js:20:21:20:27 | req.url |
|
||||
| ldap.js:20:21:20:27 | req.url |
|
||||
| ldap.js:22:7:22:33 | username |
|
||||
| ldap.js:22:18:22:18 | q |
|
||||
| ldap.js:22:18:22:24 | q.query |
|
||||
| ldap.js:22:18:22:33 | q.query.username |
|
||||
| ldap.js:25:13:25:57 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:25:24:25:31 | username |
|
||||
| ldap.js:25:46:25:53 | username |
|
||||
| ldap.js:28:30:28:34 | opts1 |
|
||||
| ldap.js:28:30:28:34 | opts1 |
|
||||
| ldap.js:32:5:32:61 | { filte ... e}))` } |
|
||||
| ldap.js:32:5:32:61 | { filte ... e}))` } |
|
||||
| ldap.js:32:15:32:59 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:32:26:32:33 | username |
|
||||
| ldap.js:32:48:32:55 | username |
|
||||
| ldap.js:63:9:65:3 | parsedFilter |
|
||||
| ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) |
|
||||
| ldap.js:64:5:64:49 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:64:16:64:23 | username |
|
||||
| ldap.js:64:38:64:45 | username |
|
||||
| ldap.js:66:30:66:53 | { filte ... ilter } |
|
||||
| ldap.js:66:30:66:53 | { filte ... ilter } |
|
||||
| ldap.js:66:40:66:51 | parsedFilter |
|
||||
| ldap.js:68:27:68:42 | `cn=${username}` |
|
||||
| ldap.js:68:27:68:42 | `cn=${username}` |
|
||||
| ldap.js:68:33:68:40 | username |
|
||||
| marsdb-flow-to.js:10:9:10:18 | query |
|
||||
| marsdb-flow-to.js:10:17:10:18 | {} |
|
||||
| marsdb-flow-to.js:11:17:11:24 | req.body |
|
||||
@@ -444,6 +473,37 @@ edges
|
||||
| json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) | json-schema-validator.js:50:15:50:48 | query |
|
||||
| json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) |
|
||||
| json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) |
|
||||
| ldap.js:20:7:20:34 | q | ldap.js:22:18:22:18 | q |
|
||||
| ldap.js:20:11:20:34 | url.par ... , true) | ldap.js:20:7:20:34 | q |
|
||||
| ldap.js:20:21:20:27 | req.url | ldap.js:20:11:20:34 | url.par ... , true) |
|
||||
| ldap.js:20:21:20:27 | req.url | ldap.js:20:11:20:34 | url.par ... , true) |
|
||||
| ldap.js:22:7:22:33 | username | ldap.js:25:24:25:31 | username |
|
||||
| ldap.js:22:7:22:33 | username | ldap.js:25:46:25:53 | username |
|
||||
| ldap.js:22:7:22:33 | username | ldap.js:32:26:32:33 | username |
|
||||
| ldap.js:22:7:22:33 | username | ldap.js:32:48:32:55 | username |
|
||||
| ldap.js:22:7:22:33 | username | ldap.js:64:16:64:23 | username |
|
||||
| ldap.js:22:7:22:33 | username | ldap.js:64:38:64:45 | username |
|
||||
| ldap.js:22:7:22:33 | username | ldap.js:68:33:68:40 | username |
|
||||
| ldap.js:22:18:22:18 | q | ldap.js:22:18:22:24 | q.query |
|
||||
| ldap.js:22:18:22:24 | q.query | ldap.js:22:18:22:33 | q.query.username |
|
||||
| ldap.js:22:18:22:33 | q.query.username | ldap.js:22:7:22:33 | username |
|
||||
| ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | ldap.js:28:30:28:34 | opts1 |
|
||||
| ldap.js:25:13:25:57 | `(\|(nam ... ame}))` | ldap.js:28:30:28:34 | opts1 |
|
||||
| ldap.js:25:24:25:31 | username | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:25:46:25:53 | username | ldap.js:25:13:25:57 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | ldap.js:32:5:32:61 | { filte ... e}))` } |
|
||||
| ldap.js:32:15:32:59 | `(\|(nam ... ame}))` | ldap.js:32:5:32:61 | { filte ... e}))` } |
|
||||
| ldap.js:32:26:32:33 | username | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:32:48:32:55 | username | ldap.js:32:15:32:59 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:63:9:65:3 | parsedFilter | ldap.js:66:40:66:51 | parsedFilter |
|
||||
| ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) | ldap.js:63:9:65:3 | parsedFilter |
|
||||
| ldap.js:64:5:64:49 | `(\|(nam ... ame}))` | ldap.js:63:24:65:3 | ldap.pa ... ))`\\n ) |
|
||||
| ldap.js:64:16:64:23 | username | ldap.js:64:5:64:49 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:64:38:64:45 | username | ldap.js:64:5:64:49 | `(\|(nam ... ame}))` |
|
||||
| ldap.js:66:40:66:51 | parsedFilter | ldap.js:66:30:66:53 | { filte ... ilter } |
|
||||
| ldap.js:66:40:66:51 | parsedFilter | ldap.js:66:30:66:53 | { filte ... ilter } |
|
||||
| ldap.js:68:33:68:40 | username | ldap.js:68:27:68:42 | `cn=${username}` |
|
||||
| ldap.js:68:33:68:40 | username | ldap.js:68:27:68:42 | `cn=${username}` |
|
||||
| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query |
|
||||
| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query |
|
||||
| marsdb-flow-to.js:10:17:10:18 | {} | marsdb-flow-to.js:10:9:10:18 | query |
|
||||
@@ -852,6 +912,10 @@ edges
|
||||
| json-schema-validator.js:55:22:55:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:55:22:55:26 | query | This query depends on $@. | json-schema-validator.js:50:34:50:47 | req.query.data | a user-provided value |
|
||||
| json-schema-validator.js:59:22:59:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:59:22:59:26 | query | This query depends on $@. | json-schema-validator.js:50:34:50:47 | req.query.data | a user-provided value |
|
||||
| json-schema-validator.js:61:22:61:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:61:22:61:26 | query | This query depends on $@. | json-schema-validator.js:50:34:50:47 | req.query.data | a user-provided value |
|
||||
| ldap.js:28:30:28:34 | opts1 | ldap.js:20:21:20:27 | req.url | ldap.js:28:30:28:34 | opts1 | This query depends on $@. | ldap.js:20:21:20:27 | req.url | a user-provided value |
|
||||
| ldap.js:32:5:32:61 | { filte ... e}))` } | ldap.js:20:21:20:27 | req.url | ldap.js:32:5:32:61 | { filte ... e}))` } | This query depends on $@. | ldap.js:20:21:20:27 | req.url | a user-provided value |
|
||||
| ldap.js:66:30:66:53 | { filte ... ilter } | ldap.js:20:21:20:27 | req.url | ldap.js:66:30:66:53 | { filte ... ilter } | This query depends on $@. | ldap.js:20:21:20:27 | req.url | a user-provided value |
|
||||
| ldap.js:68:27:68:42 | `cn=${username}` | ldap.js:20:21:20:27 | req.url | ldap.js:68:27:68:42 | `cn=${username}` | This query depends on $@. | ldap.js:20:21:20:27 | req.url | a user-provided value |
|
||||
| marsdb-flow-to.js:14:17:14:21 | query | marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:14:17:14:21 | query | This query depends on $@. | marsdb-flow-to.js:11:17:11:24 | req.body | a user-provided value |
|
||||
| marsdb.js:16:12:16:16 | query | marsdb.js:13:17:13:24 | req.body | marsdb.js:16:12:16:16 | query | This query depends on $@. | marsdb.js:13:17:13:24 | req.body | a user-provided value |
|
||||
| minimongo.js:18:12:18:16 | query | minimongo.js:15:17:15:24 | req.body | minimongo.js:18:12:18:16 | query | This query depends on $@. | minimongo.js:15:17:15:24 | req.body | a user-provided value |
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
const http = require("http");
|
||||
const url = require("url");
|
||||
const ldap = require("ldapjs");
|
||||
const client = ldap.createClient({
|
||||
url: "ldap://127.0.0.1:1389",
|
||||
});
|
||||
|
||||
// https://github.com/vesse/node-ldapauth-fork/commit/3feea43e243698bcaeffa904a7324f4d96df60e4
|
||||
const sanitizeInput = function (input) {
|
||||
return input
|
||||
.replace(/\*/g, "\\2a")
|
||||
.replace(/\(/g, "\\28")
|
||||
.replace(/\)/g, "\\29")
|
||||
.replace(/\\/g, "\\5c")
|
||||
.replace(/\0/g, "\\00")
|
||||
.replace(/\//g, "\\2f");
|
||||
};
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
let q = url.parse(req.url, true);
|
||||
|
||||
let username = q.query.username;
|
||||
|
||||
var opts1 = {
|
||||
filter: `(|(name=${username})(username=${username}))`,
|
||||
};
|
||||
|
||||
client.search("o=example", opts1, function (err, res) {}); // NOT OK
|
||||
|
||||
client.search(
|
||||
"o=example",
|
||||
{ filter: `(|(name=${username})(username=${username}))` }, // NOT OK
|
||||
function (err, res) {}
|
||||
);
|
||||
|
||||
// GOOD
|
||||
client.search(
|
||||
"o=example",
|
||||
{ // OK
|
||||
filter: `(|(name=${sanitizeInput(username)})(username=${sanitizeInput(
|
||||
username
|
||||
)}))`,
|
||||
},
|
||||
function (err, res) {}
|
||||
);
|
||||
|
||||
// GOOD (https://github.com/ldapjs/node-ldapjs/issues/181)
|
||||
let f = new OrFilter({
|
||||
filters: [
|
||||
new EqualityFilter({
|
||||
attribute: "name",
|
||||
value: username,
|
||||
}),
|
||||
new EqualityFilter({
|
||||
attribute: "username",
|
||||
value: username,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
client.search("o=example", { filter: f }, function (err, res) {});
|
||||
|
||||
const parsedFilter = ldap.parseFilter(
|
||||
`(|(name=${username})(username=${username}))`
|
||||
);
|
||||
client.search("o=example", { filter: parsedFilter }, function (err, res) {}); // NOT OK
|
||||
|
||||
const dn = ldap.parseDN(`cn=${username}`, function (err, dn) {}); // NOT OK
|
||||
});
|
||||
|
||||
server.listen(389, () => {});
|
||||
@@ -0,0 +1,20 @@
|
||||
| tst-httpOnly.js:11:9:15:2 | session ... BAD\\n}) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:29:9:29:21 | session(sess) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:38:9:38:22 | session(sess2) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:47:9:47:22 | session(sess3) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:51:9:55:2 | session ... BAD\\n}) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:68:5:73:10 | res.coo ... }) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:78:5:81:10 | res.coo ... }) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:101:5:101:43 | res.coo ... ptions) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:109:5:109:43 | res.coo ... ptions) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:118:5:118:43 | res.coo ... ptions) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:137:5:137:43 | res.coo ... ptions) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:148:5:148:41 | res.coo ... ptions) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:159:5:159:43 | res.coo ... ptions) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:170:5:170:40 | res.coo ... ptions) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:209:37:209:51 | "authKey=ninja" | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:229:38:229:52 | "authKey=ninja" | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:289:37:289:59 | `authKe ... {attr}` | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:303:9:307:2 | session ... BAD\\n}) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:320:9:324:2 | session ... tter\\n}) | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
| tst-httpOnly.js:330:37:330:68 | "sessio ... onKey() | Sensitive server cookie is missing 'httpOnly' flag. |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE-1004/ClientExposedCookie.ql
|
||||
@@ -1,20 +0,0 @@
|
||||
| test_cookie-session.js:12:9:16:2 | session ... BAD\\n}) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_cookie-session.js:30:9:30:21 | session(sess) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_cookie-session.js:39:9:39:22 | session(sess2) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_cookie-session.js:48:9:48:22 | session(sess3) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_cookie-session.js:52:9:56:2 | session ... BAD\\n}) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_express-session.js:11:9:15:2 | session ... BAD\\n}) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_express-session.js:28:9:32:2 | session ... tter\\n}) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_httpserver.js:7:37:7:48 | "auth=ninja" | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_httpserver.js:27:37:27:70 | ["auth= ... cript"] | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_httpserver.js:57:37:57:80 | ["auth= ... cript"] | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_httpserver.js:87:37:87:59 | `sessio ... {attr}` | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:15:5:20:10 | res.coo ... }) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:25:5:28:10 | res.coo ... }) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:48:5:48:43 | res.coo ... ptions) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:56:5:56:43 | res.coo ... ptions) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:65:5:65:43 | res.coo ... ptions) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:84:5:84:43 | res.coo ... ptions) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:95:5:95:41 | res.coo ... ptions) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:106:5:106:43 | res.coo ... ptions) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
| test_responseCookie.js:117:5:117:40 | res.coo ... ptions) | Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie. |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
@@ -1,56 +0,0 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('cookie-session')
|
||||
const expiryDate = new Date(Date.now() + 60 * 60 * 1000)
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: true, // GOOD
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: false // BAD
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
secure: true // GOOD, httpOnly is true by default
|
||||
}))
|
||||
|
||||
var sess = {
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
}
|
||||
|
||||
sess.httpOnly = false;
|
||||
app.use(session(sess)) // BAD
|
||||
|
||||
var sess2 = {
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: true,
|
||||
}
|
||||
|
||||
sess2.httpOnly = false;
|
||||
app.use(session(sess2)) // BAD
|
||||
|
||||
var sess3 = {
|
||||
name: 'mycookie',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: true,
|
||||
}
|
||||
|
||||
sess3.httpOnly = false;
|
||||
app.use(session(sess3)) // BAD, It is a session cookie, name doesn't matter
|
||||
|
||||
var flag = false
|
||||
var flag2 = flag
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: flag2 // BAD
|
||||
}))
|
||||
@@ -1,32 +0,0 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('express-session')
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: { httpOnly: true }, // GOOD
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: { httpOnly: false } // BAD
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: { secure: true } // GOOD, httpOnly is true by default
|
||||
}))
|
||||
|
||||
app.use(session({ // GOOD, httpOnly is true by default
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2']
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'mycookie',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: { httpOnly: false } // BAD, It is a session cookie, name doesn't matter
|
||||
}))
|
||||
@@ -1,91 +0,0 @@
|
||||
const http = require('http');
|
||||
|
||||
function test1() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", "auth=ninja");
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test2() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD
|
||||
res.setHeader("Set-Cookie", "auth=ninja; HttpOnly");
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test3() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", ["auth=ninja", "token=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test4() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD
|
||||
res.setHeader("Set-Cookie", ["auth=ninja; HttpOnly"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test5() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD, case insensitive
|
||||
res.setHeader("Set-Cookie", ["auth=ninja; httponly"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test6() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", ["auth=ninja; httponly", "token=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test7() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// Good, not auth related
|
||||
res.setHeader("Set-Cookie", ["foo=ninja", "bar=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test8() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
let attr = "; httponly"
|
||||
res.setHeader("Set-Cookie", `session=ninja ${attr}`); // Good, httponly string expression
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test9() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
let attr = "; secure"
|
||||
res.setHeader("Set-Cookie", `session=ninja ${attr}`); // Bad, not httponly string expression
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('session', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true, // GOOD
|
||||
secure: false
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('session', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false, // BAD
|
||||
secure: false
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('session', 'value',
|
||||
{
|
||||
maxAge: 9000000000
|
||||
});
|
||||
res.end('ok') // BAD
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true, // GOOD
|
||||
secure: false
|
||||
}
|
||||
res.cookie('session', 'value', options);
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false, // BAD
|
||||
secure: false
|
||||
}
|
||||
res.cookie('session', 'value', options);
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000
|
||||
}
|
||||
res.cookie('session', 'value', options); // BAD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000
|
||||
}
|
||||
options.httpOnly = false;
|
||||
res.cookie('session', 'value', options); // BAD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000
|
||||
}
|
||||
options.httpOnly = true;
|
||||
res.cookie('session', 'value', options); // GOOD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = false;
|
||||
res.cookie('session', 'value', options); // BAD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = false;
|
||||
let session = "blabla"
|
||||
res.cookie(session, 'value', options); // BAD, var name likely auth related
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = false;
|
||||
let o = { session: "blabla" }
|
||||
res.cookie(o.session, 'value', options); // BAD, var name likely auth related
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = false;
|
||||
let blabla = "session"
|
||||
res.cookie(blabla, 'value', options); // BAD, var name likely auth related
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
}
|
||||
options.httpOnly = true;
|
||||
res.cookie('session', 'value', options); // GOOD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = true;
|
||||
res.cookie('session', 'value', options); // GOOD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
res.cookie('mycookie', 'value', options); // GOOD, name likely is not auth sensitive
|
||||
res.end('ok')
|
||||
})
|
||||
334
javascript/ql/test/query-tests/Security/CWE-1004/tst-httpOnly.js
Normal file
334
javascript/ql/test/query-tests/Security/CWE-1004/tst-httpOnly.js
Normal file
@@ -0,0 +1,334 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('cookie-session')
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: true, // GOOD
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: false // BAD
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
secure: true // GOOD, httpOnly is true by default
|
||||
}))
|
||||
|
||||
var sess = {
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
}
|
||||
|
||||
sess.httpOnly = false;
|
||||
app.use(session(sess)) // BAD
|
||||
|
||||
var sess2 = {
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: true,
|
||||
}
|
||||
|
||||
sess2.httpOnly = false;
|
||||
app.use(session(sess2)) // BAD
|
||||
|
||||
var sess3 = {
|
||||
name: 'mycookie',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: true,
|
||||
}
|
||||
|
||||
sess3.httpOnly = false;
|
||||
app.use(session(sess3)) // BAD, It is a session cookie, name doesn't matter
|
||||
|
||||
var flag = false
|
||||
var flag2 = flag
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
httpOnly: flag2 // BAD
|
||||
}))
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('authkey', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true, // GOOD
|
||||
secure: false
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('authkey', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false, // BAD
|
||||
secure: false
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('authkey', 'value',
|
||||
{
|
||||
maxAge: 9000000000
|
||||
});
|
||||
res.end('ok') // BAD
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true, // GOOD
|
||||
secure: false
|
||||
}
|
||||
res.cookie('authkey', 'value', options);
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false, // BAD
|
||||
secure: false
|
||||
}
|
||||
res.cookie('authkey', 'value', options);
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000
|
||||
}
|
||||
res.cookie('authkey', 'value', options); // BAD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000
|
||||
}
|
||||
options.httpOnly = false;
|
||||
res.cookie('authkey', 'value', options); // BAD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000
|
||||
}
|
||||
options.httpOnly = true;
|
||||
res.cookie('authkey', 'value', options); // GOOD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = false;
|
||||
res.cookie('authkey', 'value', options); // BAD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = false;
|
||||
let authKey = "blabla"
|
||||
res.cookie(authKey, 'value', options); // BAD, var name likely auth related
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = false;
|
||||
let o = { authKey: "blabla" }
|
||||
res.cookie(o.authKey, 'value', options); // BAD, var name likely auth related
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = false;
|
||||
let blabla = "authKey"
|
||||
res.cookie(blabla, 'value', options); // BAD, var name likely auth related
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
}
|
||||
options.httpOnly = true;
|
||||
res.cookie('authkey', 'value', options); // GOOD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
options.httpOnly = true;
|
||||
res.cookie('authkey', 'value', options); // GOOD
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: false,
|
||||
}
|
||||
res.cookie('mycookie', 'value', options); // GOOD, name likely is not auth sensitive
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
const http = require('http');
|
||||
|
||||
function test1() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", "authKey=ninja");
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test2() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD
|
||||
res.setHeader("Set-Cookie", "auth=ninja; HttpOnly");
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test3() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", ["authKey=ninja", "token=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test4() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD
|
||||
res.setHeader("Set-Cookie", ["auth=ninja; HttpOnly"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test5() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD, case insensitive
|
||||
res.setHeader("Set-Cookie", ["auth=ninja; httponly"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test6() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// OK - the sensitive cookie has httpOnly set
|
||||
res.setHeader("Set-Cookie", ["authKey=ninja; httponly", "token=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test7() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// Good, not auth related
|
||||
res.setHeader("Set-Cookie", ["foo=ninja", "bar=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test8() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
let attr = "; httponly"
|
||||
res.setHeader("Set-Cookie", `session=ninja ${attr}`); // Good, httponly string expression
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test9() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
let attr = "; secure"
|
||||
res.setHeader("Set-Cookie", `authKey=ninja ${attr}`); // Bad, not httponly string expression
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
const session = require('express-session')
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: { httpOnly: true }, // GOOD
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: { httpOnly: false } // BAD
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: { secure: true } // GOOD, httpOnly is true by default
|
||||
}))
|
||||
|
||||
app.use(session({ // GOOD, httpOnly is true by default
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2']
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'mycookie',
|
||||
keys: ['key1', 'key2'],
|
||||
cookie: { httpOnly: false } // BAD, It is a session cookie, name doesn't matter
|
||||
}))
|
||||
|
||||
const http = require('http');
|
||||
function test10() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader("Set-Cookie", "sessionKey=" + makeSessionKey()); // BAD
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
| tst-cleartextCookie.js:5:5:10:10 | res.coo ... }) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:20:5:20:43 | res.coo ... ptions) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:35:1:35:52 | js_cook ... alse }) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:44:37:44:51 | "authKey=ninja" | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:64:13:64:27 | "authKey=ninja" | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:97:13:97:25 | "authKey=foo" | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:108:9:111:2 | session ... T OK\\n}) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:113:9:116:2 | session ... T OK\\n}) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:118:9:121:2 | session ... T OK\\n}) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:128:9:128:21 | session(sess) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:152:9:160:2 | session ... Date\\n}) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:164:33:164:58 | `authKe ... key()}` | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:177:5:177:19 | document.cookie | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:181:5:181:41 | cookies ... hkey()) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:186:5:186:46 | cookie. ... hkey()) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
| tst-cleartextCookie.js:195:33:195:74 | cookie. ... hkey()) | Sensitive cookie sent without enforcing SSL encryption |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE-614/ClearTextCookie.ql
|
||||
@@ -1,11 +0,0 @@
|
||||
| test_cookie-session.js:16:9:24:2 | session ... Date\\n}) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_express-session.js:5:9:8:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_express-session.js:10:9:13:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_express-session.js:15:9:18:2 | session ... T OK\\n}) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_express-session.js:25:9:25:21 | session(sess) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_httpserver.js:7:37:7:48 | "type=ninja" | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_httpserver.js:27:37:27:73 | ["type= ... cript"] | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_httpserver.js:57:37:57:81 | ["type= ... cript"] | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_jscookie.js:2:1:2:48 | js_cook ... alse }) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_responseCookie.js:5:5:10:10 | res.coo ... }) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
| test_responseCookie.js:20:5:20:40 | res.coo ... ptions) | Cookie is added to response without the 'secure' flag being set to true |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security/CWE-614/InsecureCookie.ql
|
||||
@@ -1,24 +0,0 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('cookie-session')
|
||||
const expiryDate = new Date(Date.now() + 60 * 60 * 1000)
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
secure: true, // OK
|
||||
httpOnly: true,
|
||||
domain: 'example.com',
|
||||
path: 'foo/bar',
|
||||
expires: expiryDate
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
secure: false, // NOT OK
|
||||
httpOnly: true,
|
||||
domain: 'example.com',
|
||||
path: 'foo/bar',
|
||||
expires: expiryDate
|
||||
}))
|
||||
@@ -1,33 +0,0 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('express-session')
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: { secure: false } // NOT OK
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret'
|
||||
// NOT OK
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: {} // NOT OK
|
||||
}))
|
||||
|
||||
const sess = {
|
||||
secret: 'secret',
|
||||
cookie: { secure: false } // NOT OK
|
||||
}
|
||||
|
||||
app.use(session(sess))
|
||||
|
||||
|
||||
app.set('trust proxy', 1)
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: { secure: true } // OK
|
||||
}))
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
const http = require('http');
|
||||
|
||||
function test1() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", "type=ninja");
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test2() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD
|
||||
res.setHeader("Set-Cookie", "type=ninja; Secure");
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test3() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test4() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD
|
||||
res.setHeader("Set-Cookie", ["type=ninja; Secure"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test5() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD, case insensitive
|
||||
res.setHeader("Set-Cookie", ["type=ninja; secure"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test6() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", ["type=ninja; secure", "language=javascript"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
const js_cookie = require('js-cookie')
|
||||
js_cookie.set('key', 'value', { secure: false }); // NOT OK
|
||||
js_cookie.set('key', 'value', { secure: true }); // OK
|
||||
@@ -1,33 +0,0 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('name', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: false // NOT OK
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/b', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: false // NOT OK
|
||||
}
|
||||
res.cookie('name', 'value', options);
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/c', function (req, res, next) {
|
||||
res.cookie('name', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: true // OK
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
|
||||
app.get('/a', function (req, res, next) {
|
||||
res.cookie('authkey', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: false // NOT OK
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/b', function (req, res, next) {
|
||||
let options = {
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: false // NOT OK
|
||||
}
|
||||
res.cookie('authKey', 'value', options);
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
app.get('/c', function (req, res, next) {
|
||||
res.cookie('name', 'value',
|
||||
{
|
||||
maxAge: 9000000000,
|
||||
httpOnly: true,
|
||||
secure: true // OK
|
||||
});
|
||||
res.end('ok')
|
||||
})
|
||||
|
||||
const js_cookie = require('js-cookie')
|
||||
js_cookie.set('authKey', 'value', { secure: false }); // NOT OK
|
||||
js_cookie.set('authKey', 'value', { secure: true }); // OK
|
||||
|
||||
const http = require('http');
|
||||
|
||||
function test1() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// BAD
|
||||
res.setHeader("Set-Cookie", "authKey=ninja");
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test2() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD
|
||||
res.setHeader("Set-Cookie", "type=ninja; Secure");
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test3() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader("Set-Cookie", [
|
||||
"authKey=ninja", // NOT OK
|
||||
"language=javascript" // OK
|
||||
]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test4() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD
|
||||
res.setHeader("Set-Cookie", ["type=ninja; Secure"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test5() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
// GOOD, case insensitive
|
||||
res.setHeader("Set-Cookie", ["type=ninja; secure"]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
function test6() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader("Set-Cookie", [
|
||||
"type=ninja; secure", // OK
|
||||
"authKey=foo" // NOT OK
|
||||
]);
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
}
|
||||
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('express-session')
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: { secure: false } // NOT OK
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret'
|
||||
// NOT OK
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: {} // NOT OK
|
||||
}))
|
||||
|
||||
const sess = {
|
||||
secret: 'secret',
|
||||
cookie: { secure: false } // NOT OK
|
||||
}
|
||||
|
||||
app.use(session(sess))
|
||||
|
||||
|
||||
app.set('trust proxy', 1)
|
||||
app.use(session({
|
||||
secret: 'secret',
|
||||
cookie: { secure: true } // OK
|
||||
}))
|
||||
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('cookie-session')
|
||||
const expiryDate = new Date(Date.now() + 60 * 60 * 1000)
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
secure: true, // OK
|
||||
httpOnly: true,
|
||||
domain: 'example.com',
|
||||
path: 'foo/bar',
|
||||
expires: expiryDate
|
||||
}))
|
||||
|
||||
app.use(session({
|
||||
name: 'session',
|
||||
keys: ['key1', 'key2'],
|
||||
secure: false, // NOT OK
|
||||
httpOnly: true,
|
||||
domain: 'example.com',
|
||||
path: 'foo/bar',
|
||||
expires: expiryDate
|
||||
}))
|
||||
|
||||
http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader("Set-Cookie", `authKey=${makeAuthkey()}`); // NOT OK
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
|
||||
http.createServer((req, res) => {
|
||||
res.setHeader("Set-Cookie", `authKey=${makeAuthkey()}; secure; httpOnly`); // OK
|
||||
res.writeHead(200, { 'Content-Type': 'text/html' });
|
||||
res.end('<h2>Hello world</h2>');
|
||||
});
|
||||
|
||||
function clientCookies() {
|
||||
document.cookie = `authKey=${makeAuthkey()}; secure`; // OK
|
||||
document.cookie = `authKey=${makeAuthkey()}`; // NOT OK
|
||||
|
||||
var cookies = require('browser-cookies');
|
||||
|
||||
cookies.set('authKey', makeAuthkey()); // NOT OK
|
||||
cookies.set('authKey', makeAuthkey(), { secure: true, expires: 7 }); // OK
|
||||
|
||||
const cookie = require('cookie');
|
||||
|
||||
cookie.serialize('authKey', makeAuthkey()); // NOT OK
|
||||
cookie.serialize('authKey', makeAuthkey(), { secure: true, expires: 7 }); // OK
|
||||
}
|
||||
|
||||
const cookie = require('cookie');
|
||||
|
||||
http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader("Set-Cookie", cookie.serialize("authKey", makeAuthkey(), {secure: true,httpOnly: true})); // OK
|
||||
res.setHeader("Set-Cookie", cookie.serialize("authKey", makeAuthkey())); // NOT OK
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('ok');
|
||||
});
|
||||
|
||||
(function mightBeSecures() {
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const session = require('express-session')
|
||||
|
||||
app.use(session({
|
||||
secret: config.sessionSecret,
|
||||
cookie: {
|
||||
httpOnly: config.sessionCookie.httpOnly,
|
||||
secure: config.sessionCookie.secure && config.secure.ssl
|
||||
},
|
||||
name: config.sessionKey
|
||||
}));
|
||||
})();
|
||||
@@ -23,6 +23,16 @@ nodes
|
||||
| tst.js:45:9:45:11 | obj |
|
||||
| tst.js:48:9:48:11 | obj |
|
||||
| tst.js:48:9:48:11 | obj |
|
||||
| tst.js:78:5:78:37 | obj[req ... ', '')] |
|
||||
| tst.js:78:5:78:37 | obj[req ... ', '')] |
|
||||
| tst.js:78:9:78:19 | req.query.x |
|
||||
| tst.js:78:9:78:19 | req.query.x |
|
||||
| tst.js:78:9:78:36 | req.que ... _', '') |
|
||||
| tst.js:81:5:81:46 | obj[req ... g, '')] |
|
||||
| tst.js:81:5:81:46 | obj[req ... g, '')] |
|
||||
| tst.js:81:9:81:19 | req.query.x |
|
||||
| tst.js:81:9:81:19 | req.query.x |
|
||||
| tst.js:81:9:81:45 | req.que ... /g, '') |
|
||||
edges
|
||||
| tst.js:5:9:5:38 | taint | tst.js:8:12:8:16 | taint |
|
||||
| tst.js:5:9:5:38 | taint | tst.js:9:12:9:16 | taint |
|
||||
@@ -47,6 +57,14 @@ edges
|
||||
| tst.js:33:23:33:25 | obj | tst.js:45:9:45:11 | obj |
|
||||
| tst.js:33:23:33:25 | obj | tst.js:48:9:48:11 | obj |
|
||||
| tst.js:33:23:33:25 | obj | tst.js:48:9:48:11 | obj |
|
||||
| tst.js:78:9:78:19 | req.query.x | tst.js:78:9:78:36 | req.que ... _', '') |
|
||||
| tst.js:78:9:78:19 | req.query.x | tst.js:78:9:78:36 | req.que ... _', '') |
|
||||
| tst.js:78:9:78:36 | req.que ... _', '') | tst.js:78:5:78:37 | obj[req ... ', '')] |
|
||||
| tst.js:78:9:78:36 | req.que ... _', '') | tst.js:78:5:78:37 | obj[req ... ', '')] |
|
||||
| tst.js:81:9:81:19 | req.query.x | tst.js:81:9:81:45 | req.que ... /g, '') |
|
||||
| tst.js:81:9:81:19 | req.query.x | tst.js:81:9:81:45 | req.que ... /g, '') |
|
||||
| tst.js:81:9:81:45 | req.que ... /g, '') | tst.js:81:5:81:46 | obj[req ... g, '')] |
|
||||
| tst.js:81:9:81:45 | req.que ... /g, '') | tst.js:81:5:81:46 | obj[req ... g, '')] |
|
||||
#select
|
||||
| tst.js:8:5:8:17 | object[taint] | tst.js:5:24:5:37 | req.query.data | tst.js:8:5:8:17 | object[taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:5:24:5:37 | req.query.data | here |
|
||||
| tst.js:9:5:9:17 | object[taint] | tst.js:5:24:5:37 | req.query.data | tst.js:9:5:9:17 | object[taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:5:24:5:37 | req.query.data | here |
|
||||
@@ -55,3 +73,5 @@ edges
|
||||
| tst.js:39:9:39:11 | obj | tst.js:5:24:5:37 | req.query.data | tst.js:39:9:39:11 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:5:24:5:37 | req.query.data | here |
|
||||
| tst.js:45:9:45:11 | obj | tst.js:5:24:5:37 | req.query.data | tst.js:45:9:45:11 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:5:24:5:37 | req.query.data | here |
|
||||
| tst.js:48:9:48:11 | obj | tst.js:5:24:5:37 | req.query.data | tst.js:48:9:48:11 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:5:24:5:37 | req.query.data | here |
|
||||
| tst.js:78:5:78:37 | obj[req ... ', '')] | tst.js:78:9:78:19 | req.query.x | tst.js:78:5:78:37 | obj[req ... ', '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:78:9:78:19 | req.query.x | here |
|
||||
| tst.js:81:5:81:46 | obj[req ... g, '')] | tst.js:81:9:81:19 | req.query.x | tst.js:81:5:81:46 | obj[req ... g, '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:81:9:81:19 | req.query.x | here |
|
||||
|
||||
@@ -71,3 +71,13 @@ class Box {
|
||||
this.foo = 'bar'; // OK - 'this' won't refer to Object.prototype
|
||||
}
|
||||
}
|
||||
|
||||
app.get('/foo', (req, res) => {
|
||||
let obj = {};
|
||||
obj[req.query.x.replace('_', '-')].x = 'foo'; // OK
|
||||
obj[req.query.x.replace('_', '')].x = 'foo'; // NOT OK
|
||||
obj[req.query.x.replace(/_/g, '')].x = 'foo'; // OK
|
||||
obj[req.query.x.replace(/_/g, '-')].x = 'foo'; // OK
|
||||
obj[req.query.x.replace(/__proto__/g, '')].x = 'foo'; // NOT OK - "__pr__proto__oto__"
|
||||
obj[req.query.x.replace('o', '0')].x = 'foo'; // OK
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user