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:
Jean Helie
2022-12-19 10:55:30 +01:00
committed by GitHub
50 changed files with 19379 additions and 2894 deletions

View File

@@ -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] |

View File

@@ -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) |

View File

@@ -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).

View File

@@ -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
});

View File

@@ -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
}
});
});

View File

@@ -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, () => {});

View File

@@ -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) => {});
});

View File

@@ -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) => {});
});

View File

@@ -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) {});
});
});

View File

@@ -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
);

View File

@@ -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
});

View File

@@ -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);
});

View File

@@ -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"
}));
});

View File

@@ -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
}
});

View File

@@ -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
});

View File

@@ -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);
});
});

View File

@@ -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
});

View File

@@ -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;
});
});

View File

@@ -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
}
}
}

View File

@@ -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
}

View File

@@ -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
});
})();

View File

@@ -0,0 +1,7 @@
import * as dummy from 'dummy';
class CustomElm extends HTMLElement {
test() {
this.innerHTML = window.name; // NOT OK
}
}

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -57,3 +57,13 @@ function Node() {}
* @type {Node}
*/
Node.prototype.parentNode;
/**
* @return {DomObjectStub}
*/
DomObjectStub.prototype.insertRow = function() {};
/**
* @return {DomObjectStub}
*/
DomObjectStub.prototype.insertCell = function() {};

View File

@@ -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
}

View File

@@ -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');
})();

View File

@@ -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
}

View File

@@ -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
});

View File

@@ -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
}
});

View File

@@ -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
}});

View File

@@ -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);

View File

@@ -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
});

View File

@@ -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
});

View File

@@ -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
}

View File

@@ -0,0 +1,4 @@
export function trivialXss(s: string) {
const html = "<span>" + s + "</span>"; // NOT OK
document.querySelector("#html").innerHTML = html;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
};
});

View File

@@ -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:&quot;&gt;&lt;img src=1 onerror=&quot;alert(1)&quot;&gt;" />`
}
}
(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
})();

View File

@@ -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');

View File

@@ -0,0 +1,96 @@
function badEncode(s) {
return s.replace(/"/g, "&quot;")
.replace(/'/g, "&apos;")
.replace(/&/g, "&amp;");
}
function goodEncode(s) {
return s.replace(/&/g, "&amp;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&apos;");
}
function goodDecode(s) {
return s.replace(/&quot;/g, "\"")
.replace(/&apos;/g, "'")
.replace(/&amp;/g, "&");
}
function badDecode(s) {
return s.replace(/&amp;/g, "&")
.replace(/&quot;/g, "\"")
.replace(/&apos;/g, "'");
}
function cleverEncode(code) {
return code.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/&(?![\w\#]+;)/g, '&amp;');
}
function badDecode2(s) {
return s.replace(/&amp;/g, "&")
.replace(/s?ome|thin*g/g, "else")
.replace(/&apos;/g, "'");
}
function goodDecodeInLoop(ss) {
var res = [];
for (var s of ss) {
s = s.replace(/&quot;/g, "\"")
.replace(/&apos;/g, "'")
.replace(/&amp;/g, "&");
res.push(s);
}
return res;
}
function badDecode3(s) {
s = s.replace(/&amp;/g, "&");
s = s.replace(/&quot;/g, "\"");
return s.replace(/&apos;/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, "&quot;")
.replace(indirect2, "&apos;")
.replace(indirect3, "&amp;");
}
function badEncodeWithReplacer(s) {
var repl = {
'"': "&quot;",
"'": "&apos;",
"&": "&amp;"
};
return s.replace(/["']/g, (c) => repl[c]).replace(/&/g, "&amp;");
}
// 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)));
}

View File

@@ -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)
});

View File

@@ -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});
});
});

View File

@@ -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, '&lt;').replace(/>/g, '&gt').replace(/&/g, '&amp;').replace(/"/g, '&#34;'); // OK
s().replace(/</g, '&lt;').replace(/>/g, '&gt').replace(/&/g, '&amp;').replace(/'/g, '&#39;'); // OK - single quotes or double quotes both work
s().replace(/</g, '&lt;').replace(/>/g, '&gt').replace(RE, function(match) {/* ... */ }); // OK (probably)
s().replace(/[<>'"&]/g,''); // OK
s().replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/&(?![\w\#]+;)/g, '&amp;'); // OK
s().replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); // OK (and not recognized due to the ternary)
s().replace(/[\\/:\*\?"<>\|]/g, ''); // OK
s().replace(/[<>]/g,'_'); // OK (but probably unsafe)
s().replace(/&/g, "&gt;"); // 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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function attr_str(a) {
return ' ' + a.name + '="' + escapeHTML(a.value).replace(/"/g, '&quot;') + '"'; // 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, '&amp;');
x = x.replace(/</g, '&lt;').replace(/>/g, '&gt;');
'onclick="' + x + '"'; // NOT OK - but not flagged since the `x` replace chain is extended below
x = x.replace(/"/g, '&quot;');
'onclick="' + x + '"'; // OK
var y;
if (escapeAmpersand) {
y = y.replace(/&/g, '&amp;');
}
y = y.replace(/</g, '&lt;').replace(/>/g, '&gt;');
'onclick="' + y + '"'; // NOT OK - but not flagged since the `x` replace chain is extended below
if (escapeQuotes) {
y = y.replace(/"/g, '&quot;');
}
'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 "&amp;";
if (str === "<")
return "&lt;";
if (str === ">")
return "&gt;";
if (str === "\"")
return "&quot;";
}) + '\'';
'="' + s().replace(/[&<>"]/gm, function (str) { // OK
if (str === "&")
return "&amp;";
if (str === "<")
return "&lt;";
if (str === ">")
return "&gt;";
if (str === "\"")
return "&quot;";
}) + '"';
}

View File

@@ -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')