Skip to content

Don't re-apply persistent credential headers across cross-origin redirects#433

Open
oalders wants to merge 1 commit into
masterfrom
mech-cross-origin
Open

Don't re-apply persistent credential headers across cross-origin redirects#433
oalders wants to merge 1 commit into
masterfrom
mech-cross-origin

Conversation

@oalders

@oalders oalders commented Jun 19, 2026

Copy link
Copy Markdown
Member

Summary

Headers set via add_header() — notably Authorization — were re-applied by _modify_request() to cross-origin redirect targets, undoing the credential stripping LWP::UserAgent performs on its own cross-origin redirects.

_modify_request() now detects a cross-origin redirect hop using the response LWP::UserAgent threads into request(), and skips re-applying Authorization/Proxy-Authorization to a different origin. This mirrors LWP's own redirect handling. Set allow_credentialed_redirects to a true value to opt back in.

Details

  • A new private _is_cross_origin() compares scheme and host_port of the previous hop and the new request (after canonical, so case-only and default-port differences don't count as cross-origin).
  • request() passes the LWP-threaded triggering response into _modify_request() so the cross-origin check only fires on redirect/auth re-entry, never on a normal first request.
  • Same-origin redirects, and the allow_credentialed_redirects opt-out, preserve the header exactly as before.

Tests

t/cross-origin-redirect.t drives LWP's real redirect loop over a mocked transport and asserts, table-driven:

  • cross-origin strips Authorization and Proxy-Authorization
  • same-origin preserves the header
  • a different port is cross-origin (strips)
  • a case-only host difference is same-origin (preserves)
  • allow_credentialed_redirects opts back in (preserves)

🤖 Generated with Claude Code

@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.95%. Comparing base (c0adc38) to head (c1d0b83).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #433      +/-   ##
==========================================
+ Coverage   89.84%   89.95%   +0.10%     
==========================================
  Files           3        3              
  Lines         857      866       +9     
  Branches      226      227       +1     
==========================================
+ Hits          770      779       +9     
  Misses         37       37              
  Partials       50       50              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Persistent headers set via add_header() (Authorization, Proxy-Authorization
and Cookie) were re-applied by _modify_request() to cross-origin redirect
targets, leaking them to a different origin (the CVE-2018-1000007 class of
leak).

_modify_request() now detects a cross-origin redirect hop using the
response LWP::UserAgent threads into request(), and removes the credential
headers from the request outright on such a hop. Removing them (rather than
only declining to re-apply our own) means the fix does not depend on the
LWP version: older LWP releases clone these headers forward instead of
stripping them. The cookie jar is unaffected, since it sets its
domain-scoped Cookie header later in prepare_request.

allow_credentialed_redirects opts out. Mech now owns that option (stored in
the same hash slot LWP::UserAgent uses) so the opt-out is honoured on every
LWP version, including releases that predate LWP's own cross-origin strip.

A new _is_cross_origin() compares scheme and host_port (after canonical),
so case-only and default-port differences do not count as cross-origin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@oalders oalders force-pushed the mech-cross-origin branch from 9c133d0 to c1d0b83 Compare June 19, 2026 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant