From 674f40b35fdf4ea6aaf22c31b7a76d1f23c6d65a Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 9 Apr 2025 14:39:09 +0200 Subject: [PATCH 1/4] Added test cases for `make-dir` package. --- .../Security/CWE-022/TaintedPath/make-dir.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js new file mode 100644 index 000000000000..a91287bb0b0e --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js @@ -0,0 +1,11 @@ +import { makeDirectory, makeDirectorySync } from 'make-dir'; + +const express = require('express'); +const app = express(); + +app.get('/makedir', (req, res) => { + const file = req.query.file; // $ MISSING: Source + + makeDirectory(file); // $ MISSING: Alert + makeDirectorySync(file); // $ MISSING: Alert +}); From ce2fc25cdbd0c21bb40845f0ac317f6d1d47ddb2 Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 9 Apr 2025 14:40:28 +0200 Subject: [PATCH 2/4] Added `make-dir` model as data --- javascript/ql/lib/ext/make-dir.model.yml | 6 ++++++ .../Security/CWE-022/TaintedPath/TaintedPath.expected | 9 +++++++++ .../query-tests/Security/CWE-022/TaintedPath/make-dir.js | 6 +++--- 3 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 javascript/ql/lib/ext/make-dir.model.yml diff --git a/javascript/ql/lib/ext/make-dir.model.yml b/javascript/ql/lib/ext/make-dir.model.yml new file mode 100644 index 000000000000..512259126a66 --- /dev/null +++ b/javascript/ql/lib/ext/make-dir.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sinkModel + data: + - ["make-dir", "Member[makeDirectory,makeDirectorySync].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 4fa0dbd3a2a4..02fc6c0ce954 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 @@ -52,6 +52,8 @@ | handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value | | handlebars.js:15:25:15:32 | filePath | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:15:25:15:32 | filePath | This path depends on a $@. | handlebars.js:43:15:43:29 | req.params.path | user-provided value | | hapi.js:15:44:15:51 | filepath | hapi.js:14:30:14:51 | request ... ilepath | hapi.js:15:44:15:51 | filepath | This path depends on a $@. | hapi.js:14:30:14:51 | request ... ilepath | user-provided value | +| make-dir.js:9:19:9:22 | file | make-dir.js:7:18:7:31 | req.query.file | make-dir.js:9:19:9:22 | file | This path depends on a $@. | make-dir.js:7:18:7:31 | req.query.file | user-provided value | +| make-dir.js:10:23:10:26 | file | make-dir.js:7:18:7:31 | req.query.file | make-dir.js:10:23:10:26 | file | This path depends on a $@. | make-dir.js:7:18:7:31 | req.query.file | user-provided value | | mkdirp.js:11:12:11:18 | dirPath | mkdirp.js:9:42:9:59 | req.query.filename | mkdirp.js:11:12:11:18 | dirPath | This path depends on a $@. | mkdirp.js:9:42:9:59 | req.query.filename | user-provided value | | mkdirp.js:12:17:12:23 | dirPath | mkdirp.js:9:42:9:59 | req.query.filename | mkdirp.js:12:17:12:23 | dirPath | This path depends on a $@. | mkdirp.js:9:42:9:59 | req.query.filename | user-provided value | | mkdirp.js:13:23:13:29 | dirPath | mkdirp.js:9:42:9:59 | req.query.filename | mkdirp.js:13:23:13:29 | dirPath | This path depends on a $@. | mkdirp.js:9:42:9:59 | req.query.filename | user-provided value | @@ -403,6 +405,9 @@ edges | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | provenance | | | hapi.js:14:19:14:51 | filepath | hapi.js:15:44:15:51 | filepath | provenance | | | hapi.js:14:30:14:51 | request ... ilepath | hapi.js:14:19:14:51 | filepath | provenance | | +| make-dir.js:7:11:7:31 | file | make-dir.js:9:19:9:22 | file | provenance | | +| make-dir.js:7:11:7:31 | file | make-dir.js:10:23:10:26 | file | provenance | | +| make-dir.js:7:18:7:31 | req.query.file | make-dir.js:7:11:7:31 | file | provenance | | | mkdirp.js:9:11:9:76 | dirPath | mkdirp.js:11:12:11:18 | dirPath | provenance | | | mkdirp.js:9:11:9:76 | dirPath | mkdirp.js:12:17:12:23 | dirPath | provenance | | | mkdirp.js:9:11:9:76 | dirPath | mkdirp.js:13:23:13:29 | dirPath | provenance | | @@ -949,6 +954,10 @@ nodes | hapi.js:14:19:14:51 | filepath | semmle.label | filepath | | hapi.js:14:30:14:51 | request ... ilepath | semmle.label | request ... ilepath | | hapi.js:15:44:15:51 | filepath | semmle.label | filepath | +| make-dir.js:7:11:7:31 | file | semmle.label | file | +| make-dir.js:7:18:7:31 | req.query.file | semmle.label | req.query.file | +| make-dir.js:9:19:9:22 | file | semmle.label | file | +| make-dir.js:10:23:10:26 | file | semmle.label | file | | mkdirp.js:9:11:9:76 | dirPath | semmle.label | dirPath | | mkdirp.js:9:21:9:76 | path.jo ... ltDir') | semmle.label | path.jo ... ltDir') | | mkdirp.js:9:42:9:59 | req.query.filename | semmle.label | req.query.filename | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js index a91287bb0b0e..59b0cfe8d8c5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js @@ -4,8 +4,8 @@ const express = require('express'); const app = express(); app.get('/makedir', (req, res) => { - const file = req.query.file; // $ MISSING: Source + const file = req.query.file; // $ Source - makeDirectory(file); // $ MISSING: Alert - makeDirectorySync(file); // $ MISSING: Alert + makeDirectory(file); // $ Alert + makeDirectorySync(file); // $ Alert }); From 5ec71ab9af33fe00bc2e9eb673c67e0bac80da02 Mon Sep 17 00:00:00 2001 From: Napalys Date: Wed, 9 Apr 2025 14:40:36 +0200 Subject: [PATCH 3/4] Added change note --- javascript/ql/lib/change-notes/2025-04-09-make-dir.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2025-04-09-make-dir.md diff --git a/javascript/ql/lib/change-notes/2025-04-09-make-dir.md b/javascript/ql/lib/change-notes/2025-04-09-make-dir.md new file mode 100644 index 000000000000..fd056bbc98d3 --- /dev/null +++ b/javascript/ql/lib/change-notes/2025-04-09-make-dir.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added support for the `make-dir` package. From 171a84609e4ad54ae6cb6dc66fc680ee33883a59 Mon Sep 17 00:00:00 2001 From: Napalys Date: Thu, 10 Apr 2025 14:13:48 +0200 Subject: [PATCH 4/4] Applied copilot suggestion. --- .../Security/CWE-022/TaintedPath/TaintedPath.expected | 6 +++--- .../query-tests/Security/CWE-022/TaintedPath/make-dir.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) 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 02fc6c0ce954..08bf15800dad 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 @@ -52,7 +52,7 @@ | handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value | | handlebars.js:15:25:15:32 | filePath | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:15:25:15:32 | filePath | This path depends on a $@. | handlebars.js:43:15:43:29 | req.params.path | user-provided value | | hapi.js:15:44:15:51 | filepath | hapi.js:14:30:14:51 | request ... ilepath | hapi.js:15:44:15:51 | filepath | This path depends on a $@. | hapi.js:14:30:14:51 | request ... ilepath | user-provided value | -| make-dir.js:9:19:9:22 | file | make-dir.js:7:18:7:31 | req.query.file | make-dir.js:9:19:9:22 | file | This path depends on a $@. | make-dir.js:7:18:7:31 | req.query.file | user-provided value | +| make-dir.js:9:25:9:28 | file | make-dir.js:7:18:7:31 | req.query.file | make-dir.js:9:25:9:28 | file | This path depends on a $@. | make-dir.js:7:18:7:31 | req.query.file | user-provided value | | make-dir.js:10:23:10:26 | file | make-dir.js:7:18:7:31 | req.query.file | make-dir.js:10:23:10:26 | file | This path depends on a $@. | make-dir.js:7:18:7:31 | req.query.file | user-provided value | | mkdirp.js:11:12:11:18 | dirPath | mkdirp.js:9:42:9:59 | req.query.filename | mkdirp.js:11:12:11:18 | dirPath | This path depends on a $@. | mkdirp.js:9:42:9:59 | req.query.filename | user-provided value | | mkdirp.js:12:17:12:23 | dirPath | mkdirp.js:9:42:9:59 | req.query.filename | mkdirp.js:12:17:12:23 | dirPath | This path depends on a $@. | mkdirp.js:9:42:9:59 | req.query.filename | user-provided value | @@ -405,7 +405,7 @@ edges | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | provenance | | | hapi.js:14:19:14:51 | filepath | hapi.js:15:44:15:51 | filepath | provenance | | | hapi.js:14:30:14:51 | request ... ilepath | hapi.js:14:19:14:51 | filepath | provenance | | -| make-dir.js:7:11:7:31 | file | make-dir.js:9:19:9:22 | file | provenance | | +| make-dir.js:7:11:7:31 | file | make-dir.js:9:25:9:28 | file | provenance | | | make-dir.js:7:11:7:31 | file | make-dir.js:10:23:10:26 | file | provenance | | | make-dir.js:7:18:7:31 | req.query.file | make-dir.js:7:11:7:31 | file | provenance | | | mkdirp.js:9:11:9:76 | dirPath | mkdirp.js:11:12:11:18 | dirPath | provenance | | @@ -956,7 +956,7 @@ nodes | hapi.js:15:44:15:51 | filepath | semmle.label | filepath | | make-dir.js:7:11:7:31 | file | semmle.label | file | | make-dir.js:7:18:7:31 | req.query.file | semmle.label | req.query.file | -| make-dir.js:9:19:9:22 | file | semmle.label | file | +| make-dir.js:9:25:9:28 | file | semmle.label | file | | make-dir.js:10:23:10:26 | file | semmle.label | file | | mkdirp.js:9:11:9:76 | dirPath | semmle.label | dirPath | | mkdirp.js:9:21:9:76 | path.jo ... ltDir') | semmle.label | path.jo ... ltDir') | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js index 59b0cfe8d8c5..2306e00bcae7 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/make-dir.js @@ -3,9 +3,9 @@ import { makeDirectory, makeDirectorySync } from 'make-dir'; const express = require('express'); const app = express(); -app.get('/makedir', (req, res) => { +app.get('/makedir', async (req, res) => { const file = req.query.file; // $ Source - makeDirectory(file); // $ Alert + await makeDirectory(file); // $ Alert makeDirectorySync(file); // $ Alert });