Skip to content

fix: guard encoded example routes by matched route ID - #21

Merged
nicknisi merged 2 commits into
mainfrom
nickcollisson/sec-1332-encoded-path-guard-bypass
Sep 15, 2026
Merged

nicknisi merged 2 commits into
mainfrom
nickcollisson/sec-1332-encoded-path-guard-bypass

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

The example app's protectedRoutesHandle (example/src/hooks.server.ts) matched request paths without normalizing percent-encoded segments, so encoded variants could miss the guard's prefix checks. This change normalizes the path before matching.

Please review before merging.

The example protectedRoutesHandle hook guarded on event.url.pathname, which preserves percent-encoding per the WHATWG URL spec. SvelteKit decodes the pathname before matching routes, so a request to /%61ccount skipped the guard yet still dispatched the protected /account route (same for /%61pi/... vs the /api/ guard).

Guard on event.route.id (the resolved route) instead, which reflects the matched route and is immune to encoding tricks.
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author
Original prompt from Linear User

Please work on ticket "Authentication bypass of the reference route-protection handle hook via percent-encoded pathnames (example app protectedRoutesHandle)" (SEC-1332)

@playbook:playbook-b588614117c7477a9b9729928385384f

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@linear-code

linear-code Bot commented Jul 22, 2026

Copy link
Copy Markdown

SEC-1332

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge.

Summary

The PR hardens and verifies the example application's protected-route handling.

  • Uses SvelteKit's matched route ID instead of the percent-encoded request pathname when applying authentication policy.
  • Preserves redirects for protected browser pages and JSON 401 responses for protected API routes.
  • Adds Vitest coverage for encoded protected paths, authenticated requests, public routes, and unmatched routes.
  • Enables test execution with coverage in CI.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Incoming request] --> B[AuthKit handle]
  B --> C[Populate event.locals.auth]
  C --> D[Protected-routes handle]
  D --> E{Matched route ID protected?}
  E -->|No| F[Resolve route]
  E -->|Yes, authenticated| F
  E -->|Yes, unauthenticated API| G[Return JSON 401]
  E -->|Yes, unauthenticated page| H[Redirect to login]
Loading

Reviews (2) · Last reviewed commit: "fix: recover encoded-route guard with CI..."

@devin-ai-integration
devin-ai-integration Bot deleted the nickcollisson/sec-1332-encoded-path-guard-bypass branch July 27, 2026 16:15
@devin-ai-integration devin-ai-integration Bot changed the title Fix encoded-path auth bypass in example route guard Normalize encoded paths in the example route guard Jul 27, 2026
@nicknisi nicknisi reopened this Sep 15, 2026
@nicknisi nicknisi changed the title Normalize encoded paths in the example route guard fix: guard encoded example routes by matched route ID Sep 15, 2026
@nicknisi

Copy link
Copy Markdown
Member

Recovered this branch onto current main and added tests against the actual example route guard. Coverage includes canonical and encoded account/API paths, authenticated access, public routes, and unmatched routes. Enabled the test/coverage step in CI.

Verification: 39 tests passed with coverage, plus root typecheck, formatting, library build, and example build. The example typecheck passes with placeholder environment configuration. The standalone lint script still fails because of its pre-existing ESLint configuration, reproduced on current main; lint was already disabled in CI and remains unchanged. A fresh independent code review found no code blocker. Not merged or released.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

❌ Cannot revive Devin session - the session is too old. Please start a new session instead.

View session

@nicknisi
nicknisi merged commit 3ba1db1 into main Sep 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant