# Issue Description

> This fix resolves a Content Security Policy (CSP) violation that prevented enhanced citations PDF documents from being displayed in iframe modals.

- Skill: `tools-only/issue-description-9` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/issue-description-9`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/issue-description-9/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-29
- Page: https://skillmd.com/skills/tools-only/issue-description-9

---

# ENHANCED_CITATIONS_CSP_FIX

**Fixed in version:** 0.229.061

## Overview

This fix resolves a Content Security Policy (CSP) violation that prevented enhanced citations PDF documents from being displayed in iframe modals. The issue was caused by the CSP directive `frame-ancestors 'none'` which blocked the PDF endpoints from being embedded in iframes, even when served from the same origin.

## Issue Description

Users reported that enhanced citations PDF modals were not loading, with the browser console showing CSP violations:

```
Refused to frame 'https://simplechatapp-dev-*.azurewebsites.net/api/enhanced_citations/pdf?...' 
because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'none'".
```

### Root Cause Analysis

1. **CSP Policy Too Restrictive**: The `frame-ancestors 'none'` directive prevented ANY page from being embedded in a frame or iframe, including same-origin content
2. **Enhanced Citations Architecture**: Enhanced citations use iframes to display PDF documents via the `/api/enhanced_citations/pdf` endpoint
3. **Same-Origin Blocking**: Even though the PDF content was served from the same origin, the CSP policy blocked the iframe embedding

### Technical Background

Enhanced citations display PDFs using the following approach:
- JavaScript creates an iframe element: `<iframe id="pdfFrame" class="w-100" style="height: 70vh; border: none;">`
- Sets the iframe source to: `/api/enhanced_citations/pdf?doc_id=${docId}&page=${pageNumber}`
- The iframe loads the PDF content served by the Flask route `@app.route("/api/enhanced_citations/pdf")`

## Technical Implementation

### 1. CSP Configuration Update (config.py)

**Before:**
```python
'Content-Security-Policy': (
    "default-src 'self'; "
    "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://code.jquery.com https://stackpath.bootstrapcdn.com; "
    "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com; "
    "img-src 'self' data: https: blob:; "
    "font-src 'self' https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com; "
    "connect-src 'self' https: wss: ws:; "
    "media-src 'self' blob:; "
    "object-src 'none'; "
    "frame-ancestors 'none'; "  # ❌ This blocked iframe embedding
    "base-uri 'self';"
)
```

**After:**
```python
'Content-Security-Policy': (
    "default-src 'self'; "
    "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://code.jquery.com https://stackpath.bootstrapcdn.com; "
    "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com; "
    "img-src 'self' data: https: blob:; "
    "font-src 'self' https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com; "
    "connect-src 'self' https: wss: ws:; "
    "media-src 'self' blob:; "
    "object-src 'none'; "
    "frame-ancestors 'self'; "  # ✅ Now allows same-origin framing
    "base-uri 'self';"
)
```

### 2. Version Update

Updated application version from `0.229.060` to `0.229.061` to track this security fix.

## Security Implications

### Security Maintained

- **Same-Origin Only**: `frame-ancestors 'self'` only allows content to be framed by the same origin
- **No External Framing**: External websites still cannot embed the application's content
- **Enhanced Citations Security**: PDF documents can only be displayed within the application's own interface

### Risk Analysis

- **Low Risk**: Changing from `'none'` to `'self'` maintains the same level of security against clickjacking from external sites
- **Controlled Framing**: Only the application itself can embed its own content in iframes
- **No New Attack Vectors**: This change does not introduce new security vulnerabilities

## Validation and Testing

### 1. Functional Test Implementation

Created comprehensive test suite: `test_enhanced_citations_csp_fix.py`

**Test Coverage:**
- ✅ CSP configuration validation
- ✅ Enhanced citations iframe implementation verification  
- ✅ Security headers application confirmation
- ✅ Version update validation

**Test Results:**
```bash
📊 Test Results: 4/4 tests passed
🎉 All tests passed! Enhanced citations CSP fix is working correctly.

📝 Fix Summary:
   • Changed CSP frame-ancestors from 'none' to 'self'
   • Enhanced citations PDFs can now be embedded in iframes
   • Maintains security by only allowing same-origin framing
   • Version updated to 0.229.061
```

### 2. Browser Testing

**Before Fix:**
- Console Error: `Refused to frame '...' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'none'".`
- PDF modal would not display content
- Enhanced citations fallback to text-only mode

**After Fix:**  
- PDF content loads successfully in iframe modal
- No CSP violations in browser console
- Enhanced citations display PDF documents with page navigation

## Dependencies and Compatibility

### No Breaking Changes

- **Backward Compatible**: All existing functionality continues to work
- **Same Security Level**: Security posture remains equivalent for external threats
- **Enhanced Feature**: Enhanced citations now work as originally intended

### Related Components

- **Enhanced Citations Routes**: `route_enhanced_citations.py` - No changes needed
- **Frontend JavaScript**: `chat-enhanced-citations.js` - No changes needed
- **PDF Modal Implementation**: Works with existing iframe-based architecture

## Deployment Notes

### Configuration Required

No additional configuration required. The CSP change is applied automatically through the `SECURITY_HEADERS` configuration in `config.py`.

### Restart Required

Application restart is required for the CSP header changes to take effect:
```bash
# Restart the Flask application to apply new CSP headers
```

## Related Issues and References

### Fixed Issues

1. **Enhanced Citations PDF Modal Not Loading**: CSP blocked iframe embedding
2. **Console CSP Violations**: Browser security warnings for frame-ancestors policy

### Documentation References

- **Enhanced Citations Architecture**: `/docs/features/ENHANCED_CITATIONS.md` (if exists)
- **Security Headers Documentation**: `/docs/fixes/v0.229.019/COMPREHENSIVE_SECURITY_HEADERS_FIX.md`
- **CSP Best Practices**: [Mozilla CSP Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)

## Future Considerations

### CSP Refinement

Consider implementing CSP in Report-Only mode initially for new directives to monitor for unintended impacts:

```python
# Optional: Add CSP reporting for monitoring
'Content-Security-Policy-Report-Only': '...'
```

### Enhanced Citations Security

Consider additional security measures for enhanced citations:
- Content validation for uploaded documents
- Rate limiting for enhanced citation endpoints
- Audit logging for document access

## Verification Steps

### 1. Confirm CSP Headers

Check that the application sends the correct CSP header:
```bash
curl -I https://your-app.azurewebsites.net/ | grep -i "content-security-policy"
```

Expected output should include: `frame-ancestors 'self'`

### 2. Test Enhanced Citations

1. Enable enhanced citations in admin settings
2. Upload a PDF document
3. Send a message referencing the PDF
4. Click on the enhanced citation to open PDF modal
5. Verify PDF displays correctly without console errors

### 3. Run Functional Tests

```bash
cd functional_tests
python test_enhanced_citations_csp_fix.py
```

All tests should pass with no errors.

---

**Resolution Status**: ✅ **RESOLVED**  
**Impact**: Enhanced citations PDF modals now display correctly  
**Security Impact**: No reduction in security posture  
**Breaking Changes**: None
