trails/apps/planner/app/routes
Ullrich Schäfer c3454641df
security: validate Planner callback URL to close an SSRF sink
The session callbackUrl becomes a server-side fetch target in
api.save-to-journal (POSTed with the callback bearer token, and the
journal's response is reflected to the caller). The /new query-param
loader already validated it, but the programmatic POST /api/sessions
entry point — anonymous, since the Planner is stateless — stored it
unvalidated. An attacker could make the Planner backend POST to
arbitrary hosts, including 169.254.169.254 and other internal targets.

- validateFetchUrl now blocks private / loopback / link-local /
  CGNAT / cloud-metadata hosts (IPv4, IPv6, IPv4-mapped) when an
  explicit allowlist isn't set. Gated on NODE_ENV=production && !E2E
  (the requireSecret idiom) so the dev/e2e journal-on-localhost save
  flow is unaffected. An explicit PLANNER_CALLBACK_ALLOWED_HOSTS still
  takes precedence and remains the full-closure control (it also stops
  DNS-name-to-private rebinding, which literal blocking does not).
- POST /api/sessions now validates callbackUrl exactly as /new does.
- api.save-to-journal re-validates immediately before the fetch
  (defense in depth: covers sessions persisted before this change and
  narrows the create→save rebinding window).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 22:18:18 +02:00
..
api.overpass.test.ts Fix planner build: move Overpass upstream fetch to overpass.server.ts 2026-04-23 22:40:15 +02:00
api.overpass.ts Fix planner build: move Overpass upstream fetch to overpass.server.ts 2026-04-23 22:40:15 +02:00
api.route-segments.ts Cache BRouter segments client-side, fetch only the diff 2026-04-24 17:57:54 +02:00
api.route.ts Session-bind /api/route and /api/overpass 2026-04-21 22:18:45 +02:00
api.save-to-journal.ts security: validate Planner callback URL to close an SSRF sink 2026-06-10 22:18:18 +02:00
api.sessions.ts security: validate Planner callback URL to close an SSRF sink 2026-06-10 22:18:18 +02:00
home.tsx Add legal pages, ToS acceptance, and alpha banner 2026-04-18 00:08:48 +02:00
new.tsx fix(planner): validate callback/returnUrl + cap session URL-param payloads 2026-05-26 00:05:47 +02:00
session.$id.tsx fix(planner): keep journal callback token off the client (#2 Phase A) 2026-05-26 00:29:24 +02:00