Skip to content

Fix path traversal in GET /api/chat-modes/:modeId#44

Merged
sbaker merged 1 commit into
mainfrom
fix/chat-modes-path-traversal
Apr 19, 2026
Merged

Fix path traversal in GET /api/chat-modes/:modeId#44
sbaker merged 1 commit into
mainfrom
fix/chat-modes-path-traversal

Conversation

@sbaker
Copy link
Copy Markdown
Member

@sbaker sbaker commented Apr 19, 2026

Summary

GET /api/chat-modes/:modeId in backend/src/routes/chatModes.js joined the modeId route parameter directly into a filesystem path with no validation:

const filePath = path.join(PROMPTS_DIR, `${modeId}.json`)

Express decodes URL-encoded characters in route parameters, so a request like GET /api/chat-modes/..%2F..%2Fsome-file resolves modeId to ../../some-file and path.join escapes PROMPTS_DIR. Any .json file readable by the backend process could be disclosed through the response.

Fix

Validate modeId against a strict allowlist regex (^[a-z0-9][a-z0-9-]{0,63}$) before constructing the path, and return 400 for anything else. The eight shipped mode ids (agent, planner, help-chat, brainstorm, discuss, edit, explore, generate) all match.

Test plan

  • curl http://localhost:<port>/api/chat-modes/agent → 200 with mode config
  • curl http://localhost:<port>/api/chat-modes/..%2F..%2Fpackage → 400 (previously would attempt to read backend/package.json)
  • curl http://localhost:<port>/api/chat-modes/nonexistent → 404
  • curl http://localhost:<port>/api/chat-modes/UPPER → 400

The modeId route parameter was joined into a filesystem path without
validation. Express decodes URL-encoded characters in route params, so
a request like GET /api/chat-modes/..%2F..%2Fsome-file would escape the
prompts directory and read any .json file the backend process can access.

Validate modeId against a strict allowlist regex before constructing the
path; reject anything else with 400.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@sbaker sbaker merged commit a8dd714 into main Apr 19, 2026
6 checks passed
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.

1 participant