Validate Edge extension product config - #631
Conversation
Greptile SummaryThis PR adds upfront config validation to the browser-edge target: a required
Confidence Score: 3/5The change is mostly safe, but the requireProductId regex has a gap that allows '..' as a product ID, causing both Edge API calls to be routed to wrong endpoints via URL normalisation — the exact kind of misconfiguration this PR is trying to prevent. The validation logic correctly rejects blank values and obvious path separators, but '..' passes the regex and silently redirects the upload and submit network calls to incorrect API paths. The gap is in the core validation function introduced by this PR and affects every call to build and ship. The requireProductId function in packages/targets/browser-edge/src/index.ts needs a dot-segment guard, and the test file should add a '..' case to the rejection test. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[build / ship called] --> B[requireProductId]
B -->|blank / whitespace| E1[throw: browser-edge requires productId]
B -->|contains \\ / ? # or control char| E2[throw: productId must be a single URL path segment]
B -->|'.' or '..'| PASS[passes through ⚠️]
B -->|valid| C{dryRun?}
PASS --> C
C -->|yes| D[write edge-package.json plan]
C -->|no - build| F[validate manifest.json → zip → return artifact]
C -->|no - ship| G[OAuth token → PUT upload URL → POST submit URL]
G -->|productId = '..'| H[URL normalises to /v1/submissions/… ⚠️]
D --> Z[return artifact path]
F --> Z
G --> I[return id / url / meta]
Reviews (1): Last reviewed commit: "Validate Edge extension product config" | Re-trigger Greptile |
| function requireProductId(value: string | undefined): string { | ||
| const productId = requireText(value, 'productId'); | ||
| if (/[\\/?#\x00-\x1F\x7F]/.test(productId)) { | ||
| throw new Error('browser-edge productId must be a single URL path segment'); | ||
| } | ||
| return productId; | ||
| } |
There was a problem hiding this comment.
.. bypasses the path-segment guard and traverses the API URL
The regex /[\\/?#\x00-\x1F\x7F]/ does not block . or ... Because fetch parses its URL argument via the WHATWG URL algorithm, a productId of .. causes the upload and submit URLs to be silently normalised: …/v1/products/../submissions/… → …/v1/submissions/…. Both API calls then hit the wrong endpoint and the access token is included in those misdirected requests. Add a dot-segment check after requireText returns, e.g. if (productId === '.' || productId === '..') throw new Error('browser-edge productId must be a single URL path segment');, or switch to an allowlist regex.
| function optionalText(value: string | undefined, name: string): string | undefined { | ||
| if (value === undefined) return undefined; | ||
| const trimmed = requireText(value, name); | ||
| return trimmed; | ||
| } |
There was a problem hiding this comment.
The
optionalText helper stores the requireText return value in a local trimmed variable only to immediately return it. Returning the result directly is equivalent and removes the extra variable.
| function optionalText(value: string | undefined, name: string): string | undefined { | |
| if (value === undefined) return undefined; | |
| const trimmed = requireText(value, name); | |
| return trimmed; | |
| } | |
| function optionalText(value: string | undefined, name: string): string | undefined { | |
| if (value === undefined) return undefined; | |
| return requireText(value, name); | |
| } |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| async build(ctx, config) { | ||
| const productId = requireProductId(config.productId); | ||
| const src = sourceDir(ctx, config); | ||
| const zipPath = packageArtifact(ctx, config); |
There was a problem hiding this comment.
requireProductId called three times per build
build() validates productId on line 68, then packageArtifact validates it again (line 45), and packagePlan validates it a third time (line 49). Threading the already-validated productId into those helpers as a parameter would remove the redundancy.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
10 similar comments
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
|
🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: |
Fixes #630.
Changes:
Validation: