mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Merge pull request #11726 from github/jhelie/fix-endpoint-large-scale-script
ATM: fix script updating endpoint large scale test data
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,13 @@
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:14:30:14:30 | v |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:22:33:22:33 | v |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:23:33:23:33 | v |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:77:22:77:24 | tag |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:85:20:85:22 | tag |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:130:23:130:24 | id |
|
||||
@@ -9,16 +15,23 @@
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:11:22:11:22 | v |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:12:22:12:32 | req.body.id |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:22:10:25 | temp |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/redis.js:52:28:52:30 | key |
|
||||
| DomBasedXssAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:23:16:41 | req.params.category |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath |
|
||||
| DomBasedXssAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:7:47:7:69 | classNa ... w.name) |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:8:47:8:70 | classNa ... w.name) |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:9:47:9:70 | classNa ... w.name) |
|
||||
@@ -26,11 +39,19 @@
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:11:47:11:64 | unsafeStyle('foo') |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:13:47:13:68 | safeSty ... w.name) |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:15:47:15:63 | clsx(window.name) |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:17:5:17:79 | documen ... <span>` |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:17:48:17:64 | clsx(window.name) |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/clipboard.ts:8:18:8:51 | clipboa ... /html') |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/clipboard.ts:43:22:43:55 | clipboa ... /html') |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/clipboard.ts:98:22:98:54 | dataTra ... /html') |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/dragAndDrop.ts:8:18:8:50 | dataTra ... /html') |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/dragAndDrop.ts:43:22:43:54 | dataTra ... /html') |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/event-handler-receiver.js:2:49:2:61 | location.href |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/jquery.js:7:20:7:26 | tainted |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/jquery.js:10:13:10:31 | location.toString() |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/jquery.js:34:13:34:16 | hash |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:10:30:10:47 | req.query.receiver |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:12:11:12:69 | `Hi, yo ... sage}.` |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/DomBasedXss/sanitiser.js:23:29:23:35 | tainted |
|
||||
@@ -81,6 +102,8 @@
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:99:31:99:38 | req.body |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXss.js:102:68:102:75 | req.body |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/ReflectedXssGood.js:19:45:19:57 | req.params.id |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/live-server.js:6:28:6:34 | tainted |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/live-server.js:12:28:12:34 | tainted |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:13:42:13:48 | req.url |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:42:40:50 | [req.url] |
|
||||
| DomBasedXssAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:43:40:49 | req.url |
|
||||
@@ -90,6 +113,8 @@
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:23:27:23:35 | { id: v } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/marsdb-flow-to.js:10:17:10:18 | {} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/marsdb.js:12:17:12:18 | {} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/minimongo.js:14:17:14:18 | {} |
|
||||
@@ -111,15 +136,26 @@
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:99:44:99:48 | query |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseJsonParse.js:19:19:19:20 | {} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query |
|
||||
| NosqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/redis.js:52:28:52:30 | key |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:29:38:29:62 | { path: ... .path } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:33:34:33:58 | { name: ... .name } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:37:35:37:59 | { name: ... .name } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:41:33:44:5 | {\\n ... )\\n } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:48:33:51:5 | {\\n ... "\\n } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/other-fs-libraries.js:62:37:62:47 | {cwd: path} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/other-fs-libraries.js:63:45:63:55 | {cwd: path} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/pupeteer.js:9:20:9:50 | { path: ... 'a4' } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/TaintedPath/pupeteer.js:13:29:13:45 | { path: tainted } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/clipboard.ts:19:26:19:28 | div |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/clipboard.ts:54:30:54:32 | div |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dragAndDrop.ts:19:26:19:28 | div |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dragAndDrop.ts:54:30:54:32 | div |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:8:22:14:3 | {\\n f ... OK\\n } |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:10:30:10:47 | req.query.receiver |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst3.js:6:27:6:32 | data.w |
|
||||
@@ -132,6 +168,8 @@
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:199:32:199:75 | {danger ... inted}} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:200:32:200:75 | {danger ... inted}} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:361:14:361:19 | target |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:442:25:442:40 | {"html": source} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/tst.js:444:35:444:50 | {"html": source} |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:5:11:5:11 | x |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:9:11:9:13 | foo |
|
||||
| NosqlInjectionAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:21:11:21:21 | foo + "bar" |
|
||||
@@ -156,8 +194,14 @@
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:14:30:14:30 | v |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:22:33:22:33 | v |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:23:33:23:33 | v |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:50:23:50:48 | JSON.pa ... y.data) |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:77:22:77:24 | tag |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:85:20:85:22 | tag |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongoose.js:130:23:130:24 | id |
|
||||
@@ -165,22 +209,29 @@
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:11:22:11:22 | v |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:12:22:12:32 | req.body.id |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:22:10:25 | temp |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:34 | "SELECT ... ategory |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:6:15:7:55 | "SELECT ... PRICE" |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/redis.js:52:28:52:30 | key |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:7:16:8:34 | "SELECT ... ategory |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:7:16:8:55 | "SELECT ... PRICE" |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:23:16:41 | req.params.category |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst4.js:8:10:8:60 | 'SELECT ... rams.id |
|
||||
| SqlInjectionAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst.js:10:10:10:58 | 'SELECT ... rams.id |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:312:19:312:22 | path |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath |
|
||||
| SqlInjectionAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path |
|
||||
| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/classnames.js:10:45:10:55 | window.name |
|
||||
| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:15:65:15:69 | taint |
|
||||
| SqlInjectionAtmConfig | autogenerated/Xss/DomBasedXss/dates.js:17:49:17:53 | taint |
|
||||
@@ -218,7 +269,13 @@
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:14:30:14:30 | v |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:22:33:22:33 | v |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/typed/typedClient.ts:23:33:23:33 | v |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:82:11:91:6 | JSON.st ... \\n }) |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:99:11:111:6 | JSON.st ... \\n }) |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/graphql.js:109:13:109:14 | id |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/json-schema-validator.js:26:25:26:29 | query |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:32:15:32:59 | `(\|(nam ... ame}))` |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:40:15:42:11 | `(\|(nam ... )}))` |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/ldap.js:64:5:64:49 | `(\|(nam ... ame}))` |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:21:25:21:45 | '' + qu ... y.title |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:24:25:24:50 | query.b ... bstr(1) |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongodb.js:77:22:77:24 | tag |
|
||||
@@ -228,17 +285,23 @@
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:11:22:11:22 | v |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:12:22:12:32 | req.body.id |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mongooseModelClient.js:13:22:13:37 | `${req.body.id}` |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:21:10:26 | [temp] |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/mysql.js:10:22:10:25 | temp |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:26:13:26:25 | req.params.id |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:41:7:41:20 | req.params.foo |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:48:13:48:27 | req.params.name |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:55:13:55:27 | req.params.name |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/pg-promise.js:63:23:63:27 | query |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/redis.js:52:28:52:30 | key |
|
||||
| TaintedPathAtmConfig | autogenerated/NosqlAndSqlInjection/untyped/tst3.js:16:23:16:41 | req.params.category |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/TaintedPath.js:115:12:115:51 | path.re ... /g, '') |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/TaintedPath.js:116:12:116:36 | path.re ... /g, '') |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/TaintedPath.js:128:11:128:50 | path.re ... /g, '') |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/TaintedPath.js:129:12:129:36 | path.re ... /g, '') |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/handlebars.js:29:46:29:60 | req.params.path |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/handlebars.js:33:42:33:56 | req.params.name |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/handlebars.js:37:43:37:57 | req.params.name |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/handlebars.js:43:15:43:29 | req.params.path |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/handlebars.js:49:17:49:33 | req.params.prefix |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:21:14:21:49 | pathMod ... y.path) |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:31:14:31:49 | pathMod ... y.path) |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:54:14:54:49 | pathMod ... y.path) |
|
||||
@@ -260,6 +323,8 @@
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:321:19:321:32 | normalizedPath |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:328:19:328:32 | normalizedPath |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:339:13:339:46 | pathMod ... y.path) |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:381:25:381:28 | path |
|
||||
| TaintedPathAtmConfig | autogenerated/TaintedPath/normalizedPaths.js:385:14:385:46 | pathMod ... uery.x) |
|
||||
| TaintedPathAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:10:30:10:47 | req.query.receiver |
|
||||
| TaintedPathAtmConfig | autogenerated/Xss/DomBasedXss/nodemailer.js:12:11:12:69 | `Hi, yo ... sage}.` |
|
||||
| TaintedPathAtmConfig | autogenerated/Xss/ExceptionXss/exception-xss.js:117:11:117:23 | req.params.id |
|
||||
@@ -276,3 +341,5 @@
|
||||
| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:42:40:50 | [req.url] |
|
||||
| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:40:43:40:49 | req.url |
|
||||
| TaintedPathAtmConfig | autogenerated/Xss/ReflectedXss/partial.js:49:38:49:44 | req.url |
|
||||
| XssThroughDomAtmConfig | autogenerated/Xss/XssThroughDom/xss-through-dom.js:109:45:109:55 | this.el.src |
|
||||
| XssThroughDomAtmConfig | autogenerated/Xss/XssThroughDom/xss-through-dom.js:122:53:122:70 | ev.target.files[0] |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,18 +7,26 @@ taintedPathFilteredTruePositives
|
||||
| autogenerated/TaintedPath/TaintedPath.js:66:26:66:31 | "SAFE" | not a direct argument to a likely external library call or a heuristic sink (tainted path) |
|
||||
| autogenerated/TaintedPath/TaintedPath.js:71:26:71:45 | Cookie.get("unsafe") | not a direct argument to a likely external library call or a heuristic sink (tainted path) |
|
||||
xssFilteredTruePositives
|
||||
| autogenerated/Xss/DomBasedXss/classnames.js:17:32:17:79 | `<span ... <span>` | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/d3.js:12:20:12:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/d3.js:14:20:14:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/express.js:7:15:7:33 | req.param("wobble") | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/jwt-server.js:11:19:11:29 | decoded.foo | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/trusted-types.js:2:71:2:71 | x | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/trusted-types.js:5:71:5:76 | 'safe' | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/trusted-types.js:8:71:8:71 | x | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/tst.js:316:35:316:42 | location | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
xssThroughDomFilteredTruePositives
|
||||
| autogenerated/Xss/DomBasedXss/classnames.js:17:32:17:79 | `<span ... <span>` | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/d3.js:12:20:12:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/d3.js:14:20:14:29 | getTaint() | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/express.js:7:15:7:33 | req.param("wobble") | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/jwt-server.js:11:19:11:29 | decoded.foo | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/trusted-types.js:2:71:2:71 | x | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/trusted-types.js:5:71:5:76 | 'safe' | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/trusted-types.js:8:71:8:71 | x | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/tst.js:316:35:316:42 | location | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/typeahead.js:10:16:10:18 | loc | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
| autogenerated/Xss/DomBasedXss/typeahead.js:25:18:25:20 | val | not a direct argument to a likely external library call or a heuristic sink (xss) |
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# autogenerated
|
||||
# autogenerated folder
|
||||
|
||||
This folder contains test data for the ATM endpoint CodeQL tests that has been autogenerated from the standard JS CodeQL libraries.
|
||||
|
||||
It is helpful, but not required, to periodically update this test data to incorporate new test data introduced in the standard JS CodeQL libraries.
|
||||
To update this test data, run `python /path/to/codeql-lib/ql/javascript/test/update_endpoint_test_files.py --codeql-lib-path /path/to/codeql-lib`.
|
||||
For more information, run `python /path/to/codeql-lib/ql/javascript/test/update_endpoint_test_files.py --help` or view the source code of [`update_endpoint_test_files.py`](../../update_endpoint_test_files.py).
|
||||
|
||||
To update this test data, run `python /path/to/codeql-lib/ql/javascript/test/update_endpoint_test_files.py`.
|
||||
|
||||
For more information view the source code of [`update_endpoint_test_files.py`](../../update_endpoint_test_files.py).
|
||||
@@ -0,0 +1,121 @@
|
||||
var express = require('express');
|
||||
var app = express();
|
||||
|
||||
import { Octokit } from "@octokit/core";
|
||||
const kit = new Octokit();
|
||||
|
||||
app.get('/post/:id', function(req, res) {
|
||||
const id = req.params.id;
|
||||
// NOT OK
|
||||
const response = kit.graphql(`
|
||||
query {
|
||||
repository(owner: "github", name: "${id}") {
|
||||
object(expression: "master:foo") {
|
||||
... on Blob {
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
import { graphql, withCustomRequest } from "@octokit/graphql";
|
||||
|
||||
app.get('/user/:id/', function(req, res) {
|
||||
const id = req.params.id;
|
||||
const response = graphql(`foo ${id}`); // NOT OK
|
||||
|
||||
const myGraphql = withCustomRequest(request);
|
||||
const response = myGraphql(`foo ${id}`); // NOT OK
|
||||
|
||||
const withDefaults = graphql.defaults({});
|
||||
withDefaults(`foo ${id}`); // NOT OK
|
||||
});
|
||||
|
||||
const { request } = require("@octokit/request");
|
||||
|
||||
app.get('/article/:id/', async function(req, res) {
|
||||
const id = req.params.id;
|
||||
const result = await request("POST /graphql", {
|
||||
headers: {
|
||||
authorization: "token 0000000000000000000000000000000000000001",
|
||||
},
|
||||
query: `foo ${id}`, // NOT OK
|
||||
});
|
||||
|
||||
const withDefaults = request.defaults({});
|
||||
withDefaults("POST /graphql", { query: `foo ${id}` }); // NOT OK
|
||||
});
|
||||
|
||||
import { Octokit as Core } from "@octokit/rest";
|
||||
const kit2 = new Core();
|
||||
|
||||
app.get('/event/:id/', async function(req, res) {
|
||||
const id = req.params.id;
|
||||
const result = await kit2.graphql(`foo ${id}`); // NOT OK
|
||||
|
||||
const result2 = await kit2.request("POST /graphql", { query: `foo ${id}` }); // NOT OK
|
||||
});
|
||||
|
||||
import { graphql as nativeGraphql, buildSchema } from 'graphql';
|
||||
var schema = buildSchema(`
|
||||
type Query {
|
||||
hello: String
|
||||
}
|
||||
`);
|
||||
var root = {
|
||||
hello: () => {
|
||||
return 'Hello world!';
|
||||
},
|
||||
};
|
||||
|
||||
app.get('/thing/:id', async function(req, res) {
|
||||
const id = req.query.id;
|
||||
const result = await nativeGraphql(schema, "{ foo" + id + " }", root); // NOT OK
|
||||
|
||||
fetch("https://my-grpahql-server.com/graphql", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
// NOT OK
|
||||
query: `{
|
||||
thing {
|
||||
name
|
||||
url
|
||||
${id}
|
||||
}
|
||||
}`
|
||||
})
|
||||
})
|
||||
|
||||
fetch("https://my-grpahql-server.com/graphql", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
// OK
|
||||
query: `{
|
||||
thing {
|
||||
name
|
||||
url
|
||||
$id
|
||||
}
|
||||
}`,
|
||||
variables: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
const github = require('@actions/github');
|
||||
app.get('/event/:id/', async function(req, res) {
|
||||
const kit = github.getOctokit("foo")
|
||||
|
||||
const id = req.params.id;
|
||||
const result = await kit.graphql(`foo ${id}`); // NOT OK
|
||||
});
|
||||
@@ -35,3 +35,30 @@ app.post('/documents/find', (req, res) => {
|
||||
doc.find(query); // NOT OK
|
||||
});
|
||||
});
|
||||
|
||||
import Joi from 'joi';
|
||||
|
||||
const joiSchema = Joi.object({
|
||||
date: Joi.string().required(),
|
||||
title: Joi.string().required()
|
||||
}).with('date', 'title');
|
||||
|
||||
app.post('/documents/insert', (req, res) => {
|
||||
MongoClient.connect('mongodb://localhost:27017/test', async (err, db) => {
|
||||
let doc = db.collection('doc');
|
||||
|
||||
const query = JSON.parse(req.query.data);
|
||||
const validate = joiSchema.validate(query);
|
||||
if (!validate.error) {
|
||||
doc.find(query); // OK
|
||||
} else {
|
||||
doc.find(query); // NOT OK
|
||||
}
|
||||
try {
|
||||
await joiSchema.validateAsync(query);
|
||||
doc.find(query); // OK - but still flagged [INCONSISTENCY]
|
||||
} catch (e) {
|
||||
doc.find(query); // NOT OK
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -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, () => {});
|
||||
@@ -11,5 +11,5 @@ app.post("/documents/find", (req, res) => {
|
||||
query.title = req.body.title;
|
||||
|
||||
// NOT OK: query is tainted by user-provided object value
|
||||
db.myDoc.find(query);
|
||||
db.myDoc.find(query, (err, data) => {});
|
||||
});
|
||||
|
||||
@@ -13,5 +13,5 @@ app.post("/documents/find", (req, res) => {
|
||||
query.title = req.body.title;
|
||||
|
||||
// NOT OK: query is tainted by user-provided object value
|
||||
doc.find(query);
|
||||
doc.find(query, (err, data) => {});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const app = require("express")();
|
||||
const mysql = require('mysql');
|
||||
const pool = mysql.createPool(getConfig());
|
||||
|
||||
app.get("search", function handler(req, res) {
|
||||
let temp = req.params.value;
|
||||
pool.getConnection(function(err, connection) {
|
||||
connection.query({
|
||||
sql: 'SELECT * FROM `books` WHERE `author` = ?', // OK
|
||||
values: [temp]
|
||||
}, function(error, results, fields) {});
|
||||
});
|
||||
pool.getConnection(function(err, connection) {
|
||||
connection.query({
|
||||
sql: 'SELECT * FROM `books` WHERE `author` = ' + temp, // NOT OK
|
||||
}, function(error, results, fields) {});
|
||||
});
|
||||
pool.getConnection(function(err, connection) {
|
||||
connection.query('SELECT * FROM `books` WHERE `author` = ' + temp, // NOT OK
|
||||
function(error, results, fields) {});
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,7 @@ require('express')().get('/foo', (req, res) => {
|
||||
|
||||
var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ req.params.category + "' ORDER BY PRICE";
|
||||
|
||||
|
||||
db.any(query); // NOT OK
|
||||
db.many(query); // NOT OK
|
||||
db.manyOrNone(query); // NOT OK
|
||||
@@ -17,7 +17,7 @@ require('express')().get('/foo', (req, res) => {
|
||||
db.oneOrNone(query); // NOT OK
|
||||
db.query(query); // NOT OK
|
||||
db.result(query); // NOT OK
|
||||
|
||||
|
||||
db.one({
|
||||
text: query // NOT OK
|
||||
});
|
||||
@@ -59,7 +59,7 @@ require('express')().get('/foo', (req, res) => {
|
||||
db.task(t => {
|
||||
return t.one(query); // NOT OK
|
||||
});
|
||||
db.task(
|
||||
db.taskIf(
|
||||
{ cnd: t => t.one(query) }, // NOT OK
|
||||
t => t.one(query) // NOT OK
|
||||
);
|
||||
|
||||
@@ -193,4 +193,23 @@ var server = http.createServer(function(req, res) {
|
||||
|
||||
res.write(fs.readFileSync("prefix" + path.replace(/^(\.\.[\/\\])+/, ''))); // NOT OK - not normalized
|
||||
res.write(fs.readFileSync(pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, ''))); // NOT OK (can be absolute)
|
||||
});
|
||||
});
|
||||
|
||||
import normalizeUrl from 'normalize-url';
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
// tests for a few more uri-libraries
|
||||
const qs = require("qs");
|
||||
res.write(fs.readFileSync(qs.parse(req.url).foo)); // NOT OK
|
||||
res.write(fs.readFileSync(qs.parse(normalizeUrl(req.url)).foo)); // NOT OK
|
||||
const parseqs = require("parseqs");
|
||||
res.write(fs.readFileSync(parseqs.decode(req.url).foo)); // NOT OK
|
||||
});
|
||||
|
||||
const cp = require("child_process");
|
||||
var server = http.createServer(function(req, res) {
|
||||
let path = url.parse(req.url, true).query.path;
|
||||
cp.execSync("foobar", {cwd: path}); // NOT OK
|
||||
cp.execFileSync("foobar", ["args"], {cwd: path}); // NOT OK
|
||||
cp.execFileSync("foobar", {cwd: path}); // NOT OK
|
||||
});
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
var express = require("express"),
|
||||
fileUpload = require("express-fileupload");
|
||||
|
||||
let app = express();
|
||||
app.use(fileUpload());
|
||||
|
||||
app.get("/some/path", function (req, res) {
|
||||
req.files.foo.mv(req.query.bar);
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
const express = require('express');
|
||||
const hb = require("handlebars");
|
||||
const fs = require("fs");
|
||||
|
||||
const app = express();
|
||||
|
||||
const data = {};
|
||||
|
||||
function init() {
|
||||
hb.registerHelper("catFile", function catFile(filePath) {
|
||||
return fs.readFileSync(filePath); // SINK (reads file)
|
||||
});
|
||||
hb.registerHelper("prependToLines", function prependToLines(prefix, filePath) {
|
||||
return fs
|
||||
.readFileSync(filePath)
|
||||
.split("\n")
|
||||
.map((line) => prefix + line)
|
||||
.join("\n");
|
||||
});
|
||||
data.compiledFileAccess = hb.compile("contents of file {{path}} are: {{catFile path}}")
|
||||
data.compiledBenign = hb.compile("hello, {{name}}");
|
||||
data.compiledUnknown = hb.compile(fs.readFileSync("greeting.template"));
|
||||
data.compiledMixed = hb.compile("helpers may have several args, like here: {{prependToLines prefix path}}");
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
app.get('/some/path1', function (req, res) {
|
||||
res.send(data.compiledFileAccess({ path: req.params.path })); // NOT ALLOWED (template uses vulnerable catFile)
|
||||
});
|
||||
|
||||
app.get('/some/path2', function (req, res) {
|
||||
res.send(data.compiledBenign({ name: req.params.name })); // ALLOWED (this template does not use catFile)
|
||||
});
|
||||
|
||||
app.get('/some/path3', function (req, res) {
|
||||
res.send(data.compiledUnknown({ name: req.params.name })); // ALLOWED (could be using a vulnerable helper, but we'll assume it's ok)
|
||||
});
|
||||
|
||||
app.get('/some/path4', function (req, res) {
|
||||
res.send(data.compiledMixed({
|
||||
prefix: ">>> ",
|
||||
path: req.params.path // NOT ALLOWED (template uses vulnerable helper)
|
||||
}));
|
||||
});
|
||||
|
||||
app.get('/some/path5', function (req, res) {
|
||||
res.send(data.compiledMixed({
|
||||
prefix: req.params.prefix, // ALLOWED (this parameter is safe)
|
||||
path: "data/path-5.txt"
|
||||
}));
|
||||
});
|
||||
@@ -370,4 +370,35 @@ app.get('/yet-another-prefix2', (req, res) => {
|
||||
function allowPath(requestPath, rootPath) {
|
||||
return requestPath.indexOf(rootPath) === 0;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
import slash from 'slash';
|
||||
app.get('/slash-stuff', (req, res) => {
|
||||
let path = req.query.path;
|
||||
|
||||
fs.readFileSync(path); // NOT OK
|
||||
|
||||
fs.readFileSync(slash(path)); // NOT OK
|
||||
});
|
||||
|
||||
app.get('/dotdot-regexp', (req, res) => {
|
||||
let path = pathModule.normalize(req.query.x);
|
||||
if (pathModule.isAbsolute(path))
|
||||
return;
|
||||
fs.readFileSync(path); // NOT OK
|
||||
if (!path.match(/\./)) {
|
||||
fs.readFileSync(path); // OK
|
||||
}
|
||||
if (!path.match(/\.\./)) {
|
||||
fs.readFileSync(path); // OK
|
||||
}
|
||||
if (!path.match(/\.\.\//)) {
|
||||
fs.readFileSync(path); // OK
|
||||
}
|
||||
if (!path.match(/\.\.\/foo/)) {
|
||||
fs.readFileSync(path); // NOT OK
|
||||
}
|
||||
if (!path.match(/(\.\.\/|\.\.\\)/)) {
|
||||
fs.readFileSync(path); // OK
|
||||
}
|
||||
});
|
||||
|
||||
@@ -50,4 +50,24 @@ http.createServer(function(req, res) {
|
||||
|
||||
fs.readFileSync(path); // NOT OK
|
||||
asyncFS.readFileSync(path); // NOT OK
|
||||
|
||||
require("pify")(fs.readFileSync)(path); // NOT OK
|
||||
require("pify")(fs).readFileSync(path); // NOT OK
|
||||
|
||||
require('util.promisify')(fs.readFileSync)(path); // NOT OK
|
||||
|
||||
require("thenify")(fs.readFileSync)(path); // NOT OK
|
||||
|
||||
const readPkg = require('read-pkg');
|
||||
var pkg = readPkg.readPackageSync({cwd: path}); // NOT OK
|
||||
var pkgPromise = readPkg.readPackageAsync({cwd: path}); // NOT OK
|
||||
});
|
||||
|
||||
const mkdirp = require("mkdirp");
|
||||
http.createServer(function(req, res) {
|
||||
var path = url.parse(req.url, true).query.path;
|
||||
|
||||
fs.readFileSync(path); // NOT OK
|
||||
mkdirp(path); // NOT OK
|
||||
mkdirp.sync(path); // NOT OK
|
||||
});
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
const express = require('express');
|
||||
const prettier = require("prettier");
|
||||
|
||||
const app = express();
|
||||
app.get('/some/path', function (req, res) {
|
||||
const { p } = req.params;
|
||||
prettier.resolveConfig(p).then((options) => { // NOT OK
|
||||
const formatted = prettier.format("foo", options);
|
||||
});
|
||||
|
||||
prettier.resolveConfig("foo", {config: p}).then((options) => { // NOT OK
|
||||
const formatted = prettier.format("bar", options);
|
||||
});
|
||||
});
|
||||
@@ -32,3 +32,19 @@ var server = http.createServer(function(req, res) {
|
||||
});
|
||||
|
||||
server.listen();
|
||||
|
||||
var nodefs = require('node:fs');
|
||||
|
||||
var server2 = http.createServer(function(req, res) {
|
||||
let path = url.parse(req.url, true).query.path;
|
||||
nodefs.readFileSync(path); // NOT OK
|
||||
});
|
||||
|
||||
server2.listen();
|
||||
|
||||
const chownr = require("chownr");
|
||||
|
||||
var server3 = http.createServer(function (req, res) {
|
||||
let path = url.parse(req.url, true).query.path;
|
||||
chownr(path, "someuid", "somegid", function (err) {}); // NOT OK
|
||||
});
|
||||
|
||||
@@ -6,3 +6,12 @@ app.get('/some/path', function(req, res) {
|
||||
// BAD: loading a module based on un-sanitized query parameters
|
||||
var m = require(req.param("module"));
|
||||
});
|
||||
|
||||
const resolve = require("resolve");
|
||||
app.get('/some/path', function(req, res) {
|
||||
var module = resolve.sync(req.param("module")); // NOT OK - resolving module based on query parameters
|
||||
|
||||
resolve(req.param("module"), { basedir: __dirname }, function(err, res) { // NOT OK - resolving module based on query parameters
|
||||
var module = res;
|
||||
});
|
||||
});
|
||||
@@ -14,4 +14,17 @@ function test() {
|
||||
}
|
||||
|
||||
window.addEventListener("message", foo.bind(null, {data: 'items'}));
|
||||
|
||||
window.onmessage = e => {
|
||||
if (e.origin !== "https://foobar.com") {
|
||||
return;
|
||||
}
|
||||
document.write(e.data); // OK - there is an origin check
|
||||
}
|
||||
|
||||
window.onmessage = e => {
|
||||
if (mySet.includes(e.origin)) {
|
||||
document.write(e.data); // OK - there is an origin check
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,6 @@ function main() {
|
||||
document.body.innerHTML = `<span class="${safeStyle(window.name)}">Hello<span>`; // NOT OK
|
||||
document.body.innerHTML = `<span class="${safeStyle('foo')}">Hello<span>`; // OK
|
||||
document.body.innerHTML = `<span class="${clsx(window.name)}">Hello<span>`; // NOT OK
|
||||
|
||||
document.body.innerHTML += `<span class="${clsx(window.name)}">Hello<span>`; // NOT OK
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
$("#foo").on("paste", paste);
|
||||
|
||||
function paste(e) {
|
||||
const { clipboardData } = e.originalEvent;
|
||||
if (!clipboardData) return;
|
||||
|
||||
const text = clipboardData.getData('text/plain');
|
||||
const html = clipboardData.getData('text/html');
|
||||
if (!text && !html) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const div = document.createElement('div');
|
||||
if (html) {
|
||||
div.innerHTML = html; // NOT OK
|
||||
} else {
|
||||
div.textContent = text;
|
||||
}
|
||||
document.body.append(div);
|
||||
}
|
||||
|
||||
export function install(el: HTMLElement): void {
|
||||
el.addEventListener('paste', (e) => {
|
||||
$("#id").html(e.clipboardData.getData('text/html')); // NOT OK
|
||||
})
|
||||
}
|
||||
|
||||
document.addEventListener('paste', (e) => {
|
||||
$("#id").html(e.clipboardData.getData('text/html')); // NOT OK
|
||||
});
|
||||
|
||||
$("#foo").bind('paste', (e) => {
|
||||
$("#id").html(e.originalEvent.clipboardData.getData('text/html')); // NOT OK
|
||||
});
|
||||
|
||||
(function () {
|
||||
let div = document.createElement("div");
|
||||
div.onpaste = function (e: ClipboardEvent) {
|
||||
const { clipboardData } = e;
|
||||
if (!clipboardData) return;
|
||||
|
||||
const text = clipboardData.getData('text/plain');
|
||||
const html = clipboardData.getData('text/html');
|
||||
if (!text && !html) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const div = document.createElement('div');
|
||||
if (html) {
|
||||
div.innerHTML = html; // NOT OK
|
||||
} else {
|
||||
div.textContent = text;
|
||||
}
|
||||
document.body.append(div);
|
||||
}
|
||||
})();
|
||||
|
||||
async function getClipboardData(e: ClipboardEvent): Promise<Array<File | string>> {
|
||||
// Using a set to filter out duplicates. For some reason, dropping URLs duplicates them 3 times (for me)
|
||||
const dropItems = new Set<File | string>();
|
||||
|
||||
// First get all files in the drop event
|
||||
if (e.clipboardData.files.length > 0) {
|
||||
// tslint:disable-next-line: prefer-for-of
|
||||
for (let i = 0; i < e.clipboardData.files.length; i++) {
|
||||
const file = e.clipboardData.files[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (e.clipboardData.types.includes('text/html')) {
|
||||
const droppedHtml = e.clipboardData.getData('text/html');
|
||||
const container = document.createElement('html');
|
||||
container.innerHTML = droppedHtml;
|
||||
const imgs = container.getElementsByTagName('img');
|
||||
if (imgs.length === 1) {
|
||||
const src = imgs[0].src;
|
||||
dropItems.add(src);
|
||||
}
|
||||
} else if (e.clipboardData.types.includes('text/plain')) {
|
||||
const plainText = e.clipboardData.getData('text/plain');
|
||||
// Check if text is an URL
|
||||
if (/^https?:\/\//i.test(plainText)) {
|
||||
dropItems.add(plainText);
|
||||
}
|
||||
}
|
||||
|
||||
const imageItems = Array.from(dropItems);
|
||||
return imageItems;
|
||||
}
|
||||
|
||||
// inputevent
|
||||
(function () {
|
||||
let div = document.createElement("div");
|
||||
div.addEventListener("beforeinput", function (e: InputEvent) {
|
||||
const { data, inputType, isComposing, dataTransfer } = e;
|
||||
if (!dataTransfer) return;
|
||||
|
||||
const html = dataTransfer.getData('text/html');
|
||||
$("#id").html(html); // NOT OK
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,7 @@
|
||||
import * as dummy from 'dummy';
|
||||
|
||||
class CustomElm extends HTMLElement {
|
||||
test() {
|
||||
this.innerHTML = window.name; // NOT OK
|
||||
}
|
||||
}
|
||||
@@ -16,4 +16,47 @@ function main() {
|
||||
document.body.innerHTML = `Time is ${moment(time).format(taint)}`; // NOT OK
|
||||
document.body.innerHTML = `Time is ${moment(taint).format()}`; // OK
|
||||
document.body.innerHTML = `Time is ${dateformat(time, taint)}`; // NOT OK
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
document.body.innerHTML = `Time is ${dayjs(time).format(taint)}`; // NOT OK
|
||||
}
|
||||
|
||||
import LuxonAdapter from "@date-io/luxon";
|
||||
import DateFnsAdapter from "@date-io/date-fns";
|
||||
import MomentAdapter from "@date-io/moment";
|
||||
import DayJSAdapter from "@date-io/dayjs"
|
||||
|
||||
function dateio() {
|
||||
let taint = decodeURIComponent(window.location.hash.substring(1));
|
||||
|
||||
const dateFns = new DateFnsAdapter();
|
||||
const luxon = new LuxonAdapter();
|
||||
const moment = new MomentAdapter();
|
||||
const dayjs = new DayJSAdapter();
|
||||
|
||||
document.body.innerHTML = `Time is ${dateFns.formatByString(new Date(), taint)}`; // NOT OK
|
||||
document.body.innerHTML = `Time is ${luxon.formatByString(luxon.date(), taint)}`; // NOT OK
|
||||
document.body.innerHTML = `Time is ${moment.formatByString(moment.date(), taint)}`; // NOT OK
|
||||
document.body.innerHTML = `Time is ${dayjs.formatByString(dayjs.date(), taint)}`; // NOT OK
|
||||
}
|
||||
|
||||
import { DateTime } from "luxon";
|
||||
|
||||
function luxon() {
|
||||
let taint = decodeURIComponent(window.location.hash.substring(1));
|
||||
|
||||
document.body.innerHTML = `Time is ${DateTime.now().plus({years: 1}).toFormat(taint)}`; // NOT OK
|
||||
document.body.innerHTML = `Time is ${new DateTime().setLocale('fr').toFormat(taint)}`; // NOT OK
|
||||
document.body.innerHTML = `Time is ${DateTime.fromISO("2020-01-01").startOf('day').toFormat(taint)}`; // NOT OK
|
||||
}
|
||||
|
||||
function dateio2() {
|
||||
let taint = decodeURIComponent(window.location.hash.substring(1));
|
||||
|
||||
const moment = new MomentAdapter();
|
||||
document.body.innerHTML = `Time is ${moment.addDays(moment.date("2020-06-21"), 1).format(taint)}`; // NOT OK
|
||||
const luxon = new LuxonAdapter();
|
||||
document.body.innerHTML = `Time is ${luxon.endOfDay(luxon.date()).toFormat(taint)}`; // NOT OK
|
||||
const dayjs = new DayJSAdapter();
|
||||
document.body.innerHTML = `Time is ${dayjs.setHours(dayjs.date(), 4).format(taint)}`; // NOT OK
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
$("#foo").on("drop", drop);
|
||||
|
||||
function drop(e) {
|
||||
const { dataTransfer } = e.originalEvent;
|
||||
if (!dataTransfer) return;
|
||||
|
||||
const text = dataTransfer.getData('text/plain');
|
||||
const html = dataTransfer.getData('text/html');
|
||||
if (!text && !html) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const div = document.createElement('div');
|
||||
if (html) {
|
||||
div.innerHTML = html; // NOT OK
|
||||
} else {
|
||||
div.textContent = text;
|
||||
}
|
||||
document.body.append(div);
|
||||
}
|
||||
|
||||
export function install(el: HTMLElement): void {
|
||||
el.addEventListener('drop', (e) => {
|
||||
$("#id").html(e.dataTransfer.getData('text/html')); // NOT OK
|
||||
})
|
||||
}
|
||||
|
||||
document.addEventListener('drop', (e) => {
|
||||
$("#id").html(e.dataTransfer.getData('text/html')); // NOT OK
|
||||
});
|
||||
|
||||
$("#foo").bind('drop', (e) => {
|
||||
$("#id").html(e.originalEvent.dataTransfer.getData('text/html')); // NOT OK
|
||||
});
|
||||
|
||||
(function () {
|
||||
let div = document.createElement("div");
|
||||
div.ondrop = function (e: DragEvent) {
|
||||
const { dataTransfer } = e;
|
||||
if (!dataTransfer) return;
|
||||
|
||||
const text = dataTransfer.getData('text/plain');
|
||||
const html = dataTransfer.getData('text/html');
|
||||
if (!text && !html) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const div = document.createElement('div');
|
||||
if (html) {
|
||||
div.innerHTML = html; // NOT OK
|
||||
} else {
|
||||
div.textContent = text;
|
||||
}
|
||||
document.body.append(div);
|
||||
}
|
||||
})();
|
||||
|
||||
async function getDropData(e: DragEvent): Promise<Array<File | string>> {
|
||||
// Using a set to filter out duplicates. For some reason, dropping URLs duplicates them 3 times (for me)
|
||||
const dropItems = new Set<File | string>();
|
||||
|
||||
// First get all files in the drop event
|
||||
if (e.dataTransfer.files.length > 0) {
|
||||
// tslint:disable-next-line: prefer-for-of
|
||||
for (let i = 0; i < e.dataTransfer.files.length; i++) {
|
||||
const file = e.dataTransfer.files[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (e.dataTransfer.types.includes('text/html')) {
|
||||
const droppedHtml = e.dataTransfer.getData('text/html');
|
||||
const container = document.createElement('html');
|
||||
container.innerHTML = droppedHtml;
|
||||
const imgs = container.getElementsByTagName('img');
|
||||
if (imgs.length === 1) {
|
||||
const src = imgs[0].src;
|
||||
dropItems.add(src);
|
||||
}
|
||||
} else if (e.dataTransfer.types.includes('text/plain')) {
|
||||
const plainText = e.dataTransfer.getData('text/plain');
|
||||
// Check if text is an URL
|
||||
if (/^https?:\/\//i.test(plainText)) {
|
||||
dropItems.add(plainText);
|
||||
}
|
||||
}
|
||||
|
||||
const imageItems = Array.from(dropItems);
|
||||
return imageItems;
|
||||
}
|
||||
@@ -57,3 +57,13 @@ function Node() {}
|
||||
* @type {Node}
|
||||
*/
|
||||
Node.prototype.parentNode;
|
||||
|
||||
/**
|
||||
* @return {DomObjectStub}
|
||||
*/
|
||||
DomObjectStub.prototype.insertRow = function() {};
|
||||
|
||||
/**
|
||||
* @return {DomObjectStub}
|
||||
*/
|
||||
DomObjectStub.prototype.insertCell = function() {};
|
||||
|
||||
@@ -14,4 +14,22 @@ function test() {
|
||||
elm.innerHTML = decodeURIComponent(window.location.hash); // NOT OK
|
||||
elm.innerHTML = decodeURIComponent(window.location.search); // NOT OK
|
||||
elm.innerHTML = decodeURIComponent(window.location.toString()); // NOT OK
|
||||
|
||||
let hash = window.location.hash;
|
||||
$(hash); // OK - start with '#'
|
||||
|
||||
$(hash.substring(1)); // NOT OK
|
||||
$(hash.substring(1, 10)); // NOT OK
|
||||
$(hash.substr(1)); // NOT OK
|
||||
$(hash.slice(1)); // NOT OK
|
||||
$(hash.substring(0, 10)); // OK
|
||||
|
||||
$(hash.replace('#', '')); // NOT OK
|
||||
$(window.location.search.replace('?', '')); // NOT OK
|
||||
$(hash.replace('!', '')); // OK
|
||||
$(hash.replace('blah', '')); // OK
|
||||
|
||||
$(hash + 'blah'); // OK
|
||||
$('blah' + hash); // OK - does not start with '<'
|
||||
$('<b>' + hash + '</b>'); // NOT OK
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
(function() {
|
||||
const policy1 = trustedTypes.createPolicy('x', { createHTML: x => x }); // NOT OK
|
||||
policy1.createHTML(window.name);
|
||||
|
||||
const policy2 = trustedTypes.createPolicy('x', { createHTML: x => 'safe' }); // OK
|
||||
policy2.createHTML(window.name);
|
||||
|
||||
const policy3 = trustedTypes.createPolicy('x', { createHTML: x => x }); // OK
|
||||
policy3.createHTML('safe');
|
||||
})();
|
||||
@@ -430,4 +430,63 @@ function nonGlobalSanitizer() {
|
||||
$("#foo").html(target.replace(/<metadata>[\s\S]*<\/metadata>/, '<metadata></metadata>')); // NOT OK
|
||||
|
||||
$("#foo").html(target.replace(/<|>/g, '')); // OK
|
||||
}
|
||||
}
|
||||
|
||||
function mootools(){
|
||||
var source = document.location.search;
|
||||
|
||||
new Element("div"); // OK
|
||||
new Element("div", {text: source}); // OK
|
||||
new Element("div", {html: source}); // NOT OK
|
||||
new Element("div").set("html", source); // NOT OK
|
||||
new Element("div").set({"html": source}); // NOT OK
|
||||
new Element("div").setProperty("html", source); // NOT OK
|
||||
new Element("div").setProperties({"html": source}); // NOT OK
|
||||
new Element("div").appendHtml(source); // NOT OK
|
||||
}
|
||||
|
||||
|
||||
const Convert = require('ansi-to-html');
|
||||
const ansiToHtml = new Convert();
|
||||
|
||||
function ansiToHTML() {
|
||||
var source = document.location.search;
|
||||
|
||||
$("#foo").html(source); // NOT OK
|
||||
$("#foo").html(ansiToHtml.toHtml(source)); // NOT OK
|
||||
}
|
||||
|
||||
function domMethods() {
|
||||
var source = document.location.search;
|
||||
|
||||
let table = document.getElementById('mytable');
|
||||
table.innerHTML = source; // NOT OK
|
||||
let row = table.insertRow(-1);
|
||||
row.innerHTML = source; // NOT OK
|
||||
let cell = row.insertCell();
|
||||
cell.innerHTML = source; // NOT OK
|
||||
}
|
||||
|
||||
function urlStuff() {
|
||||
var url = document.location.search.substr(1);
|
||||
|
||||
$("<a>", {href: url}).appendTo("body"); // NOT OK
|
||||
$("#foo").attr("href", url); // NOT OK
|
||||
$("#foo").attr({href: url}); // NOT OK
|
||||
$("<img>", {src: url}).appendTo("body"); // NOT OK
|
||||
$("<a>", {href: win.location.href}).appendTo("body"); // OK
|
||||
|
||||
$("<img>", {src: "http://google.com/" + url}).appendTo("body"); // OK
|
||||
|
||||
$("<img>", {src: ["http://google.com", url].join("/")}).appendTo("body"); // OK
|
||||
|
||||
if (url.startsWith("https://")) {
|
||||
$("<img>", {src: url}).appendTo("body"); // OK
|
||||
} else {
|
||||
$("<img>", {src: url}).appendTo("body"); // NOT OK
|
||||
}
|
||||
|
||||
window.open(location.hash.substr(1)); // OK - any JavaScript is executed in another context
|
||||
|
||||
navigation.navigate(location.hash.substr(1)); // NOT OK
|
||||
}
|
||||
|
||||
@@ -6,11 +6,19 @@ $(document).ready(function () {
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState !== 4) { return }
|
||||
var json = JSON.parse(xhr.responseText)
|
||||
$("#myThing").html(json.message);
|
||||
$("#myThing").html(json.message); // caught with additional sources
|
||||
}
|
||||
try {
|
||||
xhr.send()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$(document).ready(async function () {
|
||||
const got = require('got');
|
||||
const resp = await got.get("{{ some_url }}");
|
||||
const json = JSON.parse(resp.body);
|
||||
$("#myThing").html(json.message); // caught with additional sources
|
||||
|
||||
});
|
||||
@@ -11,3 +11,16 @@ app.post('/polldata', (req, res) => {
|
||||
res.send(ajv.errorsText()); // NOT OK
|
||||
}
|
||||
});
|
||||
|
||||
const joi = require("joi");
|
||||
const joiSchema = joi.object().keys({
|
||||
name: joi.string().required(),
|
||||
age: joi.number().required()
|
||||
}).with('name', 'age');
|
||||
|
||||
app.post('/votedata', (req, res) => {
|
||||
const val = joiSchema.validate(req.body);
|
||||
if (val.error) {
|
||||
res.send(val.error); // NOT OK
|
||||
}
|
||||
});
|
||||
@@ -101,4 +101,11 @@ app.get('/user/:id', function (req, res) {
|
||||
|
||||
res.send(markdownIt.use(require('markdown-it-sanitizer')).render(req.body)); // OK - HTML is sanitized.
|
||||
res.send(markdownIt.use(require('markdown-it-abbr')).use(unknown).render(req.body)); // NOT OK
|
||||
});
|
||||
});
|
||||
|
||||
var Hapi = require('hapi');
|
||||
var hapi = new Hapi.Server();
|
||||
hapi.route({
|
||||
handler: function (request){
|
||||
return request.query.p; // NOT OK
|
||||
}});
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
var liveServer = require("live-server");
|
||||
|
||||
const middleware = [function(req, res, next) {
|
||||
const tainted = req.url;
|
||||
|
||||
res.end(`<html><body>${tainted}</body></html>`); // NOT OK
|
||||
}];
|
||||
|
||||
middleware.push(function(req, res, next) {
|
||||
const tainted = req.url;
|
||||
|
||||
res.end(`<html><body>${tainted}</body></html>`); // NOT OK
|
||||
});
|
||||
|
||||
var params = {
|
||||
middleware
|
||||
};
|
||||
liveServer.start(params);
|
||||
@@ -22,3 +22,69 @@ app.get('/bar', function(req, res) {
|
||||
else
|
||||
res.send(p); // OK
|
||||
});
|
||||
|
||||
|
||||
const clone = require('clone');
|
||||
|
||||
app.get('/baz', function(req, res) {
|
||||
let { p } = req.params;
|
||||
|
||||
var obj = {};
|
||||
obj.p = p;
|
||||
var other = clone(obj);
|
||||
|
||||
res.send(p); // NOT OK
|
||||
res.send(other.p); // NOT OK
|
||||
});
|
||||
|
||||
const serializeJavaScript = require('serialize-javascript');
|
||||
|
||||
app.get('/baz', function(req, res) {
|
||||
let { p } = req.params;
|
||||
|
||||
var serialized = serializeJavaScript(p);
|
||||
|
||||
res.send(serialized); // OK
|
||||
|
||||
var unsafe = serializeJavaScript(p, {unsafe: true});
|
||||
|
||||
res.send(unsafe); // NOT OK
|
||||
});
|
||||
|
||||
const fclone = require('fclone');
|
||||
|
||||
app.get('/baz', function(req, res) {
|
||||
let { p } = req.params;
|
||||
|
||||
var obj = {};
|
||||
obj.p = p;
|
||||
var other = fclone(obj);
|
||||
|
||||
res.send(p); // NOT OK
|
||||
res.send(other.p); // NOT OK
|
||||
});
|
||||
|
||||
const jc = require('json-cycle');
|
||||
app.get('/baz', function(req, res) {
|
||||
let { p } = req.params;
|
||||
|
||||
var obj = {};
|
||||
obj.p = p;
|
||||
var other = jc.retrocycle(jc.decycle(obj));
|
||||
|
||||
res.send(p); // NOT OK
|
||||
res.send(other.p); // NOT OK
|
||||
});
|
||||
|
||||
const sortKeys = require('sort-keys');
|
||||
|
||||
app.get('/baz', function(req, res) {
|
||||
let { p } = req.params;
|
||||
|
||||
var obj = {};
|
||||
obj.p = p;
|
||||
var other = sortKeys(obj);
|
||||
|
||||
res.send(p); // NOT OK
|
||||
res.send(other.p); // NOT OK
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
var express = require('express');
|
||||
|
||||
var app = express();
|
||||
app.enable('x-powered-by').disable('x-powered-by').get('/', function (req, res) {
|
||||
let { p } = req.params;
|
||||
res.send(p); // NOT OK
|
||||
});
|
||||
|
||||
const prettier = require("prettier");
|
||||
app.post("foobar", function (reg, res) {
|
||||
const code = prettier.format(reg.body, { semi: false, parser: "babel" });
|
||||
res.send(code); // NOT OK
|
||||
});
|
||||
@@ -7,3 +7,9 @@
|
||||
}(function ($) {
|
||||
$("<span>" + $.trim("foo") + "</span>"); // OK
|
||||
}));
|
||||
|
||||
$.fn.myPlugin = function (stuff, options) {
|
||||
$("#foo").html("<span>" + options.foo + "</span>"); // NOT OK
|
||||
|
||||
$("#foo").html("<span>" + stuff + "</span>"); // NOT OK
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export function trivialXss(s: string) {
|
||||
const html = "<span>" + s + "</span>"; // NOT OK
|
||||
document.querySelector("#html").innerHTML = html;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export function trivialXss(s: string) {
|
||||
const html = "<span>" + s + "</span>"; // NOT OK - this file is recognized as a main file.
|
||||
document.querySelector("#html").innerHTML = html;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export function trivialXss(s: string) {
|
||||
const html = "<span>" + s + "</span>"; // OK - this file is not recognized as a main file.
|
||||
document.querySelector("#html").innerHTML = html;
|
||||
}
|
||||
@@ -75,3 +75,45 @@ module.exports.intentionalTemplate = function (obj) {
|
||||
const html = "<span>" + obj.spanTemplate + "</span>"; // OK
|
||||
document.querySelector("#template").innerHTML = html;
|
||||
}
|
||||
|
||||
module.exports.types = function (val) {
|
||||
if (typeof val === "string") {
|
||||
$("#foo").html("<span>" + val + "</span>"); // NOT OK
|
||||
} else if (typeof val === "number") {
|
||||
$("#foo").html("<span>" + val + "</span>"); // OK
|
||||
} else if (typeof val === "boolean") {
|
||||
$("#foo").html("<span>" + val + "</span>"); // OK
|
||||
}
|
||||
}
|
||||
|
||||
function createHTML(x) {
|
||||
return "<span>" + x + "</span>"; // NOT OK
|
||||
}
|
||||
|
||||
module.exports.usesCreateHTML = function (x) {
|
||||
$("#foo").html(createHTML(x));
|
||||
}
|
||||
|
||||
const myMermaid = require('mermaid');
|
||||
module.exports.usesCreateHTML = function (x) {
|
||||
myMermaid.render("id", x, function (svg) { // NOT OK
|
||||
$("#foo").html(svg);
|
||||
});
|
||||
|
||||
$("#foo").html(myMermaid.render("id", x)); // NOT OK
|
||||
|
||||
mermaid.render("id", x, function (svg) {// NOT OK
|
||||
$("#foo").html(svg);
|
||||
});
|
||||
|
||||
$("#foo").html(mermaid.render("id", x)); // NOT OK
|
||||
|
||||
mermaid.mermaidAPI.render("id", x, function (svg) {// NOT OK
|
||||
$("#foo").html(svg);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.xssThroughMarkdown = function (s) {
|
||||
const html = markdown.render(s); // NOT OK
|
||||
document.querySelector("#markdown").innerHTML = html;
|
||||
}
|
||||
|
||||
@@ -182,4 +182,14 @@
|
||||
$(document).find(options.target); // OK
|
||||
}});
|
||||
|
||||
$.fn.position = function( options ) {
|
||||
if ( !options || !options.of ) {
|
||||
return doSomethingElse( this, arguments );
|
||||
}
|
||||
// extending options
|
||||
options = $.extend( {}, options );
|
||||
|
||||
var target = $( options.of ); // NOT OK
|
||||
console.log(target);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -89,4 +89,54 @@
|
||||
$("section h1").each(function(){
|
||||
$("nav ul").append("<a href='#" + $(this).text().toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g,'') + "'>Section</a>"); // OK
|
||||
});
|
||||
|
||||
$("#id").html($("#foo").find(".bla")[0].value); // NOT OK.
|
||||
|
||||
for (var i = 0; i < foo.length; i++) {
|
||||
$("#id").html($("#foo").find(".bla")[i].value); // NOT OK.
|
||||
}
|
||||
})();
|
||||
|
||||
class Super {
|
||||
constructor() {
|
||||
this.el = $("#id").get(0);
|
||||
}
|
||||
}
|
||||
|
||||
class Sub extends Super {
|
||||
constructor() {
|
||||
super();
|
||||
$("#id").get(0).innerHTML = "<a src=\"" + this.el.src + "\">foo</a>"; // NOT OK. Attack: `<mytag id="id" src="x:"><img src=1 onerror="alert(1)">" />`
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
const src = document.getElementById("#link").src;
|
||||
$("#id").html(src); // NOT OK.
|
||||
|
||||
$("#id").attr("src", src); // OK
|
||||
|
||||
$("input.foo")[0].onchange = function (ev) {
|
||||
$("#id").html(ev.target.files[0].name); // NOT OK.
|
||||
|
||||
$("img#id").attr("src", URL.createObjectURL(ev.target.files[0])); // NOT OK
|
||||
}
|
||||
})();
|
||||
|
||||
(function () {
|
||||
let elem = document.createElement('a');
|
||||
const wSelection = getSelection();
|
||||
const dSelection = document.getSelection();
|
||||
let linkText = wSelection.toString() || dSelection.toString() || '';
|
||||
elem.innerHTML = linkText; // NOT OK
|
||||
$("#id").html(linkText); // NOT OK
|
||||
elem.innerText = linkText; // OK
|
||||
})();
|
||||
|
||||
const cashDom = require("cash-dom");
|
||||
|
||||
(function () {
|
||||
const src = document.getElementById("#link").src;
|
||||
cash("#id").html(src); // NOT OK.
|
||||
cashDom("#id").html(src); // NOT OK
|
||||
})();
|
||||
@@ -0,0 +1,28 @@
|
||||
var filters = [
|
||||
/<script.*?>.*?<\/script>/i, // NOT OK - doesn't match newlines or `</script >`
|
||||
/<script.*?>.*?<\/script>/is, // NOT OK - doesn't match `</script >`
|
||||
/<script.*?>.*?<\/script[^>]*>/is, // OK
|
||||
/<!--.*-->/is, // OK - we don't care regexps that only match comments
|
||||
/<!--.*--!?>/is, // OK
|
||||
/<!--.*--!?>/i, // NOT OK, does not match newlines
|
||||
/<script.*?>(.|\s)*?<\/script[^>]*>/i, // NOT OK - doesn't match inside the script tag
|
||||
/<script[^>]*?>.*?<\/script[^>]*>/i, // NOT OK - doesn't match newlines inside the content
|
||||
/<script(\s|\w|=|")*?>.*?<\/script[^>]*>/is, // NOT OK - does not match single quotes for attribute values
|
||||
/<script(\s|\w|=|')*?>.*?<\/script[^>]*>/is, // NOT OK - does not match double quotes for attribute values
|
||||
/<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>/is, // NOT OK - does not match tabs between attributes
|
||||
/<script.*?>.*?<\/script[^>]*>/s, // NOT OK - does not match uppercase SCRIPT tags
|
||||
/<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>/s, // NOT OK - does not match mixed case script tags
|
||||
/<script[^>]*?>[\s\S]*?<\/script.*>/i, // NOT OK - doesn't match newlines in the end tag
|
||||
/<script[^>]*?>[\s\S]*?<\/script[^>]*?>/i, // OK
|
||||
/<script\b[^>]*>([\s\S]*?)<\/script>/gi, // NOT OK - too strict matching on the end tag
|
||||
/<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>/, // NOT OK - doesn't match comments with the right capture groups
|
||||
/<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))/, // NOT OK - capture groups
|
||||
/(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi, // NOT OK - capture groups
|
||||
/<(?:(?:!--([\w\W]*?)-->)|(?:!\[CDATA\[([\w\W]*?)\]\]>)|(?:!DOCTYPE([\w\W]*?)>)|(?:\?([^\s\/<>]+) ?([\w\W]*?)[?/]>)|(?:\/([A-Za-z][A-Za-z0-9\-_\:\.]*)>)|(?:([A-Za-z][A-Za-z0-9\-_\:\.]*)((?:\s+[^"'>]+(?:(?:"[^"]*")|(?:'[^']*')|[^>]*))*|\/|\s+)>))/g, // NOT OK - capture groups
|
||||
/<!--([\w\W]*?)-->|<([^>]*?)>/g, // NOT OK - capture groups
|
||||
]
|
||||
|
||||
doFilters(filters)
|
||||
|
||||
var strip = '<script([^>]*)>([\\S\\s]*?)<\/script([^>]*)>'; // OK - it's used with the ignorecase flag
|
||||
new RegExp(strip, 'gi');
|
||||
@@ -0,0 +1,96 @@
|
||||
function badEncode(s) {
|
||||
return s.replace(/"/g, """)
|
||||
.replace(/'/g, "'")
|
||||
.replace(/&/g, "&");
|
||||
}
|
||||
|
||||
function goodEncode(s) {
|
||||
return s.replace(/&/g, "&")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function goodDecode(s) {
|
||||
return s.replace(/"/g, "\"")
|
||||
.replace(/'/g, "'")
|
||||
.replace(/&/g, "&");
|
||||
}
|
||||
|
||||
function badDecode(s) {
|
||||
return s.replace(/&/g, "&")
|
||||
.replace(/"/g, "\"")
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function cleverEncode(code) {
|
||||
return code.replace(/</g, '<').replace(/>/g, '>').replace(/&(?![\w\#]+;)/g, '&');
|
||||
}
|
||||
|
||||
function badDecode2(s) {
|
||||
return s.replace(/&/g, "&")
|
||||
.replace(/s?ome|thin*g/g, "else")
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function goodDecodeInLoop(ss) {
|
||||
var res = [];
|
||||
for (var s of ss) {
|
||||
s = s.replace(/"/g, "\"")
|
||||
.replace(/'/g, "'")
|
||||
.replace(/&/g, "&");
|
||||
res.push(s);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function badDecode3(s) {
|
||||
s = s.replace(/&/g, "&");
|
||||
s = s.replace(/"/g, "\"");
|
||||
return s.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function badUnescape(s) {
|
||||
return s.replace(/\\\\/g, '\\')
|
||||
.replace(/\\'/g, '\'')
|
||||
.replace(/\\"/g, '\"');
|
||||
}
|
||||
|
||||
function badPercentEscape(s) {
|
||||
s = s.replace(/&/g, '%26');
|
||||
s = s.replace(/%/g, '%25');
|
||||
return s;
|
||||
}
|
||||
|
||||
function badEncode(s) {
|
||||
var indirect1 = /"/g;
|
||||
var indirect2 = /'/g;
|
||||
var indirect3 = /&/g;
|
||||
return s.replace(indirect1, """)
|
||||
.replace(indirect2, "'")
|
||||
.replace(indirect3, "&");
|
||||
}
|
||||
|
||||
function badEncodeWithReplacer(s) {
|
||||
var repl = {
|
||||
'"': """,
|
||||
"'": "'",
|
||||
"&": "&"
|
||||
};
|
||||
return s.replace(/["']/g, (c) => repl[c]).replace(/&/g, "&");
|
||||
}
|
||||
|
||||
// dubious, but out of scope for this query
|
||||
function badRoundtrip(s) {
|
||||
return s.replace(/\\\\/g, "\\").replace(/\\/g, "\\\\");
|
||||
}
|
||||
|
||||
function testWithCapturedVar(x) {
|
||||
var captured = x;
|
||||
(function() {
|
||||
captured = captured.replace(/\\/g, "\\\\");
|
||||
})();
|
||||
}
|
||||
|
||||
function encodeDecodeEncode(s) {
|
||||
return goodEncode(goodDecode(goodEncode(s)));
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
(function(){
|
||||
let defaultPattern = /<(([\w:]+)[^>]*)\/>/gi;
|
||||
let expanded = "<$1></$2>";
|
||||
|
||||
// lib1
|
||||
html.replace(
|
||||
/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
|
||||
expanded
|
||||
); // NOT OK
|
||||
html.replace(/<(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, expanded); // NOT OK
|
||||
|
||||
// lib2
|
||||
html.replace(
|
||||
/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
|
||||
expanded
|
||||
); // NOT OK
|
||||
html.replace(/<(([\w:]+)[^>]*)\/>/gi, expanded); // NOT OK
|
||||
|
||||
// lib3
|
||||
html.replace(
|
||||
/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
|
||||
expanded
|
||||
); // NOT OK
|
||||
html.replace(/<(([\w:-]+)[^>]*)\/>/gi, expanded); // NOT OK
|
||||
|
||||
html.replace(defaultPattern, expanded); // NOT OK
|
||||
function getPattern() {
|
||||
return defaultPattern;
|
||||
}
|
||||
html.replace(getPattern(), expanded); // NOT OK
|
||||
|
||||
function getExpanded() {
|
||||
return expanded;
|
||||
}
|
||||
html.replace(defaultPattern, getExpanded()); // NOT OK (but not tracking the expansion string)
|
||||
html.replace(defaultPattern, something); // OK (possibly)
|
||||
defaultPattern.match(something); // OK (possibly)
|
||||
getPattern().match(something); // OK (possibly)
|
||||
});
|
||||
@@ -0,0 +1,155 @@
|
||||
// CVE-2019-10756
|
||||
(function(content) {
|
||||
content = content.replace(/<.*cript.*\/scrip.*>/gi, ""); // NOT OK
|
||||
content = content.replace(/ on\w+=".*"/g, ""); // NOT OK
|
||||
content = content.replace(/ on\w+=\'.*\'/g, ""); // NOT OK
|
||||
return content;
|
||||
});
|
||||
(function(content) {
|
||||
content = content.replace(/<.*cript.*/gi, ""); // NOT OK
|
||||
content = content.replace(/.on\w+=.*".*"/g, ""); // NOT OK
|
||||
content = content.replace(/.on\w+=.*\'.*\'/g, ""); // NOT OK
|
||||
|
||||
return content;
|
||||
});
|
||||
|
||||
// CVE-2020-7656
|
||||
(function(responseText) {
|
||||
var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
|
||||
responseText.replace(rscript, ""); // NOT OK
|
||||
return responseText;
|
||||
});
|
||||
|
||||
// CVE-2019-1010091
|
||||
(function(text) {
|
||||
text = text.replace(/<!--|--!?>/g, ""); // NOT OK
|
||||
return text;
|
||||
});
|
||||
(function(text) {
|
||||
while (/<!--|--!?>/g.test(text)) {
|
||||
text = text.replace(/<!--|--!?>/g, ""); // OK
|
||||
}
|
||||
|
||||
return text;
|
||||
});
|
||||
|
||||
// CVE-2019-10767
|
||||
(function(id) {
|
||||
id = id.replace(/\.\./g, ""); // OK (can not contain '..' afterwards)
|
||||
return id;
|
||||
});
|
||||
(function(id) {
|
||||
id = id.replace(/[\]\[*,;'"`<>\\?\/]/g, ""); // OK (or is it?)
|
||||
return id;
|
||||
});
|
||||
|
||||
// CVE-2019-8903
|
||||
(function(req) {
|
||||
var REG_TRAVEL = /(\/)?\.\.\//g;
|
||||
req.url = req.url.replace(REG_TRAVEL, ""); // NOT OK
|
||||
});
|
||||
(function(req) {
|
||||
var beg;
|
||||
for (var i = 0; i < req.url.length; i++) {
|
||||
if (req.url[i] === "." && req.url[i + 1] === "/") beg = i + 1;
|
||||
else if (req.url[i] === "?") break;
|
||||
}
|
||||
|
||||
if (beg) req.url = req.url.substring(beg);
|
||||
});
|
||||
|
||||
// New cases
|
||||
|
||||
(function(x) {
|
||||
x = x.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/g, ""); // NOT OK
|
||||
|
||||
x = x.replace(/(\/|\s)on\w+=(\'|")?[^"]*(\'|")?/g, ""); // NOT OK
|
||||
|
||||
x = x.replace(/<\/script>/g, ""); // OK
|
||||
|
||||
x = x.replace(/<(.)?br(.)?>/g, ""); // OK
|
||||
x = x.replace(/<\/?b>/g, ""); // OK
|
||||
x = x.replace(/<(ul|ol)><\/(ul|ol)>/gi, ""); // OK
|
||||
x = x.replace(/<li><\/li>/gi, ""); // OK
|
||||
|
||||
x = x.replace(/<!--(.*?)-->/gm, ""); // NOT OK
|
||||
x = x.replace(/\sng-[a-z-]+/, ""); // NOT OK
|
||||
x = x.replace(/\sng-[a-z-]+/g, ""); // NOT OK (ng-attributes)
|
||||
|
||||
x = x.replace(/(<!--\[CDATA\[|\]\]-->)/g, "\n"); // OK: not a sanitizer
|
||||
|
||||
x = x.replace(/<script.+desktop\-only.+<\/script>/g, ""); // OK [INCONSISTENCY]
|
||||
x = x.replace(/<script async.+?<\/script>/g, ""); // OK
|
||||
x = x.replace(/<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi, ""); // NOT OK
|
||||
|
||||
x = x.replace(/\x2E\x2E\x2F\x2E\x2E\x2F/g, ""); // NOT OK (matches "../../")
|
||||
|
||||
x = x.replace(/<script.*>.*<\/script>/gi, ""); // NOT OK
|
||||
|
||||
x = x.replace(/^(\.\.\/?)+/g, ""); // OK
|
||||
|
||||
// NOT OK
|
||||
x = x.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/g, function(
|
||||
$0
|
||||
) {
|
||||
return unknown ? $0 : "";
|
||||
});
|
||||
|
||||
x = x.replace(/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, ""); // NOT OK [INCONSISTENCY]
|
||||
|
||||
x = x.replace(/\.\./g, ""); // OK
|
||||
x = x.replace(/\.\.\//g, ""); // NOT OK
|
||||
x = x.replace(/\/\.\./g, ""); // NOT OK
|
||||
|
||||
x = x.replace(/<script(.*?)>([\s\S]*?)<\/script>/gi, ""); // NOT OK
|
||||
|
||||
x = x.replace(/<(script|del)(?=[\s>])[\w\W]*?<\/\1\s*>/gi, ""); // NOT OK
|
||||
x = x.replace(/\<script[\s\S]*?\>[\s\S]*?\<\/script\>/g, ""); // NOT OK
|
||||
x = x.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm, ""); // NOT OK
|
||||
x = x.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, ""); // NOT OK
|
||||
x = x.replace(/<script[\s\S]*?<\/script>/gi, ""); // NOT OK
|
||||
x = x.replace(/ ?<!-- ?/g, ""); // NOT OK
|
||||
x = x.replace(/require\('\.\.\/common'\);/g, ""); // OK
|
||||
x = x.replace(/\.\.\/\.\.\/lib\//g, ""); // OK
|
||||
|
||||
while (x.indexOf(".") !== -1) {
|
||||
x = x
|
||||
.replace(/^\.\//, "")
|
||||
.replace(/\/\.\//, "/")
|
||||
.replace(/[^\/]*\/\.\.\//, ""); // OK
|
||||
}
|
||||
|
||||
x = x.replace(/([^.\s]+\.)+/, ""); // OK
|
||||
|
||||
x = x.replace(/<!\-\-DEVEL[\d\D]*?DEVEL\-\->/g, ""); // OK
|
||||
|
||||
x = x
|
||||
.replace(/^\.\//, "")
|
||||
.replace(/\/\.\//, "/")
|
||||
.replace(/[^\/]*\/\.\.\//, ""); // NOT OK
|
||||
|
||||
return x;
|
||||
});
|
||||
|
||||
(function (content) {
|
||||
content.replace(/<script.*\/script>/gi, ""); // NOT OK
|
||||
content.replace(/<(script).*\/script>/gi, ""); // NOT OK
|
||||
content.replace(/.+<(script).*\/script>/gi, ""); // NOT OK
|
||||
content.replace(/.*<(script).*\/script>/gi, ""); // NOT OK
|
||||
});
|
||||
|
||||
(function (content) {
|
||||
content = content.replace(/<script[\s\S]*?<\/script>/gi, ""); // NOT OK
|
||||
content = content.replace(/<[a-zA-Z\/](.|\n)*?>/g, '') || ' '; // NOT OK
|
||||
content = content.replace(/<(script|iframe|video)[\s\S]*?<\/(script|iframe|video)>/g, '') // NOT OK
|
||||
content = content.replace(/<(script|iframe|video)(.|\s)*?\/(script|iframe|video)>/g, '') // NOT OK
|
||||
content = content.replace(/<[^<]*>/g, ""); // OK
|
||||
|
||||
n.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi, '').replace(/[\w:\-]+/gi, function(a) { // NOT OK
|
||||
o.push({specified : 1, nodeName : a});
|
||||
});
|
||||
|
||||
n.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi, '').replace(/[\w:\-]+/gi, function(a) { // NOT OK
|
||||
o.push({specified : 1, nodeName : a});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,330 @@
|
||||
let express = require('express');
|
||||
var app = express();
|
||||
|
||||
function bad1(s) {
|
||||
return s.replace("'", ""); // NOT OK
|
||||
}
|
||||
|
||||
function bad2(s) {
|
||||
return s.replace(/'/, ""); // NOT OK
|
||||
}
|
||||
|
||||
function bad3(s) {
|
||||
return s.replace(/'/g, "\\'"); // NOT OK
|
||||
}
|
||||
|
||||
function bad4(s) {
|
||||
return s.replace(/'/g, "\\$&"); // NOT OK
|
||||
}
|
||||
|
||||
function bad5(s) {
|
||||
return s.replace(/['"]/g, "\\$&"); // NOT OK
|
||||
}
|
||||
|
||||
function bad6(s) {
|
||||
return s.replace(/(['"])/g, "\\$1"); // NOT OK
|
||||
}
|
||||
|
||||
function bad7(s) {
|
||||
return s.replace(/('|")/g, "\\$1"); // NOT OK
|
||||
}
|
||||
|
||||
function bad8(s) {
|
||||
return s.replace('|', ''); // NOT OK
|
||||
}
|
||||
|
||||
function bad9(s) {
|
||||
return s.replace(/"/g, "\\\""); // NOT OK
|
||||
}
|
||||
|
||||
function bad10(s) {
|
||||
return s.replace("/", "%2F"); // NOT OK
|
||||
}
|
||||
|
||||
function bad11(s) {
|
||||
return s.replace("%25", "%"); // NOT OK
|
||||
}
|
||||
|
||||
function bad12(s) {
|
||||
return s.replace(`'`, ""); // NOT OK
|
||||
}
|
||||
|
||||
function bad13(s) {
|
||||
return s.replace("'", ``); // NOT OK
|
||||
}
|
||||
|
||||
function bad14(s) {
|
||||
return s.replace(`'`, ``); // NOT OK
|
||||
}
|
||||
|
||||
function bad15(s) {
|
||||
return s.replace("'" + "", ""); // NOT OK
|
||||
}
|
||||
|
||||
function bad16(s) {
|
||||
return s.replace("'", "" + ""); // NOT OK
|
||||
}
|
||||
|
||||
function bad17(s) {
|
||||
return s.replace("'" + "", "" + ""); // NOT OK
|
||||
}
|
||||
|
||||
function good1(s) {
|
||||
while (s.indexOf("'") > 0)
|
||||
s = s.replace("'", ""); // OK
|
||||
return s;
|
||||
}
|
||||
|
||||
function good2(s) {
|
||||
while (s.indexOf("'") > 0)
|
||||
s = s.replace(/'/, ""); // OK
|
||||
return s;
|
||||
}
|
||||
|
||||
function good3(s) {
|
||||
return s.replace("@user", "id10t"); // OK
|
||||
}
|
||||
|
||||
function good4(s) {
|
||||
return s.replace(/#/g, "\\d+"); // OK
|
||||
}
|
||||
|
||||
function good5(s) {
|
||||
return s.replace(/\\/g, "\\\\").replace(/['"]/g, "\\$&"); // OK
|
||||
}
|
||||
|
||||
function good6(s) {
|
||||
return s.replace(/[\\]/g, '\\\\').replace(/[\"]/g, '\\"'); // OK
|
||||
}
|
||||
|
||||
function good7(s) {
|
||||
s = s.replace(/[\\]/g, '\\\\');
|
||||
return s.replace(/[\"]/g, '\\"'); // OK
|
||||
}
|
||||
|
||||
function good8(s) {
|
||||
return s.replace(/\W/g, '\\$&'); // OK
|
||||
}
|
||||
|
||||
function good9(s) {
|
||||
return s.replace(/[^\w\s]/g, '\\$&'); // OK
|
||||
}
|
||||
|
||||
function good10(s) {
|
||||
s = JSON.stringify(s); // NB: escapes backslashes
|
||||
s = s.slice(1, -1);
|
||||
s = s.replace(/\\"/g, '"');
|
||||
s = s.replace(/'/g, "\\'"); // OK
|
||||
return "'" + s + "'";
|
||||
}
|
||||
|
||||
function flowifyComments(s) {
|
||||
return s.replace(/#/g, '💩'); // OK
|
||||
}
|
||||
|
||||
function good11(s) {
|
||||
return s.replace("%d", "42");
|
||||
}
|
||||
|
||||
function good12(s) {
|
||||
s.replace('[', '').replace(']', ''); // OK
|
||||
s.replace('(', '').replace(')', ''); // OK
|
||||
s.replace('{', '').replace('}', ''); // OK
|
||||
s.replace('<', '').replace('>', ''); // NOT OK: too common as a bad HTML sanitizer
|
||||
|
||||
s.replace('[', '\\[').replace(']', '\\]'); // NOT OK
|
||||
s.replace('{', '\\{').replace('}', '\\}'); // NOT OK
|
||||
|
||||
s = s.replace('[', ''); // OK
|
||||
s = s.replace(']', ''); // OK
|
||||
s.replace(/{/, '').replace(/}/, ''); // NOT OK: should have used a string literal if a single replacement was intended
|
||||
s.replace(']', '').replace('[', ''); // probably OK, but still flagged
|
||||
}
|
||||
|
||||
function newlines(s) {
|
||||
// motivation for whitelist
|
||||
require("child_process").execSync("which emacs").toString().replace("\n", ""); // OK
|
||||
|
||||
x.replace("\n", "").replace(x, y); // NOT OK
|
||||
x.replace(x, y).replace("\n", ""); // NOT OK
|
||||
}
|
||||
|
||||
app.get('/some/path', function(req, res) {
|
||||
let untrusted = req.param("p");
|
||||
|
||||
// the query doesn't currently check whether untrusted input flows into the
|
||||
// sanitiser, but we add these calls anyway to make the tests more realistic
|
||||
|
||||
bad1(untrusted);
|
||||
bad2(untrusted);
|
||||
bad3(untrusted);
|
||||
bad4(untrusted);
|
||||
bad5(untrusted);
|
||||
bad6(untrusted);
|
||||
bad7(untrusted);
|
||||
bad8(untrusted);
|
||||
bad9(untrusted);
|
||||
bad10(untrusted);
|
||||
bad11(untrusted);
|
||||
bad12(untrusted);
|
||||
bad13(untrusted);
|
||||
bad14(untrusted);
|
||||
bad15(untrusted);
|
||||
bad16(untrusted);
|
||||
bad17(untrusted);
|
||||
|
||||
good1(untrusted);
|
||||
good2(untrusted);
|
||||
good3(untrusted);
|
||||
good4(untrusted);
|
||||
good5(untrusted);
|
||||
good6(untrusted);
|
||||
good7(untrusted);
|
||||
good8(untrusted);
|
||||
good9(untrusted);
|
||||
good10(untrusted);
|
||||
flowifyComments(untrusted);
|
||||
good11(untrusted);
|
||||
good12(untrusted);
|
||||
});
|
||||
|
||||
(function (s) {
|
||||
var indirect = /'/;
|
||||
return s.replace(indirect, ""); // NOT OK
|
||||
});
|
||||
|
||||
(function (s) {
|
||||
s.replace('"', '').replace('"', ''); // OK
|
||||
s.replace("'", "").replace("'", ""); // OK
|
||||
});
|
||||
|
||||
function bad18(p) {
|
||||
return p.replace("/../", ""); // NOT OK
|
||||
}
|
||||
|
||||
function typicalBadHtmlSanitizers(s) {
|
||||
s().replace(/[<>]/g,''); // NOT OK
|
||||
s().replace(/[<>&]/g, ''); // NOT OK
|
||||
s().replace(/[<>"]/g, ''); // NOT OK
|
||||
s().replace(/</g, '').replace(/>/g, ''); // NOT OK
|
||||
s().replace(/</g, '').replace(/>/g, '').replace(/&/g, ''); // NOT OK
|
||||
s().replace(/</g, '').replace(/&/g, '').replace(/>/g, ''); // NOT OK
|
||||
s().replace(/&/g, '').replace(/>/g, '').replace(/</g, ''); // NOT OK
|
||||
|
||||
var s = s().replace(/</g, '');
|
||||
s = s.replace(/>/g, ''); // NOT OK
|
||||
s().replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&').replace(/"/g, '"'); // OK
|
||||
s().replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&').replace(/'/g, '''); // OK - single quotes or double quotes both work
|
||||
|
||||
s().replace(/</g, '<').replace(/>/g, '>').replace(RE, function(match) {/* ... */ }); // OK (probably)
|
||||
|
||||
s().replace(/[<>'"&]/g,''); // OK
|
||||
|
||||
s().replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/&(?![\w\#]+;)/g, '&'); // OK
|
||||
|
||||
s().replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, '''); // OK (and not recognized due to the ternary)
|
||||
|
||||
s().replace(/[\\/:\*\?"<>\|]/g, ''); // OK
|
||||
|
||||
s().replace(/[<>]/g,'_'); // OK (but probably unsafe)
|
||||
|
||||
s().replace(/&/g, ">"); // OK
|
||||
|
||||
s().replace(/[\#\%4\/\-\~\>8\_\@0\!\&3\[651d\=e7fA2D\(aFBb]/g, ""); // OK
|
||||
|
||||
s().replace(/[<>]/g,'').replace(/[^a-z]/g, ''); // OK
|
||||
|
||||
s().replace(/[<>]/g,'').replace(/[^abc]/g, ''); // OK
|
||||
|
||||
s().replace(/[<>]/g,'').replace(/[ -~]/g, ''); // OK
|
||||
}
|
||||
|
||||
function incompleteHtmlAttributeSanitization() {
|
||||
'="' + s().replace(/[<>]/g,'') + '"'; // NOT OK
|
||||
'="' + s().replace(/[<>&]/g, '') + '"'; // NOT OK
|
||||
'="' + s().replace(/[<>"]/g, '') + '"'; // OK (maybe, since the attribute name is unknown)
|
||||
'="' + s().replace(/[<>&"]/g,'') + '"'; // OK
|
||||
'="' + s().replace(/[&"]/g,'') + '"'; // OK
|
||||
|
||||
'="' + s().replace(/[<>&']/g,'') + '"'; // NOT OK
|
||||
"='" + s().replace(/[<>&"]/g,'') + "'"; // NOT OK
|
||||
"='" + s().replace(/[<>&']/g,'') + "'"; // OK
|
||||
|
||||
'onFunkyEvent="' + s().replace(/[<>"]/g, '') + '"'; // NOT OK
|
||||
'<div noise onFunkyEvent="' + s().replace(/[<>"]/g, '') + '"'; // NOT OK
|
||||
'<div noise monday="' + s().replace(/[<>"]/g, '') + '"'; // OK
|
||||
'monday="' + s().replace(/[<>"]/g, '') + '"'; // OK
|
||||
}
|
||||
|
||||
function multiStepSanitization() {
|
||||
function escapeHTML(value) {
|
||||
return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
function attr_str(a) {
|
||||
return ' ' + a.name + '="' + escapeHTML(a.value).replace(/"/g, '"') + '"'; // OK
|
||||
}
|
||||
result += '<' + tag(node) + [].map.call(x, attr_str).join('') + '>';
|
||||
}
|
||||
|
||||
function moreIncompleteHtmlAttributeSanitization() {
|
||||
'<a' + noise + 'onclick="javascript:document.foo.bar(\'' + s().replace(/[<>"]/g, '') + '\'); return false;">'; // NOT OK
|
||||
'="' + s().replace(/[<>]/g,'').replace(/[^\w ]+/g, '') + '"'; // OK
|
||||
'="' + encodeURIComponent(s().replace(/[<>]/g,'')) + '"'; // OK
|
||||
|
||||
var arr = s().val().trim().replace(/^,|,$/g , '').replace(/^;|;$/g , '').replace(/<|>/g , '');
|
||||
'="' + arr.join(" ") + '"'; // NOT OK
|
||||
var arr2 = s().val().trim().replace(/^,|,$/g , '').replace(/^;|;$/g , '').replace(/<|>/g , '')
|
||||
arr2 = arr2.replace(/"/g,"");
|
||||
'="' + arr2.join(" ") + '"'; // OK
|
||||
|
||||
var x;
|
||||
x = x.replace(/&/g, '&');
|
||||
x = x.replace(/</g, '<').replace(/>/g, '>');
|
||||
'onclick="' + x + '"'; // NOT OK - but not flagged since the `x` replace chain is extended below
|
||||
x = x.replace(/"/g, '"');
|
||||
'onclick="' + x + '"'; // OK
|
||||
|
||||
var y;
|
||||
if (escapeAmpersand) {
|
||||
y = y.replace(/&/g, '&');
|
||||
}
|
||||
y = y.replace(/</g, '<').replace(/>/g, '>');
|
||||
'onclick="' + y + '"'; // NOT OK - but not flagged since the `x` replace chain is extended below
|
||||
if (escapeQuotes) {
|
||||
y = y.replace(/"/g, '"');
|
||||
}
|
||||
'onclick="' + y + '"'; // OK
|
||||
}
|
||||
|
||||
function incompleteHtmlAttributeSanitization2() {
|
||||
'=\'' + s().replace(/[&<>]/g,'') + '\''; // NOT OK
|
||||
'=\'' + s().replace(/[<>]/g,'') + '\''; // NOT OK
|
||||
'=\'' + s().replace(/[&<>"]/g,'') + '\''; // NOT OK
|
||||
'=\'' + s().replace(/[<>&]/g, '') + '\''; // NOT OK
|
||||
'="' + s().replace(/[<>&"]/g,'') + '"'; // OK
|
||||
'=\'' + s().replace(/[<>&']/g,'') + '\''; // OK
|
||||
}
|
||||
|
||||
function incompleteComplexSanitizers() {
|
||||
'=\'' + s().replace(/[&<>"]/gm, function (str) { // NOT OK
|
||||
if (str === "&")
|
||||
return "&";
|
||||
if (str === "<")
|
||||
return "<";
|
||||
if (str === ">")
|
||||
return ">";
|
||||
if (str === "\"")
|
||||
return """;
|
||||
}) + '\'';
|
||||
|
||||
'="' + s().replace(/[&<>"]/gm, function (str) { // OK
|
||||
if (str === "&")
|
||||
return "&";
|
||||
if (str === "<")
|
||||
return "<";
|
||||
if (str === ">")
|
||||
return ">";
|
||||
if (str === "\"")
|
||||
return """;
|
||||
}) + '"';
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,17 @@
|
||||
|
||||
# This script updates the JavaScript test data used by the endpoint CodeQL tests.
|
||||
|
||||
import glob
|
||||
import git
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
# Get relevant paths
|
||||
script_path = Path(__file__).absolute()
|
||||
git_repo = git.Repo(__file__, search_parent_directories=True)
|
||||
git_root = Path(git_repo.git.rev_parse('--show-toplevel'))
|
||||
autogenerated_dest_path = script_path.parent.joinpath('endpoint_large_scale',
|
||||
'autogenerated')
|
||||
|
||||
# File extensions that should be copied to the endpoint tests. This should include source code files
|
||||
# e.g. .js, but not the tests themselves e.g. .expected, .ql, .qlref, etc.
|
||||
@@ -15,35 +22,31 @@ file_extensions_to_copy = ['.js', '.ts']
|
||||
# path of that test relative to a checkout of github/codeql.
|
||||
test_root_relative_paths = {
|
||||
'NosqlAndSqlInjection': 'javascript/ql/test/query-tests/Security/CWE-089',
|
||||
'TaintedPath': 'javascript/ql/test/query-tests/Security/CWE-022/TaintedPath',
|
||||
'TaintedPath':
|
||||
'javascript/ql/test/query-tests/Security/CWE-022/TaintedPath',
|
||||
'Xss': 'javascript/ql/test/query-tests/Security/CWE-079',
|
||||
'XssThroughDom': 'javascript/ql/test/query-tests/Security/CWE-116'
|
||||
}
|
||||
# The path of the endpoint tests, relative to a checkout of github/codeql
|
||||
test_path = 'javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale'
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
codeql_lib_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))))
|
||||
|
||||
autogenerated_dest_path = os.path.join(codeql_lib_path, test_path, 'autogenerated')
|
||||
if os.path.exists(autogenerated_dest_path):
|
||||
if autogenerated_dest_path.exists():
|
||||
logging.info(f'Deleting existing autogenerated test files...')
|
||||
shutil.rmtree(autogenerated_dest_path)
|
||||
|
||||
for key, rel_path in test_root_relative_paths.items():
|
||||
test_files_path = os.path.join(codeql_lib_path, rel_path)
|
||||
test_files_path = git_root.joinpath(rel_path)
|
||||
logging.info(f'Copying test files for {key}...')
|
||||
|
||||
for file in glob.glob(test_files_path + '/**', recursive=True):
|
||||
# Ignore .testproj directories
|
||||
if '.testproj' in file:
|
||||
counter = 0
|
||||
for file in Path(test_files_path).glob('**/*'):
|
||||
if file.is_dir() or '.test_proj' in str(file):
|
||||
continue
|
||||
|
||||
file_extension = os.path.splitext(file)[1]
|
||||
if file_extension in file_extensions_to_copy:
|
||||
dest_path = os.path.normpath(
|
||||
os.path.join(autogenerated_dest_path, key, os.path.relpath(file, test_files_path))
|
||||
)
|
||||
if file.suffix in file_extensions_to_copy:
|
||||
autogenerated_dest_path.joinpath(key, )
|
||||
dest_path = autogenerated_dest_path.joinpath(
|
||||
key, file.relative_to(test_files_path))
|
||||
logging.debug(f'Copying {file} to {dest_path}')
|
||||
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
|
||||
dest_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copyfile(file, dest_path)
|
||||
counter += 1
|
||||
logging.info(f'copied {counter} files')
|
||||
|
||||
Reference in New Issue
Block a user