Add sink model for SQL injection detection in exec clients.

This commit is contained in:
Napalys
2025-03-25 14:36:13 +01:00
parent 032cfc134f
commit 9229962096
3 changed files with 42 additions and 6 deletions

View File

@@ -0,0 +1,8 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- ["@sap/hana-client", "Member[createConnection].ReturnValue.Member[exec].Argument[0]", "sql-injection"]
- ["hdb", "Member[createClient].ReturnValue.Member[exec].Argument[0]", "sql-injection"]

View File

@@ -10,6 +10,10 @@
| graphql.js:74:46:74:64 | "{ foo" + id + " }" | graphql.js:73:14:73:25 | req.query.id | graphql.js:74:46:74:64 | "{ foo" + id + " }" | This query string depends on a $@. | graphql.js:73:14:73:25 | req.query.id | user-provided value |
| graphql.js:82:14:88:8 | `{\\n ... }` | graphql.js:73:14:73:25 | req.query.id | graphql.js:82:14:88:8 | `{\\n ... }` | This query string depends on a $@. | graphql.js:73:14:73:25 | req.query.id | user-provided value |
| graphql.js:118:38:118:48 | `foo ${id}` | graphql.js:117:16:117:28 | req.params.id | graphql.js:118:38:118:48 | `foo ${id}` | This query string depends on a $@. | graphql.js:117:16:117:28 | req.params.id | user-provided value |
| hana.js:11:19:11:23 | query | hana.js:9:30:9:37 | req.body | hana.js:11:19:11:23 | query | This query string depends on a $@. | hana.js:9:30:9:37 | req.body | user-provided value |
| hana.js:71:44:71:99 | "INSERT ... usInput | hana.js:68:24:68:31 | req.body | hana.js:71:44:71:99 | "INSERT ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
| hana.js:73:17:73:54 | 'select ... usInput | hana.js:68:24:68:31 | req.body | hana.js:73:17:73:54 | 'select ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
| hana.js:74:17:74:54 | 'select ... usInput | hana.js:68:24:68:31 | req.body | hana.js:74:17:74:54 | 'select ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
| 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 string depends on a $@. | html-sanitizer.js:13:39:13:44 | param1 | user-provided value |
| 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 object depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value |
| 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 object depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value |
@@ -152,6 +156,17 @@ edges
| graphql.js:117:11:117:28 | id | graphql.js:118:45:118:46 | id | provenance | |
| graphql.js:117:16:117:28 | req.params.id | graphql.js:117:11:117:28 | id | provenance | |
| graphql.js:118:45:118:46 | id | graphql.js:118:38:118:48 | `foo ${id}` | provenance | |
| hana.js:9:13:9:42 | maliciousInput | hana.js:10:64:10:77 | maliciousInput | provenance | |
| hana.js:9:30:9:37 | req.body | hana.js:9:13:9:42 | maliciousInput | provenance | |
| hana.js:10:15:10:80 | query | hana.js:11:19:11:23 | query | provenance | |
| hana.js:10:64:10:77 | maliciousInput | hana.js:10:15:10:80 | query | provenance | |
| hana.js:68:7:68:36 | maliciousInput | hana.js:71:86:71:99 | maliciousInput | provenance | |
| hana.js:68:7:68:36 | maliciousInput | hana.js:73:41:73:54 | maliciousInput | provenance | |
| hana.js:68:7:68:36 | maliciousInput | hana.js:74:41:74:54 | maliciousInput | provenance | |
| hana.js:68:24:68:31 | req.body | hana.js:68:7:68:36 | maliciousInput | provenance | |
| hana.js:71:86:71:99 | maliciousInput | hana.js:71:44:71:99 | "INSERT ... usInput | provenance | |
| hana.js:73:41:73:54 | maliciousInput | hana.js:73:17:73:54 | 'select ... usInput | provenance | |
| hana.js:74:41:74:54 | maliciousInput | hana.js:74:17:74:54 | 'select ... usInput | provenance | |
| html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:14:18:14:23 | param1 | provenance | |
| html-sanitizer.js:14:5:14:24 | param1 | html-sanitizer.js:16:54:16:59 | param1 | provenance | |
| html-sanitizer.js:14:14:14:24 | xss(param1) | html-sanitizer.js:14:5:14:24 | param1 | provenance | |
@@ -504,6 +519,19 @@ nodes
| graphql.js:117:16:117:28 | req.params.id | semmle.label | req.params.id |
| graphql.js:118:38:118:48 | `foo ${id}` | semmle.label | `foo ${id}` |
| graphql.js:118:45:118:46 | id | semmle.label | id |
| hana.js:9:13:9:42 | maliciousInput | semmle.label | maliciousInput |
| hana.js:9:30:9:37 | req.body | semmle.label | req.body |
| hana.js:10:15:10:80 | query | semmle.label | query |
| hana.js:10:64:10:77 | maliciousInput | semmle.label | maliciousInput |
| hana.js:11:19:11:23 | query | semmle.label | query |
| hana.js:68:7:68:36 | maliciousInput | semmle.label | maliciousInput |
| hana.js:68:24:68:31 | req.body | semmle.label | req.body |
| hana.js:71:44:71:99 | "INSERT ... usInput | semmle.label | "INSERT ... usInput |
| hana.js:71:86:71:99 | maliciousInput | semmle.label | maliciousInput |
| hana.js:73:17:73:54 | 'select ... usInput | semmle.label | 'select ... usInput |
| hana.js:73:41:73:54 | maliciousInput | semmle.label | maliciousInput |
| hana.js:74:17:74:54 | 'select ... usInput | semmle.label | 'select ... usInput |
| hana.js:74:41:74:54 | maliciousInput | semmle.label | maliciousInput |
| html-sanitizer.js:13:39:13:44 | param1 | semmle.label | param1 |
| html-sanitizer.js:14:5:14:24 | param1 | semmle.label | param1 |
| html-sanitizer.js:14:14:14:24 | xss(param1) | semmle.label | xss(param1) |

