From 312471e9db575802bba7fc49bead23732e84b22e Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Mon, 15 Sep 2025 16:55:27 +0200 Subject: [PATCH] JS: Add modeling for `@google-cloud/promisify` --- .../ql/lib/semmle/javascript/Promises.qll | 4 +++- .../CommandInjection/CommandInjection.expected | 18 ++++++++++++++++++ .../CommandInjection/promisification.js | 12 ++++++------ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Promises.qll b/javascript/ql/lib/semmle/javascript/Promises.qll index fb80af858f2..91ae38b9418 100644 --- a/javascript/ql/lib/semmle/javascript/Promises.qll +++ b/javascript/ql/lib/semmle/javascript/Promises.qll @@ -727,7 +727,7 @@ module Promisify { PromisifyAllCall() { this = [ - DataFlow::moduleMember("bluebird", "promisifyAll"), + DataFlow::moduleMember(["bluebird", "@google-cloud/promisify"], "promisifyAll"), DataFlow::moduleMember("thenify-all", "withCallback"), DataFlow::moduleImport(["util-promisifyall", "pify", "thenify-all"]) ].getACall() @@ -747,6 +747,8 @@ module Promisify { this = DataFlow::moduleImport("thenify").getACall() or this = DataFlow::moduleMember("thenify", "withCallback").getACall() + or + this = DataFlow::moduleMember("@google-cloud/promisify", "promisify").getACall() } } } diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected index d68af94417c..bb89e9d0654 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected @@ -90,6 +90,11 @@ | promisification.js:102:27:102:30 | code | promisification.js:99:18:99:25 | req.body | promisification.js:102:27:102:30 | code | This command line depends on a $@. | promisification.js:99:18:99:25 | req.body | user-provided value | | promisification.js:106:24:106:27 | code | promisification.js:99:18:99:25 | req.body | promisification.js:106:24:106:27 | code | This command line depends on a $@. | promisification.js:99:18:99:25 | req.body | user-provided value | | promisification.js:109:24:109:27 | code | promisification.js:99:18:99:25 | req.body | promisification.js:109:24:109:27 | code | This command line depends on a $@. | promisification.js:99:18:99:25 | req.body | user-provided value | +| promisification.js:144:21:144:24 | code | promisification.js:141:18:141:25 | req.body | promisification.js:144:21:144:24 | code | This command line depends on a $@. | promisification.js:141:18:141:25 | req.body | user-provided value | +| promisification.js:147:15:147:18 | code | promisification.js:141:18:141:25 | req.body | promisification.js:147:15:147:18 | code | This command line depends on a $@. | promisification.js:141:18:141:25 | req.body | user-provided value | +| promisification.js:150:24:150:27 | code | promisification.js:141:18:141:25 | req.body | promisification.js:150:24:150:27 | code | This command line depends on a $@. | promisification.js:141:18:141:25 | req.body | user-provided value | +| promisification.js:151:28:151:31 | code | promisification.js:141:18:141:25 | req.body | promisification.js:151:28:151:31 | code | This command line depends on a $@. | promisification.js:141:18:141:25 | req.body | user-provided value | +| promisification.js:152:25:152:28 | code | promisification.js:141:18:141:25 | req.body | promisification.js:152:25:152:28 | code | This command line depends on a $@. | promisification.js:141:18:141:25 | req.body | user-provided value | | third-party-command-injection.js:6:21:6:27 | command | third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | This command line depends on a $@. | third-party-command-injection.js:5:20:5:26 | command | user-provided value | edges | actions.js:8:9:8:13 | title | actions.js:9:16:9:20 | title | provenance | | @@ -278,6 +283,12 @@ edges | promisification.js:99:11:99:14 | code | promisification.js:106:24:106:27 | code | provenance | | | promisification.js:99:11:99:14 | code | promisification.js:109:24:109:27 | code | provenance | | | promisification.js:99:18:99:25 | req.body | promisification.js:99:11:99:14 | code | provenance | | +| promisification.js:141:11:141:14 | code | promisification.js:144:21:144:24 | code | provenance | | +| promisification.js:141:11:141:14 | code | promisification.js:147:15:147:18 | code | provenance | | +| promisification.js:141:11:141:14 | code | promisification.js:150:24:150:27 | code | provenance | | +| promisification.js:141:11:141:14 | code | promisification.js:151:28:151:31 | code | provenance | | +| promisification.js:141:11:141:14 | code | promisification.js:152:25:152:28 | code | provenance | | +| promisification.js:141:18:141:25 | req.body | promisification.js:141:11:141:14 | code | provenance | | | third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | provenance | | nodes | actions.js:8:9:8:13 | title | semmle.label | title | @@ -479,6 +490,13 @@ nodes | promisification.js:102:27:102:30 | code | semmle.label | code | | promisification.js:106:24:106:27 | code | semmle.label | code | | promisification.js:109:24:109:27 | code | semmle.label | code | +| promisification.js:141:11:141:14 | code | semmle.label | code | +| promisification.js:141:18:141:25 | req.body | semmle.label | req.body | +| promisification.js:144:21:144:24 | code | semmle.label | code | +| promisification.js:147:15:147:18 | code | semmle.label | code | +| promisification.js:150:24:150:27 | code | semmle.label | code | +| promisification.js:151:28:151:31 | code | semmle.label | code | +| promisification.js:152:25:152:28 | code | semmle.label | code | | third-party-command-injection.js:5:20:5:26 | command | semmle.label | command | | third-party-command-injection.js:6:21:6:27 | command | semmle.label | command | subpaths diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/promisification.js b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/promisification.js index 598cd9bb471..5dcefce9896 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/promisification.js +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/promisification.js @@ -138,16 +138,16 @@ app.post('/eval', async (req, res) => { app.post('/eval', async (req, res) => { const {promisify, promisifyAll} = require('@google-cloud/promisify'); - const code = req.body; // $ MISSING: Source + const code = req.body; // $ Source const promisifiedExec = promisify(cp.exec); - promisifiedExec(code); // $ MISSING: Alert + promisifiedExec(code); // $ Alert const execAsync = promisify(cp.exec.bind(cp)); - execAsync(code); // $ MISSING: Alert + execAsync(code); // $ Alert const promisifiedCp = promisifyAll(cp); - promisifiedCp.exec(code); // $ MISSING: Alert - promisifiedCp.execFile(code); // $ MISSING: Alert - promisifiedCp.spawn(code); // $ MISSING: Alert + promisifiedCp.exec(code); // $ Alert + promisifiedCp.execFile(code); // $ Alert + promisifiedCp.spawn(code); // $ Alert });