Phase 8: TypeScript migration, i18n rewrite, Activity Tree, Projects API, Heartbeats
This commit is contained in:
@@ -35,17 +35,26 @@ def safe_resolve(root: Path, requested: str) -> Path:
|
||||
return resolved
|
||||
|
||||
|
||||
def _security_headers(handler):
|
||||
def _security_headers(handler, origin=None):
|
||||
"""Add security headers to every response."""
|
||||
handler.send_header('X-Content-Type-Options', 'nosniff')
|
||||
handler.send_header('X-Frame-Options', 'DENY')
|
||||
handler.send_header('Referrer-Policy', 'same-origin')
|
||||
handler.send_header('Access-Control-Allow-Origin', origin or '*')
|
||||
handler.send_header('Access-Control-Allow-Credentials', 'true' if origin else 'false')
|
||||
handler.send_header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,PATCH,OPTIONS')
|
||||
handler.send_header('Access-Control-Allow-Headers', 'Content-Type,Authorization,X-Requested-With')
|
||||
handler.send_header('Vary', 'Origin')
|
||||
connect_src = "'self'"
|
||||
if origin:
|
||||
connect_src += f" {origin}"
|
||||
handler.send_header(
|
||||
'Content-Security-Policy',
|
||||
"default-src 'self'; "
|
||||
"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; "
|
||||
"style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; "
|
||||
"img-src 'self' data: https: blob:; font-src 'self' data: https://cdn.jsdelivr.net; connect-src 'self'; "
|
||||
"img-src 'self' data: https: blob:; font-src 'self' data: https://cdn.jsdelivr.net; "
|
||||
f"connect-src {connect_src}; "
|
||||
"base-uri 'self'; form-action 'self'"
|
||||
)
|
||||
handler.send_header(
|
||||
@@ -61,7 +70,8 @@ def j(handler, payload, status: int=200) -> None:
|
||||
handler.send_header('Content-Type', 'application/json; charset=utf-8')
|
||||
handler.send_header('Content-Length', str(len(body)))
|
||||
handler.send_header('Cache-Control', 'no-store')
|
||||
_security_headers(handler)
|
||||
origin = handler.headers.get('Origin', None) or handler.headers.get('Referer', '').rsplit('/', 1)[0] if handler.headers.get('Referer', '') else None
|
||||
_security_headers(handler, origin=origin)
|
||||
handler.end_headers()
|
||||
handler.wfile.write(body)
|
||||
|
||||
@@ -73,7 +83,8 @@ def t(handler, payload, status: int=200, content_type: str='text/plain; charset=
|
||||
handler.send_header('Content-Type', content_type)
|
||||
handler.send_header('Content-Length', str(len(body)))
|
||||
handler.send_header('Cache-Control', 'no-store')
|
||||
_security_headers(handler)
|
||||
origin = handler.headers.get('Origin', None) or handler.headers.get('Referer', '').rsplit('/', 1)[0] if handler.headers.get('Referer', '') else None
|
||||
_security_headers(handler, origin=origin)
|
||||
handler.end_headers()
|
||||
handler.wfile.write(body)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user