Skip to content

fix(http): relax CORP to cross-origin so allow-listed clients can load resources - #165

Merged
dev-fani merged 2 commits into
fanilabs:mainfrom
Sundriveauto:fix/cross-origin-resource-policy
Aug 30, 2026
Merged

fix(http): relax CORP to cross-origin so allow-listed clients can load resources#165
dev-fani merged 2 commits into
fanilabs:mainfrom
Sundriveauto:fix/cross-origin-resource-policy

Conversation

@Sundriveauto

@Sundriveauto Sundriveauto commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Closes #115
Closes #116
Closes #117
Closes #118

Summary

The securityPlugin registers @fastify/helmet with an explicit contentSecurityPolicy override but left every other Helmet directive at its default — including crossOriginResourcePolicy, whose default is same-origin (confirmed for the helmet v7/v8 line that @fastify/helmet@12 wraps).

Cross-Origin-Resource-Policy is enforced by browsers independently of CORS. It governs whether a different origin may load this origin's response at all via a no-CORS-mode request (e.g. <img src>, <script>, fonts). The CORS_ORIGIN allow-list and the CSP override in securityPlugin do nothing about it, so allow-listed cross-origin clients were silently blocked from loading this API's responses in no-CORS mode — for example, an uploaded dispute-evidence image rendered with <img src="..."> pointing at this API.

Change

  • src/shared/http/plugins/security.ts: set crossOriginResourcePolicy: { policy: 'cross-origin' } explicitly, with an explanatory comment. This matches the CORS allow-list intent so cooperating client origins can actually load API resources, while the strict CSP, origin allow-list, and credentials: true restrictions are untouched.
  • docs/SECURITY.md: document the CORP policy and the rationale (independent of CORS enforcement).

Tradeoff

cross-origin weakens CORP's default isolation across all origins. This is intended: the API already restricts cooperating origins via CORS_ORIGIN, and the same-origin default silently breaks no-CORS-mode resource loads those clients depend on. If strict isolation is ever required, evidence/media should be served from a separate static/CDN origin.

Testing

Typecheck could not be run locally because node_modules is not installed in the working checkout. The change is a standard, type-valid helmet option; please run pnpm install && pnpm typecheck to confirm.

Sundriveauto and others added 2 commits August 30, 2026 11:14
…d resources

Helmet's default crossOriginResourcePolicy is `same-origin`, which
browsers enforce independently of CORS. The CORS_ORIGIN allow-list and
Helmet's nested contentSecurityPolicy override did nothing about it,
so allow-listed cross-origin clients were silently blocked from loading
this API's responses (e.g. an evidence image rendered via `<img>`).

Set crossOriginResourcePolicy to `cross-origin`, matching the CORS
allow-list intent, and document the tradeoff in SECURITY.md.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Aug 30, 2026

Copy link
Copy Markdown

@Sundriveauto Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@dev-fani
dev-fani merged commit a2dbe47 into fanilabs:main Aug 30, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment