security: validate download keys before filesystem access (ai:gpt-5) #50

Closed
opened 2026-05-23 22:08:21 +02:00 by heiko · 0 comments
Owner

Finding from a whole-codebase security review.

Affected code:

  • cmd/once-server/download.go:21 derives key directly from r.URL.Path.
  • cmd/once-server/store/store.go:112-141 passes that key into filesystem joins without validating it as a UUID path segment.
  • cmd/once-server/store/file.go:32-34 opens filepath.Join(dir, name, "meta.json").

Impact:
Download URLs are bearer-token URLs, but the token is not validated before filesystem access. Go's ServeMux redirects literal ../ paths, but encoded path segments such as %2e%2e reach the handler decoded. filepath.Join then cleans those segments and can escape the intended store directory while looking for a meta.json/content pair. Even if exploitation depends on filesystem layout, this is the wrong trust boundary for a public unauthenticated endpoint.

Suggested fix:

  • Reject any download key that is not exactly a UUID string.
  • Reject keys containing path separators, empty segments, . or .. before calling store lookup.
  • Prefer extracting the key as a single URL path segment rather than using strings.TrimPrefix on the full path.
  • Add tests for literal and encoded traversal attempts (../, %2e%2e, %2f) and for valid UUID keys.
Finding from a whole-codebase security review. Affected code: - cmd/once-server/download.go:21 derives `key` directly from `r.URL.Path`. - cmd/once-server/store/store.go:112-141 passes that key into filesystem joins without validating it as a UUID path segment. - cmd/once-server/store/file.go:32-34 opens `filepath.Join(dir, name, "meta.json")`. Impact: Download URLs are bearer-token URLs, but the token is not validated before filesystem access. Go's ServeMux redirects literal `../` paths, but encoded path segments such as `%2e%2e` reach the handler decoded. `filepath.Join` then cleans those segments and can escape the intended store directory while looking for a `meta.json`/`content` pair. Even if exploitation depends on filesystem layout, this is the wrong trust boundary for a public unauthenticated endpoint. Suggested fix: - Reject any download key that is not exactly a UUID string. - Reject keys containing path separators, empty segments, `.` or `..` before calling store lookup. - Prefer extracting the key as a single URL path segment rather than using `strings.TrimPrefix` on the full path. - Add tests for literal and encoded traversal attempts (`../`, `%2e%2e`, `%2f`) and for valid UUID keys.
heiko closed this issue 2026-05-24 20:56:24 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
IUS/once#50
No description provided.