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:
parent
b04854a488
commit
20d0c2ff57
@ -62,6 +62,14 @@ async def update_settings(
|
|||||||
"""Update settings."""
|
"""Update settings."""
|
||||||
update_data = settings_update.model_dump(exclude_unset=True)
|
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():
|
for key, value in update_data.items():
|
||||||
setattr(current_settings, key, value)
|
setattr(current_settings, key, value)
|
||||||
|
|
||||||
|
|||||||
@ -100,6 +100,9 @@ server {
|
|||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $forwarded_proto;
|
proxy_set_header X-Forwarded-Proto $forwarded_proto;
|
||||||
proxy_cache_bypass $http_upgrade;
|
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
|
# 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 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 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;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user