Comprehensive research into Client-Side Path Traversal (CSPT) vulnerabilities across 10 modern frontend frameworks, with runnable proof-of-concept labs and detection tooling.
Presented at: Critical Thinking Bug Bounty Podcast (March 19, 2026)
Every modern frontend framework decodes URL parameters before passing them to developer code. When decoded params flow into fetch() calls, the browser normalizes ../ sequences before the HTTP request leaves — creating path traversal that bypasses server-side protections entirely.
Three things that make CSPT universal:
- No JavaScript encoding function encodes dots.
encodeURIComponent('..') === '..'— traversal survives all encoding. fetch()normalizes../before sending.fetch('/api/users/../../admin')sendsGET /admin. The browser does this, not the framework.- Server-side rendering turns CSPT into SSRF. Next.js Server Components, Remix loaders, SvelteKit
+page.server.ts— all executefetch()on the server with internal credentials and network access.
| Framework | Params decoded? | %2f → / in params? |
Double-encode? | Catch-all slashes? | Route breaks on %2f? |
|---|---|---|---|---|---|
| React Router v7 | Yes | Yes | Yes (two-step) | Yes (* splat) |
Yes |
| Next.js App Router | Client: re-encoded / Server: Yes | Client: No / Server: Yes | Version-dependent | Yes ([...slug]) |
Depends on route type |
| Remix | Yes (inherits RR) | Yes | Yes | Yes ($.tsx) |
Yes |
| Vue Router v4 | Yes | Yes | Not documented | Yes (/:pathMatch(.*)*) |
Yes |
| Nuxt 3 | Yes | Yes (via Vue Router) | Version-dependent | Yes | Yes |
| Angular | Yes | Yes (in paramMap) | Double-encodes on re-nav | N/A | No (routing preserves) |
| SvelteKit | Yes | Historical double-decode | Yes (historical) | Yes ([...rest]) |
Yes |
| Ember.js | Yes | Decoded → breaks route | Not documented | Yes (/*path) |
Yes |
| SolidStart | No | No | N/A | Yes ([...path]) |
No |
| Astro SSR | Yes (decodeURI) |
No (preserves /) |
Yes (CVE bypass) | Yes ([...slug]) |
Depends on adapter |
Each framework has a dedicated research directory containing:
| File | Contents |
|---|---|
01-route-definitions.md |
Route syntax, minification survival, detection regexes |
02-source-to-sink.md |
CSPT sources and sinks with minified patterns |
03-encoding-behavior.md |
Decoding pipeline with source code analysis |
04-encoding-matrix.md |
Complete encoding test matrix |
05-caido-patterns.md |
Regex patterns for automated detection |
06-appendix.md |
Source references, lab structure, build analysis |
Frameworks covered: React Router, Next.js, Vue Router, Nuxt, Angular, SvelteKit, Astro, Ember.js, SolidStart, Remix
Each lab is a real, runnable application demonstrating CSPT in the target framework.
| Lab | Stack | Key Patterns |
|---|---|---|
react-cspt-lab |
React 19, React Router 7, TanStack Query | useParams → fetch, splat routes, dangerouslySetInnerHTML chains |
nextjs-cspt-lab |
Next.js 15.3, App Router | Encoding differential: page params (re-encoded) vs route handlers (decoded) |
vue-router-cspt-lab |
Vue 3, Vue Router 4, TanStack Vue Query | route.params → fetch, catch-all arrays, encoding split |
nuxt-cspt-lab |
Nuxt 3.17, Vue 3 | Island payloads, server routes, H3 |
angular-cspt-lab |
Angular 21, @angular/router | paramMap extraction, encoding behaviors |
sveltekit-cspt-lab |
SvelteKit 2, Svelte 5 | +page.server.ts loaders, encoding differential |
astro-cspt-lab |
Astro 5, @astrojs/node | decodeURI behavior, middleware bypass |
ember-cspt-lab |
Ember.js 6, Embroider/Vite | Wildcard routes, triple-curlies, adapters |
solidstart-cspt-lab |
SolidStart 1.1, Solid.js 1.9 | createResource, server functions, innerHTML |
remix-cspt-lab |
React Router 7 (Framework Mode) | Loaders (decoded), actions, .data endpoint, SSRF |
Passive framework detection with client-side path extraction and CSPT sink analysis. Integrates with the Caido HTTP proxy to detect framework fingerprints, extract dynamic route definitions from minified bundles, and identify CSPT source-to-sink chains.
Chrome DevTools panel ("doctorscan") for detecting CSPT patterns directly in the browser. Identifies frameworks, extracts routes, and flags CSPT sources and sinks with per-framework encoding context. No traffic interception required.
cspt-framework-notes.md— Master reference document (54 KB) covering all frameworks with encoding comparisons, CVEs, and detection patternsreact-cspt-deep-dive.md— Detailed empirical analysis of React Router v7 encoding behavior with comprehensive encoding matrix
The novel contribution of this research is documenting how each framework's encoding pipeline creates (or prevents) CSPT:
- React Router v7 double-decodes through
safelyDecodeURI()+safelyDecodeURIComponent()—%252fbecomes/ - Next.js App Router re-encodes page params but leaves route handler params decoded — same framework, different attack surface
- SolidStart doesn't decode params at all — defense-in-depth by default
- Astro uses
decodeURI()instead ofdecodeURIComponent()—%2Fpreserved, but encoded letters decode (CVE-2025-64765) - Vue Router has the cleanest exploit:
route.paramsdecoded,route.pathencoded — consistent and reliable
| CVE | Framework | Description |
|---|---|---|
| CVE-2025-64765 | Astro | Middleware bypass via URL-encoded letters (/%61dmin) |
| CVE-2025-59414 | Nuxt 3 | Stored CSPT via island payload revival |
| CVE-2025-67647 | SvelteKit | SSRF via decode_pathname() vs url.pathname discrepancy |
| CVE-2025-29927 | Next.js | Middleware skip via x-middleware-subrequest header |
| GHSA-whqg-ppgf-wp8c | Astro | Double-encoding bypass of initial fix |
When CSPT occurs in SSR contexts, it becomes SSRF with internal credentials:
- Remix loaders execute
fetch()with server-side auth headers and internal network access - SvelteKit
+page.server.tsload functions run on the server - Next.js route handlers and Server Components fetch with full server privileges
- Nuxt server routes via H3 have access to internal services
Each lab is a standalone application. Install dependencies and start the dev server:
# Example: React lab
cd react-cspt-lab
bun install
bun run dev
# Example: Next.js lab
cd nextjs-cspt-lab
bun install
bun run devBuild to production to test detection against minified/bundled code:
bun run buildxssdoctor — Offensive security researcher specializing in client-side vulnerabilities
This research is provided for educational and authorized security testing purposes only.