Koa Vulnerable to Open Redirect via Trailing Double-Slash (//) in back Redirect Logic
Description
Koa is expressive middleware for Node.js using ES2017 async functions. In versions 2.16.2 to before 2.16.3 and 3.0.1 to before 3.0.3, a bypass to CVE-2025-8129 was discovered in the Koa.js framework affecting its back redirect functionality. In certain circumstances, an attacker can manipulate the Referer header to force a user’s browser to navigate to an external, potentially malicious website. This occurs because the implementation incorrectly treats some specially crafted URLs as safe relative paths. Exploiting this vulnerability could allow attackers to perform phishing, social engineering, or other redirect-based attacks on users of affected applications. This issue has been patched in version 3.0.3.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
koanpm | >= 3.0.1, < 3.0.3 | 3.0.3 |
koanpm | >= 2.16.2, < 2.16.3 | 2.16.3 |
Affected products
1Patches
1769fd75cc6b3fix: normalize referer before redirect (#1908)
2 files changed · +19 −9
lib/response.js+0 −6 modified@@ -322,12 +322,6 @@ module.exports = { back (alt) { const referrer = this.ctx.get('Referrer') if (referrer) { - // referrer is a relative path - if (referrer.startsWith('/')) { - this.redirect(referrer) - return - } - // referrer is an absolute URL, check if it's the same origin const url = new URL(referrer, this.ctx.href) if (url.host === this.ctx.host) {
__tests__/response/back.test.js+19 −3 modified@@ -6,7 +6,7 @@ const context = require('../../test-helpers/context') describe('ctx.back([alt])', () => { it('should redirect to Referrer', () => { - const ctx = context() + const ctx = context({ url: '/', headers: { host: 'example.com' } }) ctx.req.headers.referrer = '/login' ctx.back() assert.equal(ctx.response.header.location, '/login') @@ -28,13 +28,19 @@ describe('ctx.back([alt])', () => { assert.equal(ctx.response.header.location, '/') }) - it('should redirect to Referer', () => { - const ctx = context() + it('should redirect to Referer to a relative path', () => { + const ctx = context({ url: '/', headers: { host: 'example.com' } }) ctx.req.headers.referer = '/login' ctx.back() assert.equal(ctx.response.header.location, '/login') }) + it('should redirect to Referer to a same origin url', () => { + const ctx = context({ url: '/', headers: { host: 'example.com', referer: 'https://example.com/login' } }) + ctx.back() + assert.equal(ctx.response.header.location, 'https://example.com/login') + }) + it('should default to alt', () => { const ctx = context() ctx.back('/index.html') @@ -46,4 +52,14 @@ describe('ctx.back([alt])', () => { ctx.back() assert.equal(ctx.response.header.location, '/') }) + + it('should fix Trailing Double-Slash security issue', () => { + const ctx = context({ url: '/', headers: { host: 'example.com' } }) + ctx.req.headers.referrer = '//evil.com/login/' + ctx.back() + assert.equal(ctx.response.header.location, '/') + + ctx.back('/home') + assert.equal(ctx.response.header.location, '/home') + }) })
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-g8mr-fgfg-5qpcghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-62595ghsaADVISORY
- github.com/koajs/koa/commit/769fd75cc6b30d72493b370b5a3ae2332ca03c5bghsax_refsource_MISCWEB
- github.com/koajs/koa/security/advisories/GHSA-g8mr-fgfg-5qpcghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.