fix(workspaces): canonicalize upload content types#59
Conversation
|
Capy auto-review is paused for this organization because the usage-cycle auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews. |
📝 WalkthroughWalkthrough
Workspace File Upload Policy
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/features/workspaces/model/workspace-file/policy.test.ts (2)
11-25: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueTest structure uses two different descriptor sources; consider using the resolved descriptor for stronger coverage.
The test resolves
descriptorfromresolveWorkspaceFileTypeFromHint(line 12) but then asserts withgetWorkspaceUploadFamily("image")(line 20) instead of that descriptor. While both may yield the same family, using the resolved descriptor would more directly test the end-to-end spoofing scenario and prevent hidden regressions if hint resolution ever diverges from family lookup.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/workspaces/model/workspace-file/policy.test.ts` around lines 11 - 25, The spoofed content-type test mixes two descriptor sources, which weakens coverage. Update the assertion in workspace-file policy tests to use the descriptor returned by resolveWorkspaceFileTypeFromHint for resolveWorkspaceFileContentType, instead of calling getWorkspaceUploadFamily("image"), so the test validates the full hint-resolution flow and catches divergences between hint matching and family lookup.
1-44: 🧹 Nitpick | 🔵 TrivialCI pipeline failure is infrastructure-related, not a code defect.
The Vitest cloudflare-pool worker fails due to missing
CLOUDFLARE_API_TOKEN. This is a CI environment configuration issue unrelated to the test logic. Ensure the secret is available in GitHub Actions before merge.#!/bin/bash # Verify CI environment has required secrets gh api repos/:owner/:repo/actions/secrets | jq '.secrets[] | select(.name == "CLOUDFLARE_API_TOKEN")'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/workspaces/model/workspace-file/policy.test.ts` around lines 1 - 44, The failing Vitest run is caused by a missing CI secret rather than a test or policy issue, so no changes are needed in getWorkspaceFileShellExtension, getWorkspaceUploadFamily, resolveWorkspaceFileContentType, or resolveWorkspaceFileTypeFromHint. Update the GitHub Actions environment to provide CLOUDFLARE_API_TOKEN for the cloudflare-pool worker, and verify the secret is available before rerunning the workspace-file policy tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/features/workspaces/model/workspace-file/policy.test.ts`:
- Around line 11-25: The spoofed content-type test mixes two descriptor sources,
which weakens coverage. Update the assertion in workspace-file policy tests to
use the descriptor returned by resolveWorkspaceFileTypeFromHint for
resolveWorkspaceFileContentType, instead of calling
getWorkspaceUploadFamily("image"), so the test validates the full
hint-resolution flow and catches divergences between hint matching and family
lookup.
- Around line 1-44: The failing Vitest run is caused by a missing CI secret
rather than a test or policy issue, so no changes are needed in
getWorkspaceFileShellExtension, getWorkspaceUploadFamily,
resolveWorkspaceFileContentType, or resolveWorkspaceFileTypeFromHint. Update the
GitHub Actions environment to provide CLOUDFLARE_API_TOKEN for the
cloudflare-pool worker, and verify the secret is available before rerunning the
workspace-file policy tests.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5dcc0aab-f3ed-419a-b8a4-78bd8c2deaff
📒 Files selected for processing (2)
src/features/workspaces/model/workspace-file/policy.test.tssrc/features/workspaces/model/workspace-file/policy.ts
💤 Files with no reviewable changes (1)
- src/features/workspaces/model/workspace-file/policy.ts
Greptile SummaryThis PR canonicalizes stored workspace upload content types. The main changes are:
Confidence Score: 5/5The change is narrowly scoped to upload MIME canonicalization and adds focused regression coverage for the spoofed header case. The modified policy behavior matches the intended allowlist-driven storage model, and no review comments were identified for the changed files.
What T-Rex did
Reviews (1): Last reviewed commit: "fix(workspaces): canonicalize upload con..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae68226511
ℹ️ 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".
| } | ||
|
|
||
| return ( | ||
| resolveMatchedUploadFormat(input, input.descriptor)?.mime ?? |
There was a problem hiding this comment.
Stop honoring spoofed allowlisted MIME values
In the upload route, validation accepts either the filename or the multipart MIME and then passes the raw file.type through to this resolver. Because this call still delegates to resolveMatchedUploadFormat, which checks MIME before extension, a client can upload photo.png with Content-Type: image/jpeg and we will store image/jpeg and choose a .jpg shell path based on the header rather than the accepted .png filename. That leaves uploaded MIME choice attacker-controlled among allowlisted values, so the canonicalization does not fully remove spoofed Content-Type persistence.
Useful? React with 👍 / 👎.
ae68226 to
c75c69e
Compare
Motivation
Content-Typevalues for accepted workspace files and ensure stored MIME is canonical and safe.Description
resolveWorkspaceFileContentTypeto ignore the raw uploadedcontentTypeand instead canonicalize the stored MIME via the matched upload allowlist, falling back to the descriptor's canonical MIME orapplication/octet-streaminsrc/features/workspaces/model/workspace-file/policy.ts.src/features/workspaces/model/workspace-file/policy.test.tsthat assert a spoofedinvoice.pngwithContent-Type: text/htmlresolves toimage/png, and that shell extension selection remains aligned with canonical MIME.Testing
resolveWorkspaceFileContentType({ fileName: 'invoice.png', contentType: 'text/html' })returnsimage/png, and it succeeded.vitest(node environment config) forsrc/features/workspaces/model/workspace-file/policy.test.ts, and the new tests passed.vitestpool (Cloudflare remote pool) fails in this environment due towranglerauthentication, andvp checksurfaced unrelated, pre-existing TypeScript errors inscripts/thinkex-bulk-migration.ts(these are not caused by this change).Codex Task
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Canonicalizes stored MIME types for workspace uploads by relying on the allowlisted format and ignoring raw
Content-Type. Prevents stored same-origin XSS and keeps extensions aligned with the canonical MIME.resolveWorkspaceFileContentTypeno longer uses the uploaded header; it selects MIME from the matched upload format or the descriptor fallback.invoice.pngwithtext/htmlresolves toimage/png, and JPEG uploads keep ajpgshell extension.Written for commit c75c69e. Summary will update on new commits.
Summary by CodeRabbit
Bug Fixes
jpgfor JPEG images.Tests