This document outlines the security features, best practices, and considerations for the Aviation Intelligence Hub application. This version includes comprehensive security enhancements to protect against common web vulnerabilities.
Location: security.py - InputValidator class
All user inputs are validated and sanitized before processing:
- URL Validation: Strict validation with length limits (max 2048 chars)
- String Sanitization: Trimming, length limits, pattern matching
- Integer Validation: Range checking with configurable min/max values
- Sentiment Filter Validation: Whitelist-based validation
Implementation:
# Example usage in app.py
url = InputValidator.validate_string(data.get("url"), max_length=2048)
page = InputValidator.validate_integer(request.args.get("page"), min_val=1, default=1)Location: security.py - URLValidator class
Prevents the application from being used to probe internal networks:
Protected Against:
- Private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
- Loopback addresses (127.0.0.0/8)
- Link-local addresses (169.254.0.0/16)
- Cloud metadata endpoints (169.254.169.254, metadata.google.internal)
- IPv6 private addresses
Features:
- Domain whitelist support (
ALLOWED_DOMAINS) - Domain blacklist with secure defaults (
BLOCKED_DOMAINS) - Scheme validation (only http:// and https://)
- Port validation (blocks dangerous ports: 22, 23, 3389, 5900, etc.)
- Hostname validation
Configuration:
# .env file
ALLOWED_DOMAINS=example.com,trusted-site.org # Whitelist (optional)
BLOCKED_DOMAINS=internal.company.com,admin.local # Additional blacklistLocation: app.py - Flask-Limiter integration
Prevents abuse through rate limiting on all API endpoints:
| Endpoint | Rate Limit |
|---|---|
/api/ingest |
30 per minute |
/api/feeds/add |
20 per minute |
/api/feeds/refresh |
10 per minute |
/api/emails |
60 per minute |
/api/ai/summarize |
10 per minute |
Configuration:
# .env file
RATE_LIMIT_ENABLED=True
RATE_LIMIT_DEFAULT=60 per minuteDisable for testing (not recommended in production):
RATE_LIMIT_ENABLED=FalseLocation: app.py - Flask-Talisman integration
Implements security headers when not in debug mode:
- Content Security Policy (CSP): Restricts resource loading
- X-Frame-Options: Prevents clickjacking
- X-Content-Type-Options: Prevents MIME sniffing
- Strict-Transport-Security (HSTS): Forces HTTPS (in production)
CSP Configuration:
csp = {
'default-src': "'self'",
'script-src': ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net", ...],
'style-src': ["'self'", "'unsafe-inline'", "https://cdnjs.cloudflare.com"],
'img-src': "'self' data: https:",
'connect-src': "'self'",
}Note: In debug mode, security headers are disabled for easier development. Enable in production.
Location: config.py
Centralized configuration with validation:
- No Hardcoded Secrets: All sensitive values from environment variables
- Configuration Validation: Startup validation prevents misconfigurations
- Security Warnings: Alerts for insecure defaults
Example:
# config.py validates on startup
config.validate() # Raises ValueError if invalidLocation: app.py, config.py
Structured logging for security monitoring:
- Configurable log levels (
LOG_LEVEL=INFO|DEBUG|WARNING|ERROR) - Security event logging (failed validations, blocked requests)
- Request context logging (IP addresses via
get_client_ip())
- Parameterized Queries: All SQL queries use parameterization to prevent SQL injection
- Connection Timeouts: Prevents connection exhaustion
- Thread-safe Connections: Separate connections for background threads
- No Raw SQL: Uses SQLite's parameter substitution
Critical: Never commit secrets to version control!
Default Secrets to Change:
SECRET_KEY- Flask secret key for sessions/CSRFCF_WORKER_TOKEN- Cloudflare Worker authentication token
Generate Secure Values:
# Generate SECRET_KEY
python -c "import secrets; print(secrets.token_hex(32))"
# Generate CF_WORKER_TOKEN
python -c "import secrets; print(secrets.token_urlsafe(32))"Status: ✅ Protected
All database queries use parameterized statements:
# Safe - parameterized
cursor.execute("SELECT * FROM news_items WHERE id = ?", (item_id,))
# Unsafe - NEVER do this
cursor.execute(f"SELECT * FROM news_items WHERE id = {item_id}") # ❌Status: ✅ Protected
- HTML output is escaped using
html.escape() - Flask's Jinja2 templates auto-escape by default
- CSP headers restrict inline scripts (in production)
Status: ✅ Protected
- URL validation before all HTTP requests
- Private IP blocking
- Domain whitelisting/blacklisting
- Port restrictions
Status:
- Rate limiting on all API endpoints
- Request timeouts configured
- Database connection timeouts
- Recommendation: Use a reverse proxy (nginx) with additional rate limiting
Status: ✅ Protected (in production)
- X-Frame-Options header via Flask-Talisman
- Only enabled when
FLASK_DEBUG=False
Status: ✅ Protected
.gitignoreprevents committing secrets- Configuration summary masks sensitive values
- Database files excluded from version control
- Change
SECRET_KEYto a secure random value - Change
CF_WORKER_TOKENto a secure random value - Set
FLASK_ENV=productionandFLASK_DEBUG=False - Enable HTTPS with a reverse proxy (nginx, Caddy, etc.)
- Configure
ALLOWED_DOMAINSif possible (whitelist) - Review and update
BLOCKED_DOMAINSas needed - Set
RATE_LIMIT_ENABLED=True - Configure appropriate rate limits for your use case
- Review and test CSP headers
- Set up log monitoring and alerting
- Ensure
.envfile has restricted permissions:chmod 600 .env - Verify database file permissions:
chmod 600 emails.db - Set up automated backups of
emails.db - Configure firewall rules (allow only ports 80/443)
- Run the application with a non-root user
- Keep dependencies updated:
pip install -U -r requirements.txt
Recommended: Use Gunicorn behind nginx/Caddy with HTTPS
# Install Gunicorn
pip install gunicorn
# Run with 4 workers
gunicorn -w 4 -b 127.0.0.1:5001 app:app
# Nginx reverse proxy configuration
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:5001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Monitor logs for suspicious activity:
# Watch logs in real-time
tail -f /path/to/logs/app.log | grep -i "warning\|error\|security"
# Search for failed validations
grep "validation failed" /path/to/logs/app.log
# Search for rate limit hits
grep "rate limit exceeded" /path/to/logs/app.log- Failed URL validations: May indicate SSRF attempts
- Rate limit exceeded: May indicate DoS attack or abuse
- Configuration validation failures: May indicate misconfiguration
- Database errors: May indicate SQL injection attempts (though protected)
- Unusual request patterns: Spike in requests from single IP
If you suspect a security incident:
- Isolate: Temporarily disable affected endpoints or block suspicious IPs
- Investigate: Review logs, database, and request patterns
- Patch: Update configuration or code as needed
- Monitor: Increase logging verbosity, watch for repeat attempts
- Document: Record incident details for future reference
- No Authentication: All endpoints are public. Consider adding authentication for production.
- In-Memory Rate Limiting: Rate limits reset on app restart. Consider Redis for persistence.
- SQLite Database: Not ideal for high-concurrency. Consider PostgreSQL for production.
- No CAPTCHA: No bot protection beyond rate limiting.
- Session Management: Minimal session security (no session fixation protection).
If you discover a security vulnerability, please:
- Do not open a public GitHub issue
- Email security concerns to: [your-security-email]
- Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We will respond within 48 hours and work with you to address the issue.
Keep the application secure:
# Update Python packages
pip install -U -r requirements.txt
# Check for security vulnerabilities
pip install safety
safety check-
v2.0 (Current): Added comprehensive security features
- Input validation and sanitization
- SSRF protection
- Rate limiting
- Security headers
- Centralized configuration
- Enhanced logging
-
v1.0: Initial version (security vulnerabilities present)