Skip to content

fix(security): reject scheme-relative /share paths, enforce origin - #307

Open
birme wants to merge 1 commit into
mainfrom
security/270-share-open-redirect
Open

fix(security): reject scheme-relative /share paths, enforce origin#307
birme wants to merge 1 commit into
mainfrom
security/270-share-open-redirect

Conversation

@birme

@birme birme commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • POST /api/v1/share built a share URL from caller-supplied path validated only with TypeBox pattern: '^/', which also matches scheme-relative (//evil.com/x) and backslash-prefixed (/\evil.com) values. new URL(path, publicHost) then resolves to an attacker-controlled origin, causing an open redirect in the returned url and — more seriously — in the redirectUrl embedded in a minted OSC delegate token.
  • Defense in depth (both layers):
    1. Tightened ShareRequest.path pattern in src/models.ts to ^/(?![/\\]).* so it requires a single leading / not followed by / or \ (keeps maxLength: 500).
    2. In src/api_share.ts, after new URL(req.body.path, opts.publicHost), assert the resolved origin equals new URL(opts.publicHost).origin and reply 400 otherwise, guarding even if the schema is bypassed.
  • Both are needed: the schema rejects malformed input at the edge; the runtime origin check is a fail-safe that also catches any future URL-parsing edge cases before the value reaches the delegate service or the response.

Test plan

  • Tests pass (npm test) — 14 suites, 248 tests
  • TypeScript compiles (npm run typecheck)
  • Lint clean (npm run lint) — 0 errors
  • //evil.com, /\evil.com, \\evil.com, https://evil.com, and no-slash paths rejected (400); valid paths like /mypath/to/share still return the correct same-origin URL

Closes #270

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

…Host origin

Closes #270

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

Security: /share accepts scheme-relative path → open redirect + attacker-controlled delegate redirectUrl

1 participant