Skip to content

Commit d4b4d22

Browse files
committed
JS: Step through HTML sanitizers in SQL injection query
1 parent 56b6441 commit d4b4d22

File tree

4 files changed

+40
-0
lines changed

4 files changed

+40
-0
lines changed

javascript/ql/lib/semmle/javascript/security/dataflow/SqlInjectionQuery.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,10 @@ class Configuration extends TaintTracking::Configuration {
3030
pred = filter.getInput() and
3131
succ = filter.getOutput()
3232
)
33+
or
34+
exists(HtmlSanitizerCall call |
35+
pred = call.getInput() and
36+
succ = call
37+
)
3338
}
3439
}

javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
| html-sanitizer.js:15:5:17:5 | connect ... K\\n ) |
12
| json-schema-validator.js:27:13:27:27 | doc.find(query) |
23
| json-schema-validator.js:30:13:30:27 | doc.find(query) |
34
| json-schema-validator.js:33:13:33:27 | doc.find(query) |

javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ nodes
5050
| graphql.js:120:38:120:48 | `foo ${id}` |
5151
| graphql.js:120:38:120:48 | `foo ${id}` |
5252
| graphql.js:120:45:120:46 | id |
53+
| html-sanitizer.js:13:39:13:44 | param1 |
54+
| html-sanitizer.js:13:39:13:44 | param1 |
55+
| html-sanitizer.js:14:5:14:24 | param1 |
56+
| html-sanitizer.js:14:14:14:24 | xss(param1) |
57+
| html-sanitizer.js:14:18:14:23 | param1 |
58+
| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 |
59+
| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 |
60+
| html-sanitizer.js:16:54:16:59 | param1 |
5361
| json-schema-validator.js:25:15:25:48 | query |
5462
| json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) |
5563
| json-schema-validator.js:25:34:25:47 | req.query.data |
@@ -466,6 +474,13 @@ edges
466474
| graphql.js:119:16:119:28 | req.params.id | graphql.js:119:11:119:28 | id |
467475
| graphql.js:120:45:120:46 | id | graphql.js:120:38:120:48 | `foo ${id}` |
468476
| graphql.js:120:45:120:46 | id | graphql.js:120:38:120:48 | `foo ${id}` |
477+
| html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:14:18:14:23 | param1 |
478+
| html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:14:18:14:23 | param1 |
479+
| html-sanitizer.js:14:5:14:24 | param1 | html-sanitizer.js:16:54:16:59 | param1 |
480+
| html-sanitizer.js:14:14:14:24 | xss(param1) | html-sanitizer.js:14:5:14:24 | param1 |
481+
| html-sanitizer.js:14:18:14:23 | param1 | html-sanitizer.js:14:14:14:24 | xss(param1) |
482+
| html-sanitizer.js:16:54:16:59 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 |
483+
| html-sanitizer.js:16:54:16:59 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 |
469484
| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:33:22:33:26 | query |
470485
| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:33:22:33:26 | query |
471486
| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:35:18:35:22 | query |
@@ -924,6 +939,7 @@ edges
924939
| graphql.js:75:46:75:64 | "{ foo" + id + " }" | graphql.js:74:14:74:25 | req.query.id | graphql.js:75:46:75:64 | "{ foo" + id + " }" | This query depends on a $@. | graphql.js:74:14:74:25 | req.query.id | user-provided value |
925940
| graphql.js:84:14:90:8 | `{\\n ... }` | graphql.js:74:14:74:25 | req.query.id | graphql.js:84:14:90:8 | `{\\n ... }` | This query depends on a $@. | graphql.js:74:14:74:25 | req.query.id | user-provided value |
926941
| graphql.js:120:38:120:48 | `foo ${id}` | graphql.js:119:16:119:28 | req.params.id | graphql.js:120:38:120:48 | `foo ${id}` | This query depends on a $@. | graphql.js:119:16:119:28 | req.params.id | user-provided value |
942+
| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | This query depends on a $@. | html-sanitizer.js:13:39:13:44 | param1 | user-provided value |
927943
| json-schema-validator.js:33:22:33:26 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:33:22:33:26 | query | This query depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value |
928944
| json-schema-validator.js:35:18:35:22 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:35:18:35:22 | query | This query depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value |
929945
| json-schema-validator.js:55:22:55:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:55:22:55:26 | query | This query depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value |
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const route = require('koa-route');
2+
const Koa = require('koa');
3+
const mysql = require('mysql2');
4+
const app = new Koa();
5+
const xss = require('xss');
6+
7+
const connection = mysql.createConnection({
8+
host: 'localhost',
9+
user: 'root',
10+
database: 'test'
11+
});
12+
13+
app.use(route.get('/test1', (context, param1) => {
14+
param1 = xss(param1)
15+
connection.query(
16+
`SELECT * FROM \`table\` WHERE \`name\` =` + param1, // NOT OK
17+
);
18+
}));

0 commit comments

Comments
 (0)