8000 fix(auth): refuse sign-in destinations with control characters by adeelahmad · Pull Request #197 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content

fix(auth): refuse sign-in destinations with control characters - #197

Merged
adeelahmad merged 1 commit into
mainfrom
claude/project-thread-qt650x-safe-next
Oct 6, 2026
Merged

adeelahmad merged 1 commit into
mainfrom
claude/project-thread-qt650x-safe-next

Conversation

@adeelahmad
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

Description

Before: the post-sign-in destination checks (safeCallbackUrl for /login?callbackUrl=, safeNext on the external-login return, and the API's _safe_next) accepted /\t/evil.example. Browsers drop tabs, CR and LF from URLs, so after a passkey or external sign-in, location.assign went to https://evil.example/. That is an open redirect from a link on the real site.

After: all three refuse control characters and backslashes anywhere in the path, and safeNext now reuses safeCallbackUrl. Ordinary paths with query strings behave as before. Password sign-in was not affected, because Auth.js already prefixes its own base URL.

Motivation and Context

This answers threat-model question Q40: a post-sign-in next target is limited to same-origin paths (claimed, correctness-only).

Steps to reproduce (if appropriate):

The new tab, CR and LF cases fail on main and pass here: __tests__/navigation.test.ts, __tests__/externalSignIn.test.tsx, and the new line in tests/api/test_external_login.py.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change; ! in the title)

Checklist:

  • The title is a Conventional Commit.
  • My code follows the code style of this project (make hooks checks it on commit).
  • I added or updated tests.
  • My change requires documentation updates, and I have updated docs/ accordingly.
  • Users need more than the title to understand it, so I wrote it under ## Unreleased in CHANGELOG.md.

🤖 Generated with Claude Code

https://claude.ai/code/session_01W42z4FbekWr33b6791svQQ


Generated by Claude Code

Browsers drop tabs and line breaks from a URL, so a callbackUrl or next of
"/\t/evil.example" passed the same-site check and then opened
//evil.example after signing in. The web app and the API now refuse
control characters and backslashes anywhere in it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W42z4FbekWr33b6791svQQ
@adeelahmad adeelahmad self-assigned this Oct 6, 2026
@adeelahmad
adeelahmad merged commit bd97607 into main Oct 6, 2026
5 checks passed
@adeelahmad
adeelahmad deleted the claude/project-thread-qt650x-safe-next branch October 6, 2026 10:46
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.

2 participants

0