Repository navigation
Close small security gaps in dev restart, deploy upload, project tokens, and CI ownership - #377
Conversation
e067e85 to
2dbb77b
Compare
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2dbb77bbb6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba9ae09b08
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
This comment has been minimized.
This comment has been minimized.
|
Both fixed:
|
9213a94 to
f97a22b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f97a22b8e8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
5ae3b3b to
ca53624
Compare
The /__void/restarting page navigated to the raw `return` query value, so any site could send the developer to a `javascript:` URL on the dev origin. The server now keeps `return` only when it is a same-origin path and embeds it into the page script with safeJsonStringify; anything else falls back to /. A request url that does not parse also falls back to / instead of failing with a 500. The page POSTs to /__void/restart as soon as it loads, so a link or hidden iframe from another site could restart the dev server. The page is now served only when Sec-Fetch-Site is same-origin, none, or absent, answers 403 otherwise, and is marked no-store. POST /__void/restart answers 403 to cross-site browser requests, judged by Sec-Fetch-Site, or by Origin when the browser omits it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Module names from workerFiles become multipart part names next to the platform's own "metadata" part. The deploy API now rejects names that are empty, absolute, contain backslashes, control characters, or ".", ".." or empty segments, equal "metadata", or lack a module extension the CLI uploads. It also requires the main module to be one of the uploaded modules. The check runs before the deploy is admitted, on both direct and staged deployment inputs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A project token is an HMAC-SHA256 over the project id under the key that also signs login JWTs and OAuth state. A login JWT split into projectId = "header.body" and token = signature therefore verified as a project token at the proxy and at the API's internal project routes. Add isProjectId() next to generateId() (proj_ plus 12 characters of [0-9a-z]) and require it before every project-token HMAC check: the proxy's service-binding auth and receipt verification, and the internal revalidate, resolve-resource, resolve-worker and verify-prerender-build routes. Each rejects a malformed id with its existing invalid-token response. The proxy README documents the check. Test fixtures now use ids in the generated shape. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Browsers send no Fetch Metadata to plain-HTTP LAN origins, so with `void dev --host` any page could open /__void/restarting and its auto-POST carried the dev server's own Origin. The binding-hint toast now navigates with a random per-server token that the restarting page sends back, and POST /__void/restart refuses a missing or wrong token. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Local databases seeded before the generated-shape ids still hold proj_seed1..6 with the same slugs, so setup --force failed on the unique slug and kept the old rows. The seed now deletes those projects and their deployments, builds, domains and resources first. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ca53624 to
db153ea
Compare
Attack surface before this PR
Four small, separate holes. Each one could be used by a web page, a tenant, any signed-up user, or a repo writer.
1. Dev server: script injection from any website
2. Deploy upload: tenant module named
metadataIf Cloudflare read the tenant's part, a tenant could bind another tenant's D1, KV or R2.
3. Project token: any signed-up user could make one
4. CI and release files had no owners
What this PR changes
1. Dev server
2. Deploy upload
3. Project token
"header.body"always has a dot, so a JWT signature can never pass. Every real project id has this form, so no live project is affected.4. Owners
Decisions
void dev --hoston a plain-HTTP LAN address, browsers send noSec-Fetch-Site, and the restarting page's own POST carries the dev origin. The token closes that. The in-browser restart works as before; a hand-madePOST /__void/restart(curl) now gets 403. Restarting from the terminal is unchanged.Left as is on purpose: an empty Worker bundle is still accepted. It breaks only the tenant's own app.
Rollout
No user or app change. Existing tokens and apps keep working.
Testing
vp run checkvp run test --base origin/mainvp lint,vp fmt --check🤖 Generated with Claude Code