Moderate severityOSV Advisory· Published Feb 25, 2022· Updated Sep 16, 2024
Open Redirect
CVE-2021-23495
Description
The package karma before 6.3.16 are vulnerable to Open Redirect due to missing validation of the return_url query parameter.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
karmanpm | < 6.3.16 | 6.3.16 |
Affected products
1- Range: 1.7.1, v0.0.1, v0.0.10, …
Patches
1ff7edbb2ffbcfix(security): mitigate the "Open Redirect Vulnerability"
5 files changed · +58 −9
client/karma.js+9 −1 modified@@ -239,7 +239,15 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) self.updater.updateTestStatus('complete') } if (returnUrl) { - if (!/^https?:\/\//.test(returnUrl)) { + var isReturnUrlAllowed = false + for (var i = 0; i < this.config.allowedReturnUrlPatterns.length; i++) { + var allowedReturnUrlPattern = new RegExp(this.config.allowedReturnUrlPatterns[i]) + if (allowedReturnUrlPattern.test(returnUrl)) { + isReturnUrlAllowed = true + break + } + } + if (!isReturnUrlAllowed) { throw new Error( 'Security: Navigation to '.concat( returnUrl,
docs/config/01-configuration-file.md+9 −0 modified@@ -277,6 +277,15 @@ upon the completion of running the tests. Setting this to false is useful when e If true, Karma does not display the banner and browser list. Useful when using karma on component tests with screenshots. +## client.allowedReturnUrlPatterns +**Type:** Array + +**Default:** `['^https?://']` + +**Description:** Define the string representations of the regular expressions that will be allowed for the `return_url` query parameter. + +If the value of the `return_url` query parameter does not match any regular expression derived from the string representation of each of the elements of this array, navigation to it will be blocked. + ## colors **Type:** Boolean
lib/config.js+5 −4 modified@@ -17,19 +17,19 @@ let TYPE_SCRIPT_AVAILABLE = false try { require('coffeescript').register() COFFEE_SCRIPT_AVAILABLE = true -} catch (e) {} +} catch {} // LiveScript is required here to enable config files written in LiveScript. // It's not directly used in this file. try { require('LiveScript') LIVE_SCRIPT_AVAILABLE = true -} catch (e) {} +} catch {} try { require('ts-node') TYPE_SCRIPT_AVAILABLE = true -} catch (e) {} +} catch {} class Pattern { constructor (pattern, served, included, watched, nocache, type, isBinary) { @@ -324,7 +324,8 @@ class Config { useIframe: true, runInParent: false, captureConsole: true, - clearContext: true + clearContext: true, + allowedReturnUrlPatterns: ['^https?://'] } this.browserDisconnectTimeout = 2000 this.browserDisconnectTolerance = 0
static/karma.js+9 −1 modified@@ -249,7 +249,15 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) self.updater.updateTestStatus('complete') } if (returnUrl) { - if (!/^https?:\/\//.test(returnUrl)) { + var isReturnUrlAllowed = false + for (var i = 0; i < this.config.allowedReturnUrlPatterns.length; i++) { + var allowedReturnUrlPattern = new RegExp(this.config.allowedReturnUrlPatterns[i]) + if (allowedReturnUrlPattern.test(returnUrl)) { + isReturnUrlAllowed = true + break + } + } + if (!isReturnUrlAllowed) { throw new Error( 'Security: Navigation to '.concat( returnUrl,
test/client/karma.spec.js+26 −3 modified@@ -442,15 +442,18 @@ describe('Karma', function () { assert(spyResult.called) }) - it('should navigate the client to return_url if specified', function (done) { + it('should navigate the client to return_url if specified and allowed', function (done) { + var config = { + // The default value. + allowedReturnUrlPatterns: ['^https?://'] + } windowLocation.search = '?id=567&return_url=http://return.com' socket = new MockSocket() k = new ClientKarma(updater, socket, iframe, windowStub, windowNavigator, windowLocation) clientWindow = { karma: k } ck = new ContextKarma(ContextKarma.getDirectCallParentKarmaMethod(clientWindow)) - ck.config = {} + socket.emit('execute', config) - sinon.spy(socket, 'disconnect') clock.tick(500) ck.complete() @@ -462,6 +465,26 @@ describe('Karma', function () { clock.tick(10) }) + it('should not navigate the client to return_url if not allowed', function () { + var config = { + allowedReturnUrlPatterns: [] + } + + windowLocation.search = '?id=567&return_url=javascript:alert(document.domain)' + socket = new MockSocket() + k = new ClientKarma(updater, socket, iframe, windowStub, windowNavigator, windowLocation) + clientWindow = { karma: k } + ck = new ContextKarma(ContextKarma.getDirectCallParentKarmaMethod(clientWindow)) + socket.emit('execute', config) + + try { + ck.complete() + throw new Error('An error should have been caught.') + } catch (error) { + assert(/Error: Security: Navigation to .* was blocked to prevent malicious exploits./.test(error)) + } + }) + it('should clear context window upon complete when clearContext config is true', function () { var config = ck.config = { clearContext: true
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-rc3x-jf5g-xvc5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-23495ghsaADVISORY
- github.com/karma-runner/karma/commit/ff7edbb2ffbcdd69761bece86b7dc1ef0740508dghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-2412347ghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-KARMA-2396325ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.