security: add security headers to all API responses - #227
Crackhead-gsk wants to merge 1 commit into
Conversation
Found during an internal security review. ApiResponse (used by every controller for every JSON response) set only Content-Type and CORS headers, with no X-Content-Type-Options, X-Frame-Options, or Content-Security-Policy. Added a shared SECURITY_HEADERS set applied to success(), error(), exception(), and sendManualResponse(): - X-Content-Type-Options: nosniff - X-Frame-Options: DENY - Content-Security-Policy: default-src 'none' (this is a pure JSON API - it never returns HTML - so a maximally restrictive CSP has no functional impact) - Referrer-Policy: no-referrer (several endpoints put tokens in query strings, e.g. reset-password/upload-signed URLs; this avoids leaking them via the Referer header) Testing: deployed live and confirmed via curl that all four headers are now present on both success and error responses, with the JSON body unchanged (no functional regression). php -l clean.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 2 included reviews per hour; 0 remain after this review. Walkthrough
ChangesAPI Security Headers
Merge Risk: ⚪ Minimal · up to API success, error, exception, and manual responses now include four protective browser-facing headers while preserving JSON bodies and existing CORS behavior. No merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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 |
|
Wrong brach, applied via a .patch |
Summary
Found during an internal security review.
ApiResponse(the single choke point every controller uses to build JSON responses) only setContent-Typeand CORS headers - noX-Content-Type-Options,X-Frame-Options, orContent-Security-Policy.Added a shared
SECURITY_HEADERSset applied tosuccess(),error(),exception(), andsendManualResponse():X-Content-Type-Options: nosniffX-Frame-Options: DENYContent-Security-Policy: default-src 'none'- this is a pure JSON API (confirmed via the earlier audit and by inspection - no controller ever returns HTML), so a maximally restrictive CSP has zero functional impact on legitimate clients.Referrer-Policy: no-referrer- several endpoints put tokens in query strings (e.g.reset-password?token=...,upload-signed?token=...); this avoids leaking them via theRefererheader on any outbound request/navigation.Testing
Deployed live against a running instance and confirmed via
curl -ithat all four headers are present on both success and error responses (e.g.logout,forgot-password), with the JSON response body completely unchanged - no functional regression.php -lclean.Notes
Did not touch the existing
Access-Control-Allow-Origin: *+Access-Control-Allow-Credentials: truecombination flagged in the same audit - that's a separate, more invasive change (needs an actual origin allowlist instead of a wildcard) that deserves its own PR and more careful testing against the real frontend origins, rather than bundling it with this low-risk header addition.Summary by CodeRabbit