Skip to content

fix(api): download attachments instead of rendering them inline#368

Open
cavidelizade wants to merge 1 commit into
Devlaner:mainfrom
cavidelizade:fix/attachment-disposition
Open

fix(api): download attachments instead of rendering them inline#368
cavidelizade wants to merge 1 commit into
Devlaner:mainfrom
cavidelizade:fix/attachment-disposition

Conversation

@cavidelizade

Copy link
Copy Markdown
Contributor

Summary

Attachment uploads don't validate content-type, and ServeFile streamed every object back with Content-Disposition: inline. A member could upload an HTML file (or an SVG with script) and have it execute on the API origin when another member opened the attachment URL.

Linked issues

Closes #328

Type of change

  • Bug fix (fix:)

Surface

  • API (apps/api/)

What changed

ServeFile now forces Content-Disposition: attachment for the attachments/ prefix, so the browser downloads the file rather than rendering it. The uploads/ prefix (avatars, covers, logos) is validated as images and stays inline.

Test plan

  • go build, go vet, go test ./... green
  • Reasoning: with Content-Disposition: attachment the browser won't render the response in-page regardless of its declared type, which neutralizes the stored-XSS vector

Note

This is the low-risk mitigation. Validating/allow-listing content-type on upload (like the image path does) would be a good follow-up, but forcing download closes the XSS on its own.

AI assistance

  • AI tools were used, tool(s): Claude Code (Opus 4.8), commits carry a Co-Authored-By: trailer

Attachment uploads don't validate content-type, and ServeFile streamed every
object back with Content-Disposition: inline. A member could upload an HTML file
(or an SVG with script) and have it execute on the API origin when another
member opened the attachment URL.

Force Content-Disposition: attachment for the attachments/ prefix so the browser
downloads rather than renders it. The uploads/ prefix (avatars, covers, logos)
is validated as images and stays inline.

Closes Devlaner#328

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cavidelizade
cavidelizade requested a review from a team as a code owner July 16, 2026 21:17
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@cavidelizade, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 43 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ec8b6603-b6ad-4b64-a83a-d32dfabc5c1a

📥 Commits

Reviewing files that changed from the base of the PR and between 61bc903 and 30fea0c.

📒 Files selected for processing (1)
  • apps/api/internal/handler/upload.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Attachments are served inline with an attacker-controlled content-type (stored XSS)

1 participant