From e79f4602b51a28ef2b2186fa7a6d771c5bfe450b Mon Sep 17 00:00:00 2001 From: Napalys Date: Fri, 21 Mar 2025 18:01:23 +0100 Subject: [PATCH 01/13] Added test for `axios` methods. In particular for `postForm` `putForm` `patchForm` `getUri`. --- .../test/library-tests/frameworks/ClientRequests/tst.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js index c9fc40dc5068..580627682cfa 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js @@ -339,3 +339,12 @@ function gotTests(url){ const jsonClient2 = got.extend({url: url}).extend({url: url}); jsonClient2.get(); } + +function moreAxiosTests(url, data, config){ + axios.postForm(url, data, config); // not flagged + axios.putForm(url, data); // not flagged + axios.putForm(url, data, config); // not flagged + axios.patchForm(url, data); // not flagged + axios.patchForm(url, data, config); // not flagged + axios.getUri({ url: url }); // not flagged +} From 69fe251eac1e627570c6ad684541ee274db91e6f Mon Sep 17 00:00:00 2001 From: Napalys Date: Fri, 21 Mar 2025 18:05:28 +0100 Subject: [PATCH 02/13] Add support for `axios.postForm` in `ClientRequest`. --- .../ql/lib/semmle/javascript/frameworks/ClientRequests.qll | 4 +++- .../frameworks/ClientRequests/ClientRequests.expected | 4 ++++ .../ql/test/library-tests/frameworks/ClientRequests/tst.js | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index c2b01cf73178..e137b66c1408 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -222,7 +222,7 @@ module ClientRequest { method = "request" or this = axios().getMember(method).getACall() and - method = [httpMethodName(), "request"] + method = [httpMethodName(), "request", "postForm"] } private int getOptionsArgIndex() { @@ -254,6 +254,8 @@ module ClientRequest { method = ["post", "put"] and result = [this.getArgument(1), this.getOptionArgument(2, "data")] or + method = ["postForm"] and result = this.getArgument(1) + or result = this.getOptionArgument([0 .. 2], ["headers", "params"]) } diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected index bb3a73004536..c5610e532f57 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected @@ -103,6 +103,7 @@ test_ClientRequest | tst.js:334:5:334:25 | got.pag ... rl, {}) | | tst.js:337:5:337:20 | jsonClient.get() | | tst.js:340:5:340:21 | jsonClient2.get() | +| tst.js:344:5:344:37 | axios.p ... config) | test_getADataNode | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:15:18:15:55 | { 'Cont ... json' } | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:16:15:16:35 | {x: 'te ... 'test'} | @@ -146,6 +147,7 @@ test_getADataNode | tst.js:257:1:262:2 | form.su ... rs()\\n}) | tst.js:255:25:255:35 | 'new_value' | | tst.js:286:20:286:55 | new Web ... :8080') | tst.js:288:21:288:35 | 'Hello Server!' | | tst.js:321:5:321:32 | superag ... st(url) | tst.js:321:39:321:42 | data | +| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:25:344:28 | data | test_getHost | tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host | | tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host | @@ -268,6 +270,7 @@ test_getUrl | tst.js:337:5:337:20 | jsonClient.get() | tst.js:336:41:336:43 | url | | tst.js:340:5:340:21 | jsonClient2.get() | tst.js:339:42:339:44 | url | | tst.js:340:5:340:21 | jsonClient2.get() | tst.js:339:61:339:63 | url | +| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:20:344:22 | url | test_getAResponseDataNode | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | json | true | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | json | true | @@ -354,3 +357,4 @@ test_getAResponseDataNode | tst.js:334:5:334:25 | got.pag ... rl, {}) | tst.js:334:5:334:25 | got.pag ... rl, {}) | text | true | | tst.js:337:5:337:20 | jsonClient.get() | tst.js:337:5:337:20 | jsonClient.get() | text | true | | tst.js:340:5:340:21 | jsonClient2.get() | tst.js:340:5:340:21 | jsonClient2.get() | text | true | +| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:5:344:37 | axios.p ... config) | json | true | diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js index 580627682cfa..0c34a0ffc51c 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js @@ -341,7 +341,7 @@ function gotTests(url){ } function moreAxiosTests(url, data, config){ - axios.postForm(url, data, config); // not flagged + axios.postForm(url, data, config); axios.putForm(url, data); // not flagged axios.putForm(url, data, config); // not flagged axios.patchForm(url, data); // not flagged From 7fe943d8b21dab23d8f1a7a73d70edcd3072faa6 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 08:10:30 +0100 Subject: [PATCH 03/13] Added support for `putForm`. --- .../lib/semmle/javascript/frameworks/ClientRequests.qll | 4 ++-- .../frameworks/ClientRequests/ClientRequests.expected | 8 ++++++++ .../test/library-tests/frameworks/ClientRequests/tst.js | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index e137b66c1408..9e98e52d741b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -222,7 +222,7 @@ module ClientRequest { method = "request" or this = axios().getMember(method).getACall() and - method = [httpMethodName(), "request", "postForm"] + method = [httpMethodName(), "request", "postForm", "putForm"] } private int getOptionsArgIndex() { @@ -254,7 +254,7 @@ module ClientRequest { method = ["post", "put"] and result = [this.getArgument(1), this.getOptionArgument(2, "data")] or - method = ["postForm"] and result = this.getArgument(1) + method = ["postForm", "putForm"] and result = this.getArgument(1) or result = this.getOptionArgument([0 .. 2], ["headers", "params"]) } diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected index c5610e532f57..5e4afe2d4e6e 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected @@ -104,6 +104,8 @@ test_ClientRequest | tst.js:337:5:337:20 | jsonClient.get() | | tst.js:340:5:340:21 | jsonClient2.get() | | tst.js:344:5:344:37 | axios.p ... config) | +| tst.js:345:5:345:28 | axios.p ... , data) | +| tst.js:346:5:346:36 | axios.p ... config) | test_getADataNode | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:15:18:15:55 | { 'Cont ... json' } | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:16:15:16:35 | {x: 'te ... 'test'} | @@ -148,6 +150,8 @@ test_getADataNode | tst.js:286:20:286:55 | new Web ... :8080') | tst.js:288:21:288:35 | 'Hello Server!' | | tst.js:321:5:321:32 | superag ... st(url) | tst.js:321:39:321:42 | data | | tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:25:344:28 | data | +| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:24:345:27 | data | +| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:24:346:27 | data | test_getHost | tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host | | tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host | @@ -271,6 +275,8 @@ test_getUrl | tst.js:340:5:340:21 | jsonClient2.get() | tst.js:339:42:339:44 | url | | tst.js:340:5:340:21 | jsonClient2.get() | tst.js:339:61:339:63 | url | | tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:20:344:22 | url | +| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:19:345:21 | url | +| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:19:346:21 | url | test_getAResponseDataNode | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | json | true | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | json | true | @@ -358,3 +364,5 @@ test_getAResponseDataNode | tst.js:337:5:337:20 | jsonClient.get() | tst.js:337:5:337:20 | jsonClient.get() | text | true | | tst.js:340:5:340:21 | jsonClient2.get() | tst.js:340:5:340:21 | jsonClient2.get() | text | true | | tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:5:344:37 | axios.p ... config) | json | true | +| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:5:345:28 | axios.p ... , data) | json | true | +| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:5:346:36 | axios.p ... config) | json | true | diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js index 0c34a0ffc51c..0ed72f6dd704 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js @@ -342,8 +342,8 @@ function gotTests(url){ function moreAxiosTests(url, data, config){ axios.postForm(url, data, config); - axios.putForm(url, data); // not flagged - axios.putForm(url, data, config); // not flagged + axios.putForm(url, data); + axios.putForm(url, data, config); axios.patchForm(url, data); // not flagged axios.patchForm(url, data, config); // not flagged axios.getUri({ url: url }); // not flagged From f48a362d71919ef235618d33e10f2f163e93142b Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 08:12:35 +0100 Subject: [PATCH 04/13] Added support for `patchForm`. --- .../lib/semmle/javascript/frameworks/ClientRequests.qll | 4 ++-- .../frameworks/ClientRequests/ClientRequests.expected | 8 ++++++++ .../test/library-tests/frameworks/ClientRequests/tst.js | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index 9e98e52d741b..91238dd23bbf 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -222,7 +222,7 @@ module ClientRequest { method = "request" or this = axios().getMember(method).getACall() and - method = [httpMethodName(), "request", "postForm", "putForm"] + method = [httpMethodName(), "request", "postForm", "putForm", "patchForm"] } private int getOptionsArgIndex() { @@ -254,7 +254,7 @@ module ClientRequest { method = ["post", "put"] and result = [this.getArgument(1), this.getOptionArgument(2, "data")] or - method = ["postForm", "putForm"] and result = this.getArgument(1) + method = ["postForm", "putForm", "patchForm"] and result = this.getArgument(1) or result = this.getOptionArgument([0 .. 2], ["headers", "params"]) } diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected index 5e4afe2d4e6e..28f77239c2f0 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected @@ -106,6 +106,8 @@ test_ClientRequest | tst.js:344:5:344:37 | axios.p ... config) | | tst.js:345:5:345:28 | axios.p ... , data) | | tst.js:346:5:346:36 | axios.p ... config) | +| tst.js:347:5:347:30 | axios.p ... , data) | +| tst.js:348:5:348:38 | axios.p ... config) | test_getADataNode | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:15:18:15:55 | { 'Cont ... json' } | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:16:15:16:35 | {x: 'te ... 'test'} | @@ -152,6 +154,8 @@ test_getADataNode | tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:25:344:28 | data | | tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:24:345:27 | data | | tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:24:346:27 | data | +| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:26:347:29 | data | +| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:26:348:29 | data | test_getHost | tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host | | tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host | @@ -277,6 +281,8 @@ test_getUrl | tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:20:344:22 | url | | tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:19:345:21 | url | | tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:19:346:21 | url | +| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:21:347:23 | url | +| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:21:348:23 | url | test_getAResponseDataNode | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | json | true | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | json | true | @@ -366,3 +372,5 @@ test_getAResponseDataNode | tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:5:344:37 | axios.p ... config) | json | true | | tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:5:345:28 | axios.p ... , data) | json | true | | tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:5:346:36 | axios.p ... config) | json | true | +| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:5:347:30 | axios.p ... , data) | json | true | +| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:5:348:38 | axios.p ... config) | json | true | diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js index 0ed72f6dd704..f421de685b57 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js @@ -344,7 +344,7 @@ function moreAxiosTests(url, data, config){ axios.postForm(url, data, config); axios.putForm(url, data); axios.putForm(url, data, config); - axios.patchForm(url, data); // not flagged - axios.patchForm(url, data, config); // not flagged + axios.patchForm(url, data); + axios.patchForm(url, data, config); axios.getUri({ url: url }); // not flagged } From c0d848cdf1ca18a67f8c0a536f4b0edb911262a1 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 08:20:38 +0100 Subject: [PATCH 05/13] Added support for `getUri`. --- .../ql/lib/semmle/javascript/frameworks/ClientRequests.qll | 2 +- .../frameworks/ClientRequests/ClientRequests.expected | 3 +++ .../ql/test/library-tests/frameworks/ClientRequests/tst.js | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index 91238dd23bbf..f4c1f69ace3b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -222,7 +222,7 @@ module ClientRequest { method = "request" or this = axios().getMember(method).getACall() and - method = [httpMethodName(), "request", "postForm", "putForm", "patchForm"] + method = [httpMethodName(), "request", "postForm", "putForm", "patchForm", "getUri"] } private int getOptionsArgIndex() { diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected index 28f77239c2f0..d91c7e61009c 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected @@ -108,6 +108,7 @@ test_ClientRequest | tst.js:346:5:346:36 | axios.p ... config) | | tst.js:347:5:347:30 | axios.p ... , data) | | tst.js:348:5:348:38 | axios.p ... config) | +| tst.js:349:5:349:30 | axios.g ... url }) | test_getADataNode | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:15:18:15:55 | { 'Cont ... json' } | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:16:15:16:35 | {x: 'te ... 'test'} | @@ -283,6 +284,7 @@ test_getUrl | tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:19:346:21 | url | | tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:21:347:23 | url | | tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:21:348:23 | url | +| tst.js:349:5:349:30 | axios.g ... url }) | tst.js:349:18:349:29 | { url: url } | test_getAResponseDataNode | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | json | true | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | json | true | @@ -374,3 +376,4 @@ test_getAResponseDataNode | tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:5:346:36 | axios.p ... config) | json | true | | tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:5:347:30 | axios.p ... , data) | json | true | | tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:5:348:38 | axios.p ... config) | json | true | +| tst.js:349:5:349:30 | axios.g ... url }) | tst.js:349:5:349:30 | axios.g ... url }) | json | true | diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js index f421de685b57..43c46c9ec30c 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js @@ -346,5 +346,5 @@ function moreAxiosTests(url, data, config){ axios.putForm(url, data, config); axios.patchForm(url, data); axios.patchForm(url, data, config); - axios.getUri({ url: url }); // not flagged + axios.getUri({ url: url }); } From 8f2adb6543c8449f3da5faa37c6d2cdc50e237a4 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 08:53:37 +0100 Subject: [PATCH 06/13] Added test case for `create`. --- .../ql/test/library-tests/frameworks/ClientRequests/tst.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js index 43c46c9ec30c..32950b6be28c 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js @@ -347,4 +347,7 @@ function moreAxiosTests(url, data, config){ axios.patchForm(url, data); axios.patchForm(url, data, config); axios.getUri({ url: url }); + + const axiosInstance = axios.create({}); + axiosInstance({method: "get", url: url, responseType: "text"}); // Not flagged } From a3c84d9feb7f8ee0f59a8fac01d7ef66ea0f910a Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 08:54:19 +0100 Subject: [PATCH 07/13] Added support for `axios.create`. --- .../ql/lib/semmle/javascript/frameworks/ClientRequests.qll | 3 +++ .../frameworks/ClientRequests/ClientRequests.expected | 4 ++++ .../ql/test/library-tests/frameworks/ClientRequests/tst.js | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index f4c1f69ace3b..673bdf2de33f 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -223,6 +223,9 @@ module ClientRequest { or this = axios().getMember(method).getACall() and method = [httpMethodName(), "request", "postForm", "putForm", "patchForm", "getUri"] + or + this = axios().getMember("create").getReturn().getACall() and + method = "request" } private int getOptionsArgIndex() { diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected index d91c7e61009c..f787a7e60603 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequests.expected @@ -109,6 +109,7 @@ test_ClientRequest | tst.js:347:5:347:30 | axios.p ... , data) | | tst.js:348:5:348:38 | axios.p ... config) | | tst.js:349:5:349:30 | axios.g ... url }) | +| tst.js:352:5:352:66 | axiosIn ... text"}) | test_getADataNode | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:15:18:15:55 | { 'Cont ... json' } | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:16:15:16:35 | {x: 'te ... 'test'} | @@ -285,6 +286,8 @@ test_getUrl | tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:21:347:23 | url | | tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:21:348:23 | url | | tst.js:349:5:349:30 | axios.g ... url }) | tst.js:349:18:349:29 | { url: url } | +| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:19:352:65 | {method ... "text"} | +| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:40:352:42 | url | test_getAResponseDataNode | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | json | true | | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | json | true | @@ -377,3 +380,4 @@ test_getAResponseDataNode | tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:5:347:30 | axios.p ... , data) | json | true | | tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:5:348:38 | axios.p ... config) | json | true | | tst.js:349:5:349:30 | axios.g ... url }) | tst.js:349:5:349:30 | axios.g ... url }) | json | true | +| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:5:352:66 | axiosIn ... text"}) | text | true | diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js index 32950b6be28c..3cd086fae0e7 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js @@ -349,5 +349,5 @@ function moreAxiosTests(url, data, config){ axios.getUri({ url: url }); const axiosInstance = axios.create({}); - axiosInstance({method: "get", url: url, responseType: "text"}); // Not flagged + axiosInstance({method: "get", url: url, responseType: "text"}); } From ea181e41739873c9971558adf6a39d629c17a1eb Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 11:32:35 +0100 Subject: [PATCH 08/13] Added test case for `axios.interceptors.request` --- .../CWE-918/axiosInterceptors.serverSide.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-918/axiosInterceptors.serverSide.js diff --git a/javascript/ql/test/query-tests/Security/CWE-918/axiosInterceptors.serverSide.js b/javascript/ql/test/query-tests/Security/CWE-918/axiosInterceptors.serverSide.js new file mode 100644 index 000000000000..a5697acdf2ef --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-918/axiosInterceptors.serverSide.js @@ -0,0 +1,22 @@ +const express = require("express"); +const axios = require("axios"); + +const app = express(); + +let userProvidedUrl = ""; + +axios.interceptors.request.use( + function (config) { + if (userProvidedUrl) { + config.url = userProvidedUrl; // $ MISSING: Alert[js/request-forgery] + } + return config; + }, + error => error +); + +app.post("/fetch", (req, res) => { + const { url } = req.body; // $ MISSING: Source[js/request-forgery] + userProvidedUrl = url; + axios.get("placeholder"); +}); From 10498bbaa47a65015696ceb426cab865b5926eb0 Mon Sep 17 00:00:00 2001 From: Napalys Date: Tue, 25 Mar 2025 10:54:56 +0100 Subject: [PATCH 09/13] Added support for `axios.interceptors.request`. --- javascript/ql/lib/ext/axios.model.yml | 6 ++++++ .../Security/CWE-918/RequestForgery.expected | 12 ++++++++++++ .../Security/CWE-918/axiosInterceptors.serverSide.js | 4 ++-- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 javascript/ql/lib/ext/axios.model.yml diff --git a/javascript/ql/lib/ext/axios.model.yml b/javascript/ql/lib/ext/axios.model.yml new file mode 100644 index 000000000000..7fdab986858d --- /dev/null +++ b/javascript/ql/lib/ext/axios.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sinkModel + data: + - ["axios", "Member[interceptors].Member[request].Member[use].Argument[0].Parameter[0].Member[url]", "request-forgery"] diff --git a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index a8ed8b29b4be..6b33506d502f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -1,5 +1,6 @@ #select | apollo.serverSide.ts:8:39:8:64 | get(fil ... => {}) | apollo.serverSide.ts:7:36:7:44 | { files } | apollo.serverSide.ts:8:43:8:50 | file.url | The $@ of this request depends on a $@. | apollo.serverSide.ts:8:43:8:50 | file.url | URL | apollo.serverSide.ts:7:36:7:44 | { files } | user-provided value | +| axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | axiosInterceptors.serverSide.js:19:21:19:28 | req.body | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | The $@ of this request depends on a $@. | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | endpoint | axiosInterceptors.serverSide.js:19:21:19:28 | req.body | user-provided value | | serverSide.js:18:5:18:20 | request(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:18:13:18:19 | tainted | The $@ of this request depends on a $@. | serverSide.js:18:13:18:19 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value | | serverSide.js:20:5:20:24 | request.get(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:20:17:20:23 | tainted | The $@ of this request depends on a $@. | serverSide.js:20:17:20:23 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value | | serverSide.js:24:5:24:20 | request(options) | serverSide.js:14:29:14:35 | req.url | serverSide.js:23:19:23:25 | tainted | The $@ of this request depends on a $@. | serverSide.js:23:19:23:25 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value | @@ -30,6 +31,11 @@ edges | apollo.serverSide.ts:8:13:8:17 | files | apollo.serverSide.ts:8:28:8:31 | file | provenance | | | apollo.serverSide.ts:8:28:8:31 | file | apollo.serverSide.ts:8:43:8:46 | file | provenance | | | apollo.serverSide.ts:8:43:8:46 | file | apollo.serverSide.ts:8:43:8:50 | file.url | provenance | | +| axiosInterceptors.serverSide.js:19:11:19:17 | { url } | axiosInterceptors.serverSide.js:19:11:19:28 | url | provenance | | +| axiosInterceptors.serverSide.js:19:11:19:28 | url | axiosInterceptors.serverSide.js:20:23:20:25 | url | provenance | | +| axiosInterceptors.serverSide.js:19:21:19:28 | req.body | axiosInterceptors.serverSide.js:19:11:19:17 | { url } | provenance | | +| axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | provenance | | +| axiosInterceptors.serverSide.js:20:23:20:25 | url | axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | provenance | | | serverSide.js:14:9:14:52 | tainted | serverSide.js:18:13:18:19 | tainted | provenance | | | serverSide.js:14:9:14:52 | tainted | serverSide.js:20:17:20:23 | tainted | provenance | | | serverSide.js:14:9:14:52 | tainted | serverSide.js:23:19:23:25 | tainted | provenance | | @@ -85,6 +91,12 @@ nodes | apollo.serverSide.ts:8:28:8:31 | file | semmle.label | file | | apollo.serverSide.ts:8:43:8:46 | file | semmle.label | file | | apollo.serverSide.ts:8:43:8:50 | file.url | semmle.label | file.url | +| axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | semmle.label | userProvidedUrl | +| axiosInterceptors.serverSide.js:19:11:19:17 | { url } | semmle.label | { url } | +| axiosInterceptors.serverSide.js:19:11:19:28 | url | semmle.label | url | +| axiosInterceptors.serverSide.js:19:21:19:28 | req.body | semmle.label | req.body | +| axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | semmle.label | userProvidedUrl | +| axiosInterceptors.serverSide.js:20:23:20:25 | url | semmle.label | url | | serverSide.js:14:9:14:52 | tainted | semmle.label | tainted | | serverSide.js:14:19:14:42 | url.par ... , true) | semmle.label | url.par ... , true) | | serverSide.js:14:29:14:35 | req.url | semmle.label | req.url | diff --git a/javascript/ql/test/query-tests/Security/CWE-918/axiosInterceptors.serverSide.js b/javascript/ql/test/query-tests/Security/CWE-918/axiosInterceptors.serverSide.js index a5697acdf2ef..12e95a326cbc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/axiosInterceptors.serverSide.js +++ b/javascript/ql/test/query-tests/Security/CWE-918/axiosInterceptors.serverSide.js @@ -8,7 +8,7 @@ let userProvidedUrl = ""; axios.interceptors.request.use( function (config) { if (userProvidedUrl) { - config.url = userProvidedUrl; // $ MISSING: Alert[js/request-forgery] + config.url = userProvidedUrl; // $ Alert[js/request-forgery] } return config; }, @@ -16,7 +16,7 @@ axios.interceptors.request.use( ); app.post("/fetch", (req, res) => { - const { url } = req.body; // $ MISSING: Source[js/request-forgery] + const { url } = req.body; // $ Source[js/request-forgery] userProvidedUrl = url; axios.get("placeholder"); }); From 20bb831ce9c36de2f8d5a9bab20d02453f774171 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 11:40:55 +0100 Subject: [PATCH 10/13] Added test case for `axios.interceptors.response` with missing alert. --- .../CWE-079/DomBasedXss/interceptors.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js new file mode 100644 index 000000000000..8d6da238ee79 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js @@ -0,0 +1,20 @@ +const express = require("express"); +const axios = require("axios"); + +const app = express(); + +axios.interceptors.response.use( + (response) => { // $ MISSING: Source + const userGeneratedHtml = response.data; + document.getElementById("content").innerHTML = userGeneratedHtml; // $ MISSING: Alert + return response; + }, + (error) => { + return Promise.reject(error); + } +); + +app.post("/fetch", (req, res) => { + const { url } = req.body; + axios.get(url); +}); From 1ee3fde2142ccec1f8eb4366cf124c4a40a012e2 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 11:43:41 +0100 Subject: [PATCH 11/13] Added support for `axios.interceptors.response`. --- javascript/ql/lib/ext/axios.model.yml | 6 ++++++ .../query-tests/Security/CWE-079/DomBasedXss/Xss.expected | 8 ++++++++ .../CWE-079/DomBasedXss/XssWithAdditionalSources.expected | 7 +++++++ .../Security/CWE-079/DomBasedXss/interceptors.js | 4 ++-- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/ext/axios.model.yml b/javascript/ql/lib/ext/axios.model.yml index 7fdab986858d..78a525244783 100644 --- a/javascript/ql/lib/ext/axios.model.yml +++ b/javascript/ql/lib/ext/axios.model.yml @@ -4,3 +4,9 @@ extensions: extensible: sinkModel data: - ["axios", "Member[interceptors].Member[request].Member[use].Argument[0].Parameter[0].Member[url]", "request-forgery"] + + - addsTo: + pack: codeql/javascript-all + extensible: sourceModel + data: + - ["axios", "Member[interceptors].Member[response].Member[use].Argument[0].Parameter[0]", "remote"] diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 7de1561f79e8..d05ef2073fbb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -61,6 +61,7 @@ | dragAndDrop.ts:73:29:73:39 | droppedHtml | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:73:29:73:39 | droppedHtml | Cross-site scripting vulnerability due to $@. | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | user-provided value | | event-handler-receiver.js:2:31:2:83 | '

' | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | Cross-site scripting vulnerability due to $@. | event-handler-receiver.js:2:49:2:61 | location.href | user-provided value | | express.js:6:15:6:33 | req.param("wobble") | express.js:6:15:6:33 | req.param("wobble") | express.js:6:15:6:33 | req.param("wobble") | Cross-site scripting vulnerability due to $@. | express.js:6:15:6:33 | req.param("wobble") | user-provided value | +| interceptors.js:9:56:9:72 | userGeneratedHtml | interceptors.js:7:6:7:13 | response | interceptors.js:9:56:9:72 | userGeneratedHtml | Cross-site scripting vulnerability due to $@. | interceptors.js:7:6:7:13 | response | user-provided value | | jquery.js:7:5:7:34 | "
" | jquery.js:2:17:2:40 | documen ... .search | jquery.js:7:5:7:34 | "
" | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:40 | documen ... .search | user-provided value | | jquery.js:8:18:8:34 | "XSS: " + tainted | jquery.js:2:17:2:40 | documen ... .search | jquery.js:8:18:8:34 | "XSS: " + tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:40 | documen ... .search | user-provided value | | jquery.js:10:5:10:40 | "" + ... "" | jquery.js:10:13:10:20 | location | jquery.js:10:5:10:40 | "" + ... "" | Cross-site scripting vulnerability due to $@. | jquery.js:10:13:10:20 | location | user-provided value | @@ -351,6 +352,9 @@ edges | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | Config | +| interceptors.js:7:6:7:13 | response | interceptors.js:8:35:8:42 | response | provenance | | +| interceptors.js:8:15:8:47 | userGeneratedHtml | interceptors.js:9:56:9:72 | userGeneratedHtml | provenance | | +| interceptors.js:8:35:8:42 | response | interceptors.js:8:15:8:47 | userGeneratedHtml | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:5:13:5:19 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:6:11:6:17 | tainted | provenance | | @@ -952,6 +956,10 @@ nodes | event-handler-receiver.js:2:31:2:83 | '

' | semmle.label | '

' | | event-handler-receiver.js:2:49:2:61 | location.href | semmle.label | location.href | | express.js:6:15:6:33 | req.param("wobble") | semmle.label | req.param("wobble") | +| interceptors.js:7:6:7:13 | response | semmle.label | response | +| interceptors.js:8:15:8:47 | userGeneratedHtml | semmle.label | userGeneratedHtml | +| interceptors.js:8:35:8:42 | response | semmle.label | response | +| interceptors.js:9:56:9:72 | userGeneratedHtml | semmle.label | userGeneratedHtml | | jquery.js:2:7:2:40 | tainted | semmle.label | tainted | | jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | | jquery.js:4:5:4:11 | tainted | semmle.label | tainted | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index eb961fc83dbf..a235f18ee838 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -153,6 +153,10 @@ nodes | event-handler-receiver.js:2:31:2:83 | '

' | semmle.label | '

' | | event-handler-receiver.js:2:49:2:61 | location.href | semmle.label | location.href | | express.js:6:15:6:33 | req.param("wobble") | semmle.label | req.param("wobble") | +| interceptors.js:7:6:7:13 | response | semmle.label | response | +| interceptors.js:8:15:8:47 | userGeneratedHtml | semmle.label | userGeneratedHtml | +| interceptors.js:8:35:8:42 | response | semmle.label | response | +| interceptors.js:9:56:9:72 | userGeneratedHtml | semmle.label | userGeneratedHtml | | jquery.js:2:7:2:40 | tainted | semmle.label | tainted | | jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | | jquery.js:4:5:4:11 | tainted | semmle.label | tainted | @@ -791,6 +795,9 @@ edges | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | Config | +| interceptors.js:7:6:7:13 | response | interceptors.js:8:35:8:42 | response | provenance | | +| interceptors.js:8:15:8:47 | userGeneratedHtml | interceptors.js:9:56:9:72 | userGeneratedHtml | provenance | | +| interceptors.js:8:35:8:42 | response | interceptors.js:8:15:8:47 | userGeneratedHtml | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:5:13:5:19 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:6:11:6:17 | tainted | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js index 8d6da238ee79..d4e918c1de8d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js @@ -4,9 +4,9 @@ const axios = require("axios"); const app = express(); axios.interceptors.response.use( - (response) => { // $ MISSING: Source + (response) => { // $ Source const userGeneratedHtml = response.data; - document.getElementById("content").innerHTML = userGeneratedHtml; // $ MISSING: Alert + document.getElementById("content").innerHTML = userGeneratedHtml; // $ Alert return response; }, (error) => { From 9dcfe0e7096aee4a4db81590d829b927d7785518 Mon Sep 17 00:00:00 2001 From: Napalys Date: Mon, 24 Mar 2025 11:49:08 +0100 Subject: [PATCH 12/13] Added change note. --- .../lib/change-notes/2025-03-24-axios-additional-methods.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2025-03-24-axios-additional-methods.md diff --git a/javascript/ql/lib/change-notes/2025-03-24-axios-additional-methods.md b/javascript/ql/lib/change-notes/2025-03-24-axios-additional-methods.md new file mode 100644 index 000000000000..9f31730bc14b --- /dev/null +++ b/javascript/ql/lib/change-notes/2025-03-24-axios-additional-methods.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +Enhanced `axios` support with new methods (`postForm`, `putForm`, `patchForm`, `getUri`, `create`) and added support for `interceptors.request` and `interceptors.response`. From 0689cf7f5e8206098a453b9e4981519358726d5d Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Mon, 24 Mar 2025 14:19:02 +0100 Subject: [PATCH 13/13] Update javascript/ql/lib/ext/axios.model.yml Co-authored-by: Asger F --- javascript/ql/lib/ext/axios.model.yml | 2 +- .../query-tests/Security/CWE-079/DomBasedXss/Xss.expected | 8 -------- .../CWE-079/DomBasedXss/XssWithAdditionalSources.expected | 7 ------- .../CWE-079/DomBasedXssWithResponseThreat/Xss.expected | 8 ++++++++ .../interceptors.js | 0 5 files changed, 9 insertions(+), 16 deletions(-) rename javascript/ql/test/query-tests/Security/CWE-079/{DomBasedXss => DomBasedXssWithResponseThreat}/interceptors.js (100%) diff --git a/javascript/ql/lib/ext/axios.model.yml b/javascript/ql/lib/ext/axios.model.yml index 78a525244783..69740c31e299 100644 --- a/javascript/ql/lib/ext/axios.model.yml +++ b/javascript/ql/lib/ext/axios.model.yml @@ -9,4 +9,4 @@ extensions: pack: codeql/javascript-all extensible: sourceModel data: - - ["axios", "Member[interceptors].Member[response].Member[use].Argument[0].Parameter[0]", "remote"] + - ["axios", "Member[interceptors].Member[response].Member[use].Argument[0].Parameter[0]", "response"] diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index d05ef2073fbb..7de1561f79e8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -61,7 +61,6 @@ | dragAndDrop.ts:73:29:73:39 | droppedHtml | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:73:29:73:39 | droppedHtml | Cross-site scripting vulnerability due to $@. | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | user-provided value | | event-handler-receiver.js:2:31:2:83 | '

' | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | Cross-site scripting vulnerability due to $@. | event-handler-receiver.js:2:49:2:61 | location.href | user-provided value | | express.js:6:15:6:33 | req.param("wobble") | express.js:6:15:6:33 | req.param("wobble") | express.js:6:15:6:33 | req.param("wobble") | Cross-site scripting vulnerability due to $@. | express.js:6:15:6:33 | req.param("wobble") | user-provided value | -| interceptors.js:9:56:9:72 | userGeneratedHtml | interceptors.js:7:6:7:13 | response | interceptors.js:9:56:9:72 | userGeneratedHtml | Cross-site scripting vulnerability due to $@. | interceptors.js:7:6:7:13 | response | user-provided value | | jquery.js:7:5:7:34 | "
" | jquery.js:2:17:2:40 | documen ... .search | jquery.js:7:5:7:34 | "
" | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:40 | documen ... .search | user-provided value | | jquery.js:8:18:8:34 | "XSS: " + tainted | jquery.js:2:17:2:40 | documen ... .search | jquery.js:8:18:8:34 | "XSS: " + tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:40 | documen ... .search | user-provided value | | jquery.js:10:5:10:40 | "" + ... "" | jquery.js:10:13:10:20 | location | jquery.js:10:5:10:40 | "" + ... "" | Cross-site scripting vulnerability due to $@. | jquery.js:10:13:10:20 | location | user-provided value | @@ -352,9 +351,6 @@ edges | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | Config | -| interceptors.js:7:6:7:13 | response | interceptors.js:8:35:8:42 | response | provenance | | -| interceptors.js:8:15:8:47 | userGeneratedHtml | interceptors.js:9:56:9:72 | userGeneratedHtml | provenance | | -| interceptors.js:8:35:8:42 | response | interceptors.js:8:15:8:47 | userGeneratedHtml | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:5:13:5:19 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:6:11:6:17 | tainted | provenance | | @@ -956,10 +952,6 @@ nodes | event-handler-receiver.js:2:31:2:83 | '

' | semmle.label | '

' | | event-handler-receiver.js:2:49:2:61 | location.href | semmle.label | location.href | | express.js:6:15:6:33 | req.param("wobble") | semmle.label | req.param("wobble") | -| interceptors.js:7:6:7:13 | response | semmle.label | response | -| interceptors.js:8:15:8:47 | userGeneratedHtml | semmle.label | userGeneratedHtml | -| interceptors.js:8:35:8:42 | response | semmle.label | response | -| interceptors.js:9:56:9:72 | userGeneratedHtml | semmle.label | userGeneratedHtml | | jquery.js:2:7:2:40 | tainted | semmle.label | tainted | | jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | | jquery.js:4:5:4:11 | tainted | semmle.label | tainted | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index a235f18ee838..eb961fc83dbf 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -153,10 +153,6 @@ nodes | event-handler-receiver.js:2:31:2:83 | '

' | semmle.label | '

' | | event-handler-receiver.js:2:49:2:61 | location.href | semmle.label | location.href | | express.js:6:15:6:33 | req.param("wobble") | semmle.label | req.param("wobble") | -| interceptors.js:7:6:7:13 | response | semmle.label | response | -| interceptors.js:8:15:8:47 | userGeneratedHtml | semmle.label | userGeneratedHtml | -| interceptors.js:8:35:8:42 | response | semmle.label | response | -| interceptors.js:9:56:9:72 | userGeneratedHtml | semmle.label | userGeneratedHtml | | jquery.js:2:7:2:40 | tainted | semmle.label | tainted | | jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search | | jquery.js:4:5:4:11 | tainted | semmle.label | tainted | @@ -795,9 +791,6 @@ edges | dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | | | event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '

' | provenance | Config | -| interceptors.js:7:6:7:13 | response | interceptors.js:8:35:8:42 | response | provenance | | -| interceptors.js:8:15:8:47 | userGeneratedHtml | interceptors.js:9:56:9:72 | userGeneratedHtml | provenance | | -| interceptors.js:8:35:8:42 | response | interceptors.js:8:15:8:47 | userGeneratedHtml | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:5:13:5:19 | tainted | provenance | | | jquery.js:2:7:2:40 | tainted | jquery.js:6:11:6:17 | tainted | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXssWithResponseThreat/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXssWithResponseThreat/Xss.expected index ef0c88098b98..afc30e246085 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXssWithResponseThreat/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXssWithResponseThreat/Xss.expected @@ -1,4 +1,5 @@ #select +| interceptors.js:9:56:9:72 | userGeneratedHtml | interceptors.js:7:6:7:13 | response | interceptors.js:9:56:9:72 | userGeneratedHtml | Cross-site scripting vulnerability due to $@. | interceptors.js:7:6:7:13 | response | user-provided value | | test.jsx:27:29:27:32 | data | test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:27:29:27:32 | data | Cross-site scripting vulnerability due to $@. | test.jsx:5:28:5:63 | fetch(" ... ntent") | user-provided value | | test.ts:21:57:21:76 | response.description | test.ts:8:9:8:79 | this.#h ... query') | test.ts:21:57:21:76 | response.description | Cross-site scripting vulnerability due to $@. | test.ts:8:9:8:79 | this.#h ... query') | user-provided value | | test.ts:24:36:24:90 | `

