Skip to content

fix: report the post-redirect URL instead of silently mislabeling it#114

Merged
dmchaledev merged 2 commits into
mainfrom
fix/report-final-url
Jul 19, 2026
Merged

fix: report the post-redirect URL instead of silently mislabeling it#114
dmchaledev merged 2 commits into
mainfrom
fix/report-final-url

Conversation

@dmchaledev

Copy link
Copy Markdown
Contributor

Summary

analyze(url) labels the report with the pre-redirect input URL even though the grade/findings describe whatever host the redirect chain actually landed on — e.g. http://https://, apex → www, staging → a login page. Verified live against http://github.com: report said url: "http://github.com" while every finding actually described https://github.com/.

Reimplements #109 (which is closed — its fetchHeadersWithMeta used a plain fetch(url, {redirect: 'follow'}), predating #99's SSRF hardening) on top of the current hop-by-hop redirect loop in src/fetch.ts, so the private-IP/redirect validation from #99 stays intact.

Changes

  • src/fetch.ts: fetchHeadersWithMeta(url, options) returns { headers, finalUrl } from the existing validated hop loop; fetchHeaders is now a thin wrapper, unchanged signature.
  • src/types.ts: additive optional finalUrl?: string on SecurityHeaderReport.
  • src/index.ts: analyze() sets finalUrl only when it differs from the requested URL.
  • src/cli.ts: prints Redirected to: <url>; included in --json output.
  • README.md: documents the new field.
  • Tests: test/fetch.test.ts covers fetchHeadersWithMeta with and without a redirect; test/cli.test.ts's fetch.js mock updated to export fetchHeadersWithMeta (it previously mocked fetchHeaders, which index.ts no longer calls — would have broken silently otherwise).

Verification

  • npm run typecheck, npm test (143/143), npm run build all pass.
  • Manually ran the built CLI against a real redirecting URL: node dist/cli.js http://github.com --jsonurl: "http://github.com", finalUrl: "https://github.com/".

Closes #93.


Generated by Claude Code

claude and others added 2 commits July 19, 2026 07:20
Reimplements #109 on top of #99's SSRF-hardened fetch loop (redirect: 'manual'
with per-hop private-IP validation) instead of the old redirect: 'follow' call
#109 assumed, which would have silently reintroduced the SSRF-via-redirect gap.

- src/fetch.ts: fetchHeadersWithMeta(url, options) returns {headers, finalUrl},
  reusing the existing hop loop; fetchHeaders is now a thin wrapper.
- src/types.ts: optional finalUrl on SecurityHeaderReport (additive).
- src/index.ts: analyze() sets report.finalUrl when it differs from the input.
- src/cli.ts: prints "Redirected to: <url>" and includes finalUrl in --json.
- Updated test/cli.test.ts's fetch.js mock (previously exported fetchHeaders,
  which index.ts no longer calls) to export fetchHeadersWithMeta instead.

Closes #93.
@dmchaledev
dmchaledev merged commit 4bbc2ea into main Jul 19, 2026
2 checks passed
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.

Report silently grades the post-redirect URL while labeling it with the pre-redirect one

2 participants