@adonisjs/http-server: AdonisJS: Unencoded route parameters can produce open redirects
What fixes it
- 9.3.0@adonisjs/http-server, npmGitHub
npm install @adonisjs/http-server@9.3.0 - 8.2.3@adonisjs/http-server, npmGitHub
npm install @adonisjs/http-server@8.2.3
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
Route parameters are inserted into generated URLs without URI encoding.
When 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:
router.get('/:page', handler).as('pages.show')
response.redirect().toRoute('pages.show', {
page: '/evil.example.com',
})This generates the following redirect:
Location: //evil.example.com
Browsers interpret this value as an external URL and redirect the user to https://evil.example.com.
Details
The shared createURL() helper is used by route URL builders, including Router.makeUrl() and Response.redirect().toRoute().
Route parameter values were appended without encoding:
if (isDefined) {
uriSegments.push(`${value}${token.end}`)
}Wildcard parameters had the same behavior:
uriSegments.push(`${values.join('/')}${token.end}`)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.
Impact
An attacker may craft a link on a trusted application domain that redirects a victim to an attacker-controlled website.
This can facilitate phishing and may be chained with authentication or OAuth flows that rely on trusted redirect destinations.
Applications are affected when they:
- define a route whose first path segment is dynamic; and
- pass request-derived data to that segment when generating a redirect URL.
Patches
Route parameter values are now encoded using encodeURIComponent.
Wildcard values are encoded individually before being joined with /, preserving their intended segment separators:
if (isDefined) {
uriSegments.push(`${encodeURIComponent(String(value))}${token.end}`)
}uriSegments.push(
`${values.map((value) => encodeURIComponent(String(value))).join('/')}${token.end}`
)With the fix, /evil.example.com becomes:
/%2Fevil.example.com
Fixes targeting v6 and v7 have been published below.
- https://github.com/adonisjs/http-server/releases/tag/v8.2.3
- https://github.com/adonisjs/http-server/releases/tag/v9.3.0
Text from GitHub Advisory Database
Affected versions 6
- @adonisjs/http-server, npm>= 9.0.0, <= 9.2.0GitHub
- @adonisjs/http-server, npm<= 8.2.2GitHub
- http-serveraffected: < 8.2.3CVE List
- http-serveraffected: >= 9.0.0, < 9.3.0CVE List
- @adonisjs/http-server, npmfrom 9.0.0, fixed in 9.3.0OSV
- @adonisjs/http-server, npmfrom first release, fixed in 8.2.3OSV
References 6
- github.com/adonisjs/http-server/commit/4548a0631ce2ef1618f04c7b41465be42cad2f7dFixvia CVE List
- github.com/adonisjs/http-server/commit/ab607a2958327b6f0019d38f26081e431768877aFixvia CVE List
- github.com/adonisjs/http-server/releases/tag/v8.2.3Fixvia CVE List
- github.com/adonisjs/http-server/releases/tag/v9.3.0Fixvia CVE List
- github.com/adonisjs/http-server/security/advisories/GHSA-2m6q-8v3h-jqwwAdvisoryvia CVE List
- github.com/advisories/GHSA-2m6q-8v3h-jqwwAdvisoryvia GitHub