${ ... o}

` | test.ts:8:9:8:79 | this.#h ... query') | test.ts:24:36:24:90 | `

${ ... o}

` | Cross-site scripting vulnerability due to $@. | test.ts:8:9:8:79 | this.#h ... query') | user-provided value | @@ -18,6 +19,9 @@ | testUseQueries2.vue:40:10:40:23 | v-html=data3 | testUseQueries2.vue:12:28:12:41 | fetch("${id}") | testUseQueries2.vue:40:10:40:23 | v-html=data3 | Cross-site scripting vulnerability due to $@. | testUseQueries2.vue:12:28:12:41 | fetch("${id}") | user-provided value | | testUseQueries.vue:25:10:25:23 | v-html=data2 | testUseQueries.vue:11:36:11:49 | fetch("${id}") | testUseQueries.vue:25:10:25:23 | v-html=data2 | Cross-site scripting vulnerability due to $@. | testUseQueries.vue:11:36:11:49 | fetch("${id}") | user-provided value | edges +| interceptors.js:7:6:7:13 | response | interceptors.js:8:35:8:42 | response | provenance | | +| interceptors.js:8:15:8:47 | userGeneratedHtml | interceptors.js:9:56:9:72 | userGeneratedHtml | provenance | | +| interceptors.js:8:35:8:42 | response | interceptors.js:8:15:8:47 | userGeneratedHtml | provenance | | | test.jsx:5:11:5:63 | response | test.jsx:6:24:6:31 | response | provenance | | | test.jsx:5:22:5:63 | await f ... ntent") | test.jsx:5:11:5:63 | response | provenance | | | test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:5:22:5:63 | await f ... ntent") | provenance | | @@ -96,6 +100,10 @@ edges | testUseQueries.vue:12:20:12:34 | response.json() | testUseQueries.vue:18:22:18:36 | results[0].data | provenance | | | testUseQueries.vue:18:22:18:36 | results[0].data | testUseQueries.vue:25:10:25:23 | v-html=data2 | provenance | | nodes +| interceptors.js:7:6:7:13 | response | semmle.label | response | +| interceptors.js:8:15:8:47 | userGeneratedHtml | semmle.label | userGeneratedHtml | +| interceptors.js:8:35:8:42 | response | semmle.label | response | +| interceptors.js:9:56:9:72 | userGeneratedHtml | semmle.label | userGeneratedHtml | | test.jsx:5:11:5:63 | response | semmle.label | response | | test.jsx:5:22:5:63 | await f ... ntent") | semmle.label | await f ... ntent") | | test.jsx:5:28:5:63 | fetch(" ... ntent") | semmle.label | fetch(" ... ntent") | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXssWithResponseThreat/interceptors.js similarity index 100% rename from javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/interceptors.js rename to javascript/ql/test/query-tests/Security/CWE-079/DomBasedXssWithResponseThreat/interceptors.js