{"id":"GHSA-2m6q-8v3h-jqww","revision":"4d5ac48154bf4b8a93b22fa91a8de336","records":[{"revision":"4d5ac48154bf4b8a93b22fa91a8de336","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-2m6q-8v3h-jqww","aliases":["CVE-2026-107718"],"title":"AdonisJS: Unencoded route parameters can produce open redirects","description":"Route parameters are inserted into generated URLs without URI encoding.\n\nWhen an application passes untrusted input to a route whose first path segment is dynamic, a value beginning with / can produce a scheme-relative URL. For example:\n\n```ts\nrouter.get('/:page', handler).as('pages.show')\n\nresponse.redirect().toRoute('pages.show', {\n  page: '/evil.example.com',\n})\n```\n\nThis generates the following redirect:\n\n```http\nLocation: //evil.example.com\n```\n\nBrowsers interpret this value as an external URL and redirect the user to `https://evil.example.com`.\n\n## Details\n\nThe shared `createURL()` helper is used by route URL builders, including `Router.makeUrl()` and `Response.redirect().toRoute()`.\n\nRoute parameter values were appended without encoding:\n\n```ts\nif (isDefined) {\n  uriSegments.push(`${value}${token.end}`)\n}\n```\n\nWildcard parameters had the same behavior:\n\n```ts\nuriSegments.push(`${values.join('/')}${token.end}`)\n```\n\n**The issue does not affect APIs that intentionally accept complete redirect URLs. Exploitation requires an application to pass attacker-controlled data as a route parameter and use the generated URL as a redirect destination.**\n\n## Impact\n\nAn attacker may craft a link on a trusted application domain that redirects a victim to an attacker-controlled website.\n\nThis can facilitate phishing and may be chained with authentication or OAuth flows that rely on trusted redirect destinations.\n\nApplications are affected when they:\n- define a route whose first path segment is dynamic; and\n- pass request-derived data to that segment when generating a redirect URL.\n\n## Patches\n\nRoute parameter values are now encoded using `encodeURIComponent`.\n\nWildcard values are encoded individually before being joined with `/`, preserving their intended segment separators:\n\n```ts\nif (isDefined) {\n  uriSegments.push(`${encodeURIComponent(String(value))}${token.end}`)\n}\n```\n\n```ts\nuriSegments.push(\n  `${values.map((value) => encodeURIComponent(String(value))).join('/')}${token.end}`\n)\n```\n\nWith the fix, `/evil.example.com` becomes:\n\n```\n/%2Fevil.example.com\n```\n\nFixes targeting v6 and v7 have been published below.\n- https://github.com/adonisjs/http-server/releases/tag/v8.2.3\n- https://github.com/adonisjs/http-server/releases/tag/v9.3.0","state":0,"publishedAt":"2026-10-08T22:09:06+00:00","modifiedAt":"2026-10-08T22:30:09.0305892+00:00","affected":[{"ecosystem":"npm","name":"@adonisjs/http-server","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"9.0.0"},{"kind":"fixed","version":"9.3.0"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"npm","name":"@adonisjs/http-server","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"8.2.3"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/adonisjs/http-server/security/advisories/GHSA-2m6q-8v3h-jqww","https://github.com/adonisjs/http-server/commit/4548a0631ce2ef1618f04c7b41465be42cad2f7d","https://github.com/adonisjs/http-server/commit/ab607a2958327b6f0019d38f26081e431768877a","https://github.com/adonisjs/http-server","https://github.com/adonisjs/http-server/releases/tag/v8.2.3","https://github.com/adonisjs/http-server/releases/tag/v9.3.0"],"sourceUrl":"https://github.com/advisories/GHSA-2m6q-8v3h-jqww","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-2m6q-8v3h-jqww","identifiers":["GHSA-2m6q-8v3h-jqww","CVE-2026-107718"]},"retained":false,"historicalAffected":[]}],"coverage":[]}