You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(security): validate snapshot_tag in create_sandbox + token guards
Turns the two failing tests from the previous commit green and adds
defense-in-depth around adjacent footguns.
## create_sandbox path traversal (HIGH, post-auth)
`POST /v1/sandboxes` previously fed `req.snapshot_tag` straight into
`snapshot_root.join(...)` without validation. `delete_snapshot` and
`branch_sandbox` both call `is_safe_tag`; this handler was an
asymmetric oversight. CI on the prior commit captured the failure
(404 from file-existence oracle, instead of 400 input validation):
test create_sandbox_rejects_unsafe_snapshot_tag_traversal ... FAILED
test create_sandbox_rejects_unsafe_snapshot_tag_chars ... FAILED
Fix: call `is_safe_tag(&req.snapshot_tag)` immediately after the
`n`-range checks, before any filesystem op.
Defense in depth: `read_snapshot_volumes` now also checks `is_safe_tag`
on its tag argument, so a future caller forgetting to validate (or a
state.json reconstructed from a pre-validation registry row) can't
make the daemon dereference an attacker-chosen path.
## K8s placeholder bearer token (HIGH)
The shipped `packaging/k8s/forkd-controller.yaml` ships
`token: REPLACE_ME_WITH_32_BYTES_BASE64`. Users who forget to sed it
get a daemon protected only by a publicly-known token. Fix: daemon
refuses to start if the token begins with `REPLACE_ME` / `CHANGE_ME`
or is under 16 bytes. Validation is extracted to a pure `validate_token`
helper with 5 unit tests.
## boot_wait_secs DoS (LOW)
`POST /v1/snapshots` accepted any u64 for `boot_wait_secs`. A hostile
caller could pass u64::MAX and tie up a daemon worker. Cap at 60 s
(well above largest measured boot wait in our recipes).
## Test plan
- All 4 new tests pass; 21 prior tests untouched
- New `validate_token` unit tests cover empty / REPLACE_ME /
CHANGE_ME / short / realistic
- K8s manifest comment now documents the start-up refusal so the
failure mode is discoverable
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments