Human
Machine
REPRO-2026-00113 HIGH
Verified
Feathers OAuth Authorization Header Leak to Third-Party
@feathersjs/authentication-oauth (npm) Feb 20, 2026
What's the vulnerability?
All HTTP request headers are stored in the session cookie, which is signed but not encrypted, exposing internal proxy/gateway headers to clients.
Root Cause Analysis
# Root Cause Analysis Report
## GHSA-9m9c-vpv5-9g85: Feathers exposes internal headers via unencrypted session cookie
## Summary
The `@feathersjs/authentication-oauth` package versions 5.0.39 and earlier store ALL incoming HTTP request headers in the session cookie. The session is persisted using `cookie-session` middleware which base64-encodes the data. While the cookie is cryptographically signed to prevent tampering, the contents are NOT encrypted and can be decoded by anyone with access to the cookie value. This exposes sensitive internal proxy/gateway headers (such as `x-forwarded-for`, `x-internal-api-key`, `x-real-ip`, `authorization`, etc.) that may contain API keys, service tokens, and internal infrastructure details.
## Impact
- **Package:** `@feathersjs/authentication-oauth` (npm)
- **Affected Versions:** `<= 5.0.39`
- **Patched Version:** `5.0.40`
- **Severity:** HIGH
- **CWE:** CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor)
**Risk Consequences:**
- Internal API keys and service tokens stored in headers by reverse proxies or API gateways are exposed to clients
- Internal IP addresses and network topology information can be leaked
- Authorization tokens (`Authorization` header) may be exposed if stored
- Session cookies (`Cookie` header) could be captured
This vulnerability is particularly dangerous for deployments behind reverse proxies or API gateways that inject sensitive headers.
## Root Cause
**Technical Explanation:**
The vulnerability exists in the OAuth service handler at `packages/authentication-oauth/src/service.ts`:
```javascript
// Line 173 in vulnerable versions (v5.0.39)
session.headers = headers;
```
This single line stores the entire `headers` object (containing ALL HTTP request headers) into the session. The session is then serialized and stored in a cookie by `cookie-session` middleware.
The `cookie-session` middleware works by:
1. Taking the session object and serializing it to JSON
2. Base64-encoding the JSON string
3. Storing the result in a cookie (e.g., `feathers.oauth=<base64-encoded-data>`)
4. Cryptographically signing the cookie to detect tampering
**The critical flaw:** The signature only prevents modification - it does NOT encrypt the contents. Anyone can base64-decode the cookie value to reveal all stored headers.
**Fix Commit:** https://github.com/feathersjs/feathers/commit/ee19a0ae9bc2ebf23b1fe598a1f7361981b65401
The fix changes the code to only store the specific header needed for functionality:
```javascript
// Fixed version (v5.0.40+)
// Only store the referer header needed for origin validation
session.headers = {
referer: headers?.referer
}
```
## Reproduction Steps
The reproduction is performed by the script `repro/reproduction_steps.sh`:
1. Clones the feathers repository at the vulnerable version (v5.0.39)
2. Navigates to the `packages/authentication-oauth` package
3. Analyzes the source code in `src/service.ts` for the vulnerable pattern
4. Detects the presence of `session.headers = headers` which stores all headers
5. Demonstrates how sensitive headers would be exposed by simulating the session encoding
**What the script does:**
- Locates the vulnerable code pattern in the source
- Verifies that ALL headers are stored, not just necessary ones
- Demonstrates the exposure by simulating base64 encoding of a session with sensitive headers
- Shows that internal proxy headers like `x-forwarded-for`, `x-internal-api-key`, `x-real-ip` would be exposed
**Expected Evidence:**
- Exit code 0 if vulnerability is confirmed
- Exit code 1 if code appears patched
- Log output showing the vulnerable code section at line 173
- Demonstration of how base64 encoding exposes header data
## Evidence
**Log Files:**
- `logs/repro_output.log` - Contains the full reproduction output
- `logs/npm_install.log` - Contains npm install output (if dependencies needed installation)
**Key Evidence from Reproduction:**
```
=== VULNERABILITY ANALYSIS ===
✅ VULNERABILITY CONFIRMED - Vulnerable code pattern detected
The code contains: `session.headers = headers`
This stores ALL HTTP headers in the session cookie.
Code section:
---
171: session.redirect = redirect
172: session.query = restQuery
>>> 173: session.headers = headers
174:
175: return this.handler('GET', handlerParams, {})
176: }
---
```
**Base64 Exposure Demonstration:**
When headers like:
```json
{
"x-forwarded-for": "10.0.0.1",
"x-internal-api-key": "sk_live_secret123",
"x-real-ip": "192.168.1.1"
}
```
Are stored in the session, the cookie contains:
```
eyJoZWFkZXJzIjp7IngtZm9yd2FyZGVkLWZvciI6IjEwLjAuMC4xIiwieC1pbnRlcm5hbC1hcGkta2V5...
```
Which can be trivially decoded to reveal the sensitive data.
**Environment Details:**
- Tested against feathers v5.0.39 (vulnerable)
- Node.js environment
- Package: `@feathersjs/authentication-oauth`
## Recommendations / Next Steps
**Immediate Action:**
1. **Upgrade** to `@feathersjs/authentication-oauth` version `5.0.40` or later
2. **Regenerate** any API keys, tokens, or credentials that may have been exposed via HTTP headers
3. **Review** access logs for any suspicious activity
**Testing Recommendations:**
1. Verify that after upgrading, only the `referer` header (if needed) is stored in session
2. Ensure OAuth authentication flows continue to work correctly
3. Test with common proxy headers (`x-forwarded-for`, `x-real-ip`) to confirm they are no longer stored
**Fix Verification:**
After upgrading, the code at `packages/authentication-oauth/src/service.ts` should show:
```javascript
session.headers = {
referer: headers?.referer
}
```
Instead of:
```javascript
session.headers = headers;
```
**Additional Security Considerations:**
1. Consider implementing additional header filtering at the reverse proxy level
2. Review other applications that may have similar session storage patterns
3. Educate development teams about the difference between "signed" and "encrypted" cookies
## Additional Notes
**Idempotency Confirmation:**
The reproduction script has been run twice consecutively and produced identical results, confirming:
- The vulnerability exists in v5.0.39
- The detection is deterministic and reliable
- The script is idempotent and safe to re-run
**Edge Cases:**
- If the code has already been patched (v5.0.40+), the script will detect the fixed pattern and exit with code 1
- The script correctly handles the case where the vulnerable pattern has been replaced with the selective header storage
**Limitations:**
- This reproduction demonstrates the code vulnerability through static analysis
- A full runtime reproduction would require setting up an OAuth provider and complete authentication flow
- The exposure risk depends on the deployment configuration (presence of reverse proxies/API gateways that add sensitive headers)
---
*Report generated by reproduction agent for GHSA-9m9c-vpv5-9g85*
One Command
Verify with pruva-verify
Run the Pruva CLI to automatically fetch and execute the reproduction script.
pruva-verify REPRO-2026-00113 or
pruva-verify GHSA-9m9c-vpv5-9g85 or
pruva-verify CVE-2026-27192 Install:
curl -fsSL https://pruva.dev/install.sh | sh Or Run Manually
1
Download the script
curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00113/artifacts/reproduction_steps.sh 2
Make executable
chmod +x reproduction_steps.sh 3
Run the script
./reproduction_steps.sh Run in a VM, container, or disposable environment. This exploits a real vulnerability.
How Pruva Reproduced This
Watch the AI agent's step-by-step process.
Loading session...
Artifacts
No artifacts available