Skip to content

Commit 03b4d80

Browse files
committed
docs: Add path-traversal protection to extras wildcard design
1 parent 304c6a1 commit 03b4d80

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

docs/superpowers/specs/2026-05-22-extras-wildcard-design.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,32 @@ Validation at boot:
9191
extra matches.
9292
- The basePath context registration is unchanged.
9393

94+
## Path-traversal protection
95+
96+
Before any matching, the router validates the decoded request path
97+
(`HttpExchange.getRequestURI().getPath()`, which is already
98+
percent-decoded by the JDK) against these rules:
99+
100+
- No segment equals `.` or `..`.
101+
- No empty segment (no `//` in the path).
102+
- No NUL byte (U+0000) anywhere in the path.
103+
104+
A violation throws `BadRequestException` and the `ExceptionFilter` renders
105+
the standard problem+json 400. The check runs once per request inside the
106+
`ExtrasRouter`, before exact-or-wildcard dispatch, so even handlers that
107+
chose to read the URI cannot see a traversal-laden path.
108+
109+
The same validation does NOT run inside the basePath spec context — spec
110+
paths are matched against an explicit template set, so a `..` segment
111+
simply fails the exact/template match and yields a normal 404. Adding the
112+
400 check there is out of scope (mentioned for clarity, not implemented).
113+
94114
## Error handling
95115

96-
Unchanged. Misses inside the router throw `NotFoundException`, which the
97-
`ExceptionFilter` (still in front of the router) renders as the standard
98-
problem+json 404.
116+
Unchanged for normal misses: a request that passes validation but matches
117+
no extra throws `NotFoundException`, rendered by the `ExceptionFilter` as
118+
problem+json 404. Traversal violations throw `BadRequestException` → 400
119+
(see above).
99120

100121
## Testing
101122

@@ -117,6 +138,8 @@ Tests added under `src/test/java/com/retailsvc/http/`:
117138
- `/schemas/**/openapi.yaml` serves the spec at various depths
118139
- exact extras still work (regression for `ExactUrlMatchingIT` scenarios)
119140
- basePath spec routes still take precedence over extras
141+
- path-traversal: `/files/../etc/passwd`, `/files/%2e%2e/etc/passwd`,
142+
`/files/.`, `/files//x` all return 400
120143

121144
## Out of scope
122145

0 commit comments

Comments
 (0)