mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-03 18:22:57 +00:00
4.8 KiB
4.8 KiB
Security Headers Fix for PDF and File Previews
Problem
PDF previews and embedded content were failing with the error:
Refused to display 'http://localhost:8080/' in a frame because it set 'X-Frame-Options' to 'deny'.
This was preventing:
- PDF file previews in iframes
- Document previews
- Any embedded same-origin content
Root Cause
The security headers were set too restrictively:
X-Frame-Options: DENY- Completely blocked all framingContent-Security-Policywithframe-ancestors 'none'- Also blocked framing in CSP
Solution Applied
Changes Made
1. main.go (Line 109)
- c.Writer.Header().Set("X-Frame-Options", "DENY")
+ c.Writer.Header().Set("X-Frame-Options", "SAMEORIGIN")
2. internal/middleware/security_headers.go (Line 15)
- c.Header("X-Frame-Options", "DENY")
+ c.Header("X-Frame-Options", "SAMEORIGIN")
3. internal/middleware/security_headers.go (Lines 59, 74)
Production CSP:
- "frame-ancestors 'none';"
+ "frame-ancestors 'self';"
Development CSP:
- "frame-ancestors 'none';"
+ "frame-ancestors 'self';"
4. internal/config/config.go (Line 110)
- ContentSecurityPolicy: getEnv("CONTENT_SECURITY_POLICY", "default-src 'self' data: blob: https: http:; img-src * data: blob:; style-src 'self' 'unsafe-inline' https: http:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: http:; connect-src *;"),
+ ContentSecurityPolicy: getEnv("CONTENT_SECURITY_POLICY", "default-src 'self' data: blob: https: http:; img-src * data: blob:; style-src 'self' 'unsafe-inline' https: http:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: http:; connect-src *; frame-ancestors 'self';"),
Security Impact
✅ What's Still Protected:
- Clickjacking from external sites: Only same-origin framing is allowed
- XSS attacks: CSP and other headers remain in place
- MIME sniffing: X-Content-Type-Options still set
- HTTPS enforcement: HSTS still active
- All other security measures: Unchanged
✅ What's Now Allowed:
- PDF previews: Can now be embedded in iframes on same domain
- Document previews: Word, Excel, PowerPoint previews work
- Image previews: Enhanced preview capabilities
- Same-origin embedding: Any same-origin content can be framed
🔒 Security Comparison:
| Header | Before | After | Protection Level |
|---|---|---|---|
| X-Frame-Options | DENY | SAMEORIGIN | Still protected against external clickjacking |
| CSP frame-ancestors | 'none' | 'self' | Still protected against external embedding |
Verification
Test the headers are correctly applied:
curl -I http://localhost:8080/api/v1/settings | grep -E "X-Frame-Options|Content-Security-Policy"
Expected output:
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: ...frame-ancestors 'self';
Files Modified
main.gointernal/middleware/security_headers.gointernal/config/config.go
Deployment
Backend was rebuilt and restarted:
docker compose build backend --no-cache
docker compose up -d backend
Testing Checklist
- ✅ PDF files can be previewed in iframes
- ✅ Word documents (.doc, .docx) preview correctly
- ✅ Excel spreadsheets (.xls, .xlsx) preview correctly
- ✅ PowerPoint presentations (.ppt, .pptx) preview correctly
- ✅ Text files (.txt) preview correctly
- ✅ Images still display correctly
- ✅ External sites cannot frame the application
- ✅ Same-origin iframes work correctly
- ✅ YouTube embeds still work
- ✅ All other security headers remain active
Additional Notes
Why SAMEORIGIN?
- DENY: Blocks all framing, including same-origin (too restrictive for previews)
- SAMEORIGIN: Allows same-origin framing but blocks external sites (balanced security)
- ALLOW-FROM: Deprecated and not widely supported
CSP frame-ancestors
- 'none': Blocks all framing (equivalent to X-Frame-Options: DENY)
- 'self': Allows same-origin framing only (equivalent to X-Frame-Options: SAMEORIGIN)
- More modern and flexible than X-Frame-Options
Browser Compatibility
- X-Frame-Options: Supported by all browsers
- CSP frame-ancestors: Supported by all modern browsers, overrides X-Frame-Options when present
Future Enhancements (Optional)
- Implement per-route frame options for even finer control
- Add specific iframe sandbox attributes for enhanced security
- Consider using
<embed>or<object>tags with additional security attributes