Fix pentest findings: Cache-Control, SSRF save-time validation, Permissions-Policy

L-01: Add Cache-Control: no-store to all /api/ responses via nginx
L-02: Validate ntfy_server_url against blocked networks at save time
I-03: Add Permissions-Policy header to restrict unused browser APIs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kyle 2026-03-03 17:52:28 +08:00
parent b04854a488
commit 20d0c2ff57
2 changed files with 13 additions and 0 deletions

View File

@ -62,6 +62,14 @@ async def update_settings(
"""Update settings."""
update_data = settings_update.model_dump(exclude_unset=True)
# PT-L02: SSRF-validate ntfy_server_url at save time, not just at dispatch
if "ntfy_server_url" in update_data and update_data["ntfy_server_url"]:
from app.services.ntfy import validate_ntfy_host
try:
validate_ntfy_host(update_data["ntfy_server_url"])
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
for key, value in update_data.items():
setattr(current_settings, key, value)

View File

@ -100,6 +100,9 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_cache_bypass $http_upgrade;
# PT-L01: Prevent browser caching of authenticated API responses
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
}
# SPA fallback - serve index.html for all routes
@ -124,4 +127,6 @@ server {
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com; connect-src 'self';" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# PT-I03: Restrict unnecessary browser APIs
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()" always;
}