diff --git a/javascript/ql/lib/change-notes/2025-04-07-open-package.md b/javascript/ql/lib/change-notes/2025-04-07-open-package.md new file mode 100644 index 000000000000..a4c02f0d6d9e --- /dev/null +++ b/javascript/ql/lib/change-notes/2025-04-07-open-package.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added support for the `open` package. diff --git a/javascript/ql/lib/ext/open.model.yml b/javascript/ql/lib/ext/open.model.yml new file mode 100644 index 000000000000..2159fe794d74 --- /dev/null +++ b/javascript/ql/lib/ext/open.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sinkModel + data: + - ["open", "Argument[0]", "path-injection"] + - ["open", "Member[openApp].Argument[0]", "path-injection"] diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index 99be2545b8e3..88334b64c38b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -140,6 +140,8 @@ | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | normalizedPaths.js:408:38:408:48 | req.query.x | normalizedPaths.js:408:19:408:60 | pathMod ... t('/')) | This path depends on a $@. | normalizedPaths.js:408:38:408:48 | req.query.x | user-provided value | | normalizedPaths.js:415:19:415:22 | path | normalizedPaths.js:412:35:412:45 | req.query.x | normalizedPaths.js:415:19:415:22 | path | This path depends on a $@. | normalizedPaths.js:412:35:412:45 | req.query.x | user-provided value | | normalizedPaths.js:426:21:426:24 | path | normalizedPaths.js:412:35:412:45 | req.query.x | normalizedPaths.js:426:21:426:24 | path | This path depends on a $@. | normalizedPaths.js:412:35:412:45 | req.query.x | user-provided value | +| open.js:9:10:9:13 | file | open.js:7:18:7:31 | req.query.file | open.js:9:10:9:13 | file | This path depends on a $@. | open.js:7:18:7:31 | req.query.file | user-provided value | +| open.js:10:13:10:16 | file | open.js:7:18:7:31 | req.query.file | open.js:10:13:10:16 | file | This path depends on a $@. | open.js:7:18:7:31 | req.query.file | user-provided value | | other-fs-libraries.js:11:19:11:22 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:11:19:11:22 | path | This path depends on a $@. | other-fs-libraries.js:9:24:9:30 | req.url | user-provided value | | other-fs-libraries.js:12:27:12:30 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:12:27:12:30 | path | This path depends on a $@. | other-fs-libraries.js:9:24:9:30 | req.url | user-provided value | | other-fs-libraries.js:13:24:13:27 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:13:24:13:27 | path | This path depends on a $@. | other-fs-libraries.js:9:24:9:30 | req.url | user-provided value | @@ -561,6 +563,9 @@ edges | normalizedPaths.js:412:7:412:46 | path | normalizedPaths.js:426:21:426:24 | path | provenance | | | normalizedPaths.js:412:14:412:46 | pathMod ... uery.x) | normalizedPaths.js:412:7:412:46 | path | provenance | | | normalizedPaths.js:412:35:412:45 | req.query.x | normalizedPaths.js:412:14:412:46 | pathMod ... uery.x) | provenance | Config | +| open.js:7:11:7:31 | file | open.js:9:10:9:13 | file | provenance | | +| open.js:7:11:7:31 | file | open.js:10:13:10:16 | file | provenance | | +| open.js:7:18:7:31 | req.query.file | open.js:7:11:7:31 | file | provenance | | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path | provenance | | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:12:27:12:30 | path | provenance | | | other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:13:24:13:27 | path | provenance | | @@ -1116,6 +1121,10 @@ nodes | normalizedPaths.js:412:35:412:45 | req.query.x | semmle.label | req.query.x | | normalizedPaths.js:415:19:415:22 | path | semmle.label | path | | normalizedPaths.js:426:21:426:24 | path | semmle.label | path | +| open.js:7:11:7:31 | file | semmle.label | file | +| open.js:7:18:7:31 | req.query.file | semmle.label | req.query.file | +| open.js:9:10:9:13 | file | semmle.label | file | +| open.js:10:13:10:16 | file | semmle.label | file | | other-fs-libraries.js:9:7:9:48 | path | semmle.label | path | | other-fs-libraries.js:9:14:9:37 | url.par ... , true) | semmle.label | url.par ... , true) | | other-fs-libraries.js:9:14:9:43 | url.par ... ).query | semmle.label | url.par ... ).query | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/open.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/open.js new file mode 100644 index 000000000000..ce93d6284a2a --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/open.js @@ -0,0 +1,11 @@ +import open, {openApp, apps} from 'open'; + +const express = require('express'); +const app = express(); + +app.get('/open', (req, res) => { + const file = req.query.file; // $ Source + + open(file); // $ Alert + openApp(file); // $ Alert +});