chest-disease / SECURITY.md
GitHub Actions Bot
Clean deploy to HF Space
5e1f929
|
Raw
History Blame Contribute Delete
11.9 kB
# Security Considerations
This document outlines security considerations for the Chest X-Ray Assistant.
## Overview
This is a medical AI application with privacy and security as top priorities. The system processes potentially sensitive medical images and must maintain strict security controls.
## Threat Model
### Primary Concerns
1. **Privacy**: Chest X-ray images may contain protected health information (PHI)
2. **Data Integrity**: Ensure model outputs are not tampered with
3. **Availability**: System must remain operational for users
4. **Authentication**: Prevent unauthorized access to the LLM API
## Data Privacy
### Image Processing
**Current Implementation:**
- Images are processed entirely in memory
- No disk storage of uploaded images
- No logging of image content
- Ephemeral processing only
**Verification:**
```python
# backend/main.py
image_bytes = await image.read() # Read into memory
image_tensor = preprocess_image(image_bytes) # Process
# Image bytes discarded after processing
```
### Data Flow
```
User Upload → In-Memory Processing → Response → Memory Cleared
↓ ↓
Encrypted No persistence
```
### Compliance Considerations
**HIPAA:**
- No PHI is stored
- No data retention
- No transmission to unauthorized parties
- Access logs contain metadata only
**GDPR:**
- No personal data storage
- Data processing limited to request duration
- Right to access is trivial (no data to access)
## API Security
### Environment Variables
All secrets are stored in environment variables:
```bash
# Backend
GROQ_API_KEY=secret
MODEL_PATH=configuration
INFERENCE_DEVICE=configuration
PORT=configuration
# Frontend
NEXT_PUBLIC_API_URL=configuration
```
**Best Practices:**
- Never commit `.env` files to version control
- Rotate API keys regularly
- Use strong, randomly generated keys
- Limit API key permissions
### CORS Configuration
Current configuration allows all origins for development:
```python
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # ⚠️ Configure for production
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
```
**Production Configuration:**
```python
app.add_middleware(
CORSMiddleware,
allow_origins=["https://your-frontend.vercel.app"],
allow_credentials=True,
allow_methods=["POST", "GET"],
allow_headers=["Content-Type", "Authorization"],
)
```
### Rate Limiting
**Current Status:** Not implemented
**Recommendation for Production:**
```python
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@app.post("/api/chat")
@limiter.limit("10/minute")
async def chat():
# ...
```
## Input Validation
### Image Upload Validation
**Current Implementation:**
```python
# Type validation
if not image.content_type or not image.content_type.startswith('image/'):
raise HTTPException(status_code=400)
# Size validation (client-side)
if file.size > 10 * 1024 * 1024:
alert('File too large')
```
**Additional Validation (Recommended):**
```python
# Server-side size limit
MAX_IMAGE_SIZE = 10 * 1024 * 1024 # 10MB
image_bytes = await image.read()
if len(image_bytes) > MAX_IMAGE_SIZE:
raise HTTPException(status_code=413, detail="File too large")
# Image format validation
try:
image = Image.open(io.BytesIO(image_bytes))
image.verify() # Verify it's a valid image
except:
raise HTTPException(status_code=400, detail="Invalid image file")
```
### Message Validation
**Current Implementation:**
```python
# Empty message check
if not message.strip():
raise HTTPException(status_code=400)
```
**Additional Validation (Recommended):**
```python
# Length limit
MAX_MESSAGE_LENGTH = 10000
if len(message) > MAX_MESSAGE_LENGTH:
raise HTTPException(status_code=400, detail="Message too long")
# Content sanitization
import re
# Prevent potential injection attempts
if re.search(r'<script|javascript:', message.lower()):
raise HTTPException(status_code=400)
```
## Output Security
### LLM Prompt Injection Prevention
**Current Implementation:**
- Strict system prompts
- Low temperature (0.3) for deterministic responses
- Explicit constraints on output format
**Additional Measures:**
```python
# Output sanitization
def sanitize_llm_output(text: str) -> str:
# Remove any HTML tags
import re
text = re.sub(r'<[^>]+>', '', text)
# Limit length
return text[:5000]
```
### Response Format Validation
**Current Implementation:**
```python
return JSONResponse({
"response": response,
"has_image_analysis": True,
"conditions": conditions,
})
```
**Security:** JSONResponse automatically handles JSON encoding and prevents injection.
## Authentication & Authorization
### Current Status
**No user authentication required.** This is an educational tool with open access.
### Future Considerations
If authentication is added:
- Use JWT tokens
- Implement rate limiting per user
- Consider OAuth for healthcare professionals
- Log access for audit trails
## Logging & Monitoring
### Current Logging
```python
logger.info(f"Model loaded successfully")
logger.error(f"Inference error: {str(e)}")
```
**What is NOT logged:**
- Image content
- User messages (potential PHI)
- LLM responses
- Detailed error stacks in production
### Security Logging
**Recommended additions:**
```python
import logging
# Security event logging
security_logger = logging.getLogger('security')
security_logger.info(f"Inference request from {client_ip}")
security_logger.warning(f"Invalid image type attempted: {content_type}")
security_logger.error(f"Rate limit exceeded: {client_ip}")
```
## Infrastructure Security
### Vercel (Frontend)
**Built-in Security:**
- Automatic HTTPS
- DDoS protection
- Web Application Firewall (WAF)
- Content Security Policy (CSP) headers
**Additional Headers:**
```json
{
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
},
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
}
]
}
```
### Railway (Backend)
**Built-in Security:**
- Automatic HTTPS
- Container isolation
- Secret management
**Recommendations:**
- Enable railway.toml security settings
- Use private networking if scaling
- Regular dependency updates
## Dependency Security
### Frontend Dependencies
**Current (package.json):**
```json
{
"dependencies": {
"next": "14.0.4",
"react": "18.2.0",
"react-dom": "18.2.0",
"lucide-react": "^0.294.0",
"clsx": "^2.0.0",
"tailwind-merge": "^2.1.0",
"axios": "^1.6.2"
}
}
```
**Maintenance:**
```bash
# Check for vulnerabilities
npm audit
# Update dependencies
npm update
# Fix vulnerabilities
npm audit fix
```
### Backend Dependencies
**Current (requirements.txt):**
```
fastapi==0.104.1
uvicorn[standard]==0.24.0
python-multipart==0.0.6
pydantic==2.5.2
python-dotenv==1.0.0
torch==2.1.1
torchvision==0.16.1
Pillow==10.1.0
numpy==1.26.2
groq==0.4.1
```
**Maintenance:**
```bash
# Check for vulnerabilities
pip check
# Update dependencies
pip install --upgrade -r requirements.txt
# Use a vulnerability scanner
pip install safety
safety check
```
## Model Security
### Model Integrity
**Current Implementation:**
- Model loaded at startup from filesystem
- No runtime model modification
- Eval mode only (no training)
**Recommendations:**
```python
# Verify model checksum
import hashlib
def verify_model_integrity(model_path: str, expected_hash: str) -> bool:
with open(model_path, 'rb') as f:
file_hash = hashlib.sha256(f.read()).hexdigest()
return file_hash == expected_hash
# Check on startup
verify_model_integrity(MODEL_PATH, "expected_sha256_hash")
```
### Model Path Traversal Prevention
**Current Implementation:**
```python
MODEL_PATH = os.getenv("MODEL_PATH", "epoch_001_mAUROC_0.486525.pth")
```
**Security:** No user input in model path, so path traversal is not a concern.
## LLM Security
### Groq API Usage
**Current Implementation:**
```python
client = Groq(api_key=GROQ_API_KEY)
response = client.chat.completions.create(
model="llama-3.3-70b-versatile",
messages=[...],
temperature=0.3,
max_tokens=1000,
)
```
**Security Measures:**
- API key stored in environment variable
- Low temperature (0.3) for deterministic responses
- Strict system prompts
- Max tokens limit to prevent runaway generation
### Prompt Injection Prevention
**System Prompt Controls:**
```python
system_prompt = """
CRITICAL RULES (you must follow all):
1. You are NOT a doctor and do NOT provide medical diagnoses
2. DO NOT claim any condition is definitely present or absent
3. Always emphasize uncertainty
4. Include a clear disclaimer at the end
5. Reference only the conditions provided in the data - do NOT invent or hallucinate other conditions
"""
```
## Deployment Security
### Environment Separation
**Development:**
- Local development environment
- Test API keys
- Debug logging enabled
**Staging:**
- Mirror production configuration
- Separate API keys
- Production-like logging
**Production:**
- Production API keys
- Minimal logging (security events only)
- All security headers enabled
### Secrets Management
**Best Practices:**
1. Never commit secrets to git
2. Use platform secret managers (Vercel/Railway)
3. Rotate secrets regularly
4. Audit secret access
## Incident Response
### Security Incident Categories
1. **Data Breach**: Unauthorized access to user data
2. **DoS Attack**: System unavailable
3. **Compromise**: Malicious code execution
4. **Data Integrity**: Tampered model outputs
### Response Plan
**Detection:**
- Monitor logs for anomalies
- Track error rates
- Monitor API usage
**Containment:**
- Isolate affected systems
- Revoke compromised API keys
- Stop service if necessary
**Eradication:**
- Remove malicious code
- Patch vulnerabilities
- Update compromised credentials
**Recovery:**
- Restore from clean backups
- Restart services
- Monitor for recurrence
## Compliance Checklist
### HIPAA (If applicable)
- [ ] Business Associate Agreement (BAA) with cloud providers
- [ ] Access controls implemented
- [ ] Audit logging enabled
- [ ] Data encryption at rest and in transit
- [ ] PHI handling procedures documented
### GDPR (If applicable)
- [ ] Data minimization (collect only necessary data)
- [ ] Data processing agreements
- [ ] User consent mechanisms
- [ ] Right to erasure (not applicable - no data stored)
- [ ] Data breach notification procedures
### SOC 2 (If applicable)
- [ ] Security policies documented
- [ ] Access controls implemented
- [ ] Monitoring and logging
- [ ] Incident response procedures
- [ ] Regular security assessments
## Regular Security Tasks
### Daily
- Monitor error logs
- Check for unusual API usage
### Weekly
- Review access logs
- Check for dependency updates
### Monthly
- Update dependencies
- Rotate API keys
- Run security scans
### Quarterly
- Full security audit
- Penetration testing
- Compliance review
## Resources
- [OWASP Web Security Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
- [FastAPI Security Documentation](https://fastapi.tiangolo.com/tutorial/security/)
- [Next.js Security Best Practices](https://nextjs.org/docs/app/building-your-application/deploying#security-headers)
- [HIPAA Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/laws-regulations/index.html)
---
**Remember:** Security is an ongoing process, not a one-time setup. Regularly review and update security measures.