diff --git a/change-notes/1.26/analysis-javascript.md b/change-notes/1.26/analysis-javascript.md index 61036ad102d..392e4bebeb7 100644 --- a/change-notes/1.26/analysis-javascript.md +++ b/change-notes/1.26/analysis-javascript.md @@ -35,6 +35,7 @@ | Unused loop iteration variable (`js/unused-loop-variable`) | Fewer results | This query no longer flags variables in a destructuring array assignment that are not the last variable in the destructed array. | | Unsafe shell command constructed from library input (`js/shell-command-constructed-from-input`) | More results | This query now recognizes more commands where colon, dash, and underscore are used. | | Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | More results | This query now detects more unsafe uses of nested option properties. | +| Client-side URL redirect (`js/client-side-unvalidated-url-redirection`) | More results | This query now recognizes some unsafe uses of `importScripts()` inside WebWorkers. | ## Changes to libraries diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll index 358de5e8900..64c76a84b82 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll @@ -132,6 +132,15 @@ module ClientSideUrlRedirect { } } + /** + * An argument to `importScripts(..)` - which is used inside `WebWorker`s to import new scripts - viewed as a `ScriptUrlSink`. + */ + class ImportScriptsSink extends ScriptUrlSink { + ImportScriptsSink() { + this = DataFlow::globalVarRef("importScripts").getACall().getAnArgument() + } + } + /** * A script or iframe `src` attribute, viewed as a `ScriptUrlSink`. */ diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/DOM.qll b/javascript/ql/src/semmle/javascript/security/dataflow/DOM.qll index f9882537b4e..57d5612f35e 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/DOM.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/DOM.qll @@ -199,6 +199,11 @@ class PostMessageEventHandler extends Function { addEventListener.getArgument(0).mayHaveStringValue("message") and addEventListener.getArgument(1).getABoundFunctionValue(paramIndex).getFunction() = this ) + or + exists(DataFlow::Node rhs | + rhs = DataFlow::globalObjectRef().getAPropertyWrite("onmessage").getRhs() and + rhs.getABoundFunctionValue(paramIndex).getFunction() = this + ) } /** diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index 506dcf1ee0a..b7dca317a88 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -113,6 +113,14 @@ nodes | tst13.js:40:15:40:21 | payload | | tst13.js:44:14:44:20 | payload | | tst13.js:44:14:44:20 | payload | +| tst13.js:49:32:49:32 | e | +| tst13.js:49:32:49:32 | e | +| tst13.js:50:23:50:23 | e | +| tst13.js:50:23:50:23 | e | +| tst13.js:52:34:52:34 | e | +| tst13.js:52:34:52:34 | e | +| tst13.js:53:28:53:28 | e | +| tst13.js:53:28:53:28 | e | | tst.js:2:19:2:69 | /.*redi ... n.href) | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | @@ -234,6 +242,14 @@ edges | tst13.js:2:19:2:35 | document.location | tst13.js:2:19:2:42 | documen ... .search | | tst13.js:2:19:2:42 | documen ... .search | tst13.js:2:19:2:52 | documen ... bstr(1) | | tst13.js:2:19:2:52 | documen ... bstr(1) | tst13.js:2:9:2:52 | payload | +| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | +| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | +| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | +| tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | +| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | +| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | +| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | +| tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | | tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | | tst.js:2:47:2:63 | document.location | tst.js:2:47:2:68 | documen ... on.href | @@ -276,5 +292,7 @@ edges | tst13.js:36:21:36:27 | payload | tst13.js:2:19:2:35 | document.location | tst13.js:36:21:36:27 | payload | Untrusted URL redirection due to $@. | tst13.js:2:19:2:35 | document.location | user-provided value | | tst13.js:40:15:40:21 | payload | tst13.js:2:19:2:35 | document.location | tst13.js:40:15:40:21 | payload | Untrusted URL redirection due to $@. | tst13.js:2:19:2:35 | document.location | user-provided value | | tst13.js:44:14:44:20 | payload | tst13.js:2:19:2:35 | document.location | tst13.js:44:14:44:20 | payload | Untrusted URL redirection due to $@. | tst13.js:2:19:2:35 | document.location | user-provided value | +| tst13.js:50:23:50:23 | e | tst13.js:49:32:49:32 | e | tst13.js:50:23:50:23 | e | Untrusted URL redirection due to $@. | tst13.js:49:32:49:32 | e | user-provided value | +| tst13.js:53:28:53:28 | e | tst13.js:52:34:52:34 | e | tst13.js:53:28:53:28 | e | Untrusted URL redirection due to $@. | tst13.js:52:34:52:34 | e | user-provided value | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | tst.js:2:47:2:63 | document.location | tst.js:2:19:2:72 | /.*redi ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:2:47:2:63 | document.location | user-provided value | | tst.js:6:20:6:59 | indirec ... ref)[1] | tst.js:6:34:6:50 | document.location | tst.js:6:20:6:59 | indirec ... ref)[1] | Untrusted URL redirection due to $@. | tst.js:6:34:6:50 | document.location | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js index 72c9c0b6e72..7a71cf06c08 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst13.js @@ -44,3 +44,12 @@ function foo() { el.src = payload; document.body.appendChild(el); // NOT OK } + +(function () { + self.onmessage = function (e) { + importScripts(e); // NOT OK + } + window.onmessage = function (e) { + self.importScripts(e); // NOT OK + } +})();