mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 18:52:56 +00:00
dev day #65
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
# 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 framing
|
||||
- `Content-Security-Policy` with `frame-ancestors 'none'` - Also blocked framing in CSP
|
||||
|
||||
## Solution Applied
|
||||
|
||||
### Changes Made
|
||||
|
||||
#### 1. **main.go** (Line 109)
|
||||
```diff
|
||||
- c.Writer.Header().Set("X-Frame-Options", "DENY")
|
||||
+ c.Writer.Header().Set("X-Frame-Options", "SAMEORIGIN")
|
||||
```
|
||||
|
||||
#### 2. **internal/middleware/security_headers.go** (Line 15)
|
||||
```diff
|
||||
- c.Header("X-Frame-Options", "DENY")
|
||||
+ c.Header("X-Frame-Options", "SAMEORIGIN")
|
||||
```
|
||||
|
||||
#### 3. **internal/middleware/security_headers.go** (Lines 59, 74)
|
||||
```diff
|
||||
Production CSP:
|
||||
- "frame-ancestors 'none';"
|
||||
+ "frame-ancestors 'self';"
|
||||
|
||||
Development CSP:
|
||||
- "frame-ancestors 'none';"
|
||||
+ "frame-ancestors 'self';"
|
||||
```
|
||||
|
||||
#### 4. **internal/config/config.go** (Line 110)
|
||||
```diff
|
||||
- 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:
|
||||
```bash
|
||||
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
|
||||
1. `main.go`
|
||||
2. `internal/middleware/security_headers.go`
|
||||
3. `internal/config/config.go`
|
||||
|
||||
## Deployment
|
||||
Backend was rebuilt and restarted:
|
||||
```bash
|
||||
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
|
||||
|
||||
## References
|
||||
- [MDN: X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options)
|
||||
- [MDN: CSP frame-ancestors](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)
|
||||
- [OWASP: Clickjacking Defense](https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html)
|
||||
Reference in New Issue
Block a user