View File

@@ -6,9 +6,9 @@ const connectionParams = {};
app.post('/documents/find', (req, res) => {
const conn = hana.createConnection();
conn.connect(connectionParams, (err) => {
let maliciousInput = req.body.data; // $ MISSING: Source
let maliciousInput = req.body.data; // $ Source
const query = `SELECT * FROM Users WHERE username = '${maliciousInput}'`;
conn.exec(query, (err, rows) => {}); // $ MISSING: Alert
conn.exec(query, (err, rows) => {}); // $ Alert
conn.disconnect();
});
@@ -65,13 +65,13 @@ const app2 = express();
app2.post('/documents/find', (req, res) => {
var client = hdb.createClient(options);
let maliciousInput = req.body.data; // $ MISSING: Source
let maliciousInput = req.body.data; // $ Source
client.connect(function onconnect(err) {
async.series([client.exec.bind(client, "INSERT INTO NUMBERS VALUES (1, 'one')" + maliciousInput)], function (err) {}); // $ MISSING: Alert
async.series([client.exec.bind(client, "INSERT INTO NUMBERS VALUES (1, 'one')" + maliciousInput)], function (err) {}); // $ Alert
client.exec('select * from DUMMY' + maliciousInput, function (err, rows) {}); // $ MISSING: Alert
client.exec('select * from DUMMY' + maliciousInput, options, function(err, rows) {}); // $ MISSING: Alert
client.exec('select * from DUMMY' + maliciousInput, function (err, rows) {}); // $ Alert
client.exec('select * from DUMMY' + maliciousInput, options, function(err, rows) {}); // $ Alert
client.prepare('select * from DUMMY where DUMMY = ?' + maliciousInput, function (err, statement){ // $ MISSING: Alert
statement.exec([maliciousInput], function (err, rows) {}); // maliciousInput is treated as a parameter