Fix production site issues with a more permissive CSP policy
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
This commit is contained in:
parent
767df7dc44
commit
7845079307
|
@ -54,19 +54,20 @@ if CSP_CSS_HASH:
|
|||
if CSP_CUSTOM_CSS_HASH:
|
||||
logger.info(f"Using pre-calculated CSP hash for custom CSS: sha256-{CSP_CUSTOM_CSS_HASH}")
|
||||
|
||||
# Define the base CSP for UI routes
|
||||
ui_csp = {
|
||||
'default-src': "'none'", # Deny by default
|
||||
'script-src': ["'self'"] + ([f"'sha256-{CSP_JS_HASH}'"] if CSP_JS_HASH else []),
|
||||
'style-src': ["'self'"] +
|
||||
# Define a more permissive CSP that works for both UI and API routes
|
||||
# This is less secure but ensures compatibility with all clients
|
||||
csp = {
|
||||
'default-src': ["'self'", "'unsafe-inline'", "'unsafe-eval'", "data:", "blob:"],
|
||||
'script-src': ["'self'", "'unsafe-inline'", "'unsafe-eval'"] + ([f"'sha256-{CSP_JS_HASH}'"] if CSP_JS_HASH else []),
|
||||
'style-src': ["'self'", "'unsafe-inline'"] +
|
||||
([f"'sha256-{CSP_CSS_HASH}'"] if CSP_CSS_HASH else []) +
|
||||
([f"'sha256-{CSP_CUSTOM_CSS_HASH}'"] if CSP_CUSTOM_CSS_HASH else []),
|
||||
'img-src': ["'self'", "data:"],
|
||||
'font-src': ["'self'"],
|
||||
'connect-src': "'self'",
|
||||
'img-src': ["'self'", "data:", "blob:"],
|
||||
'font-src': ["'self'", "data:"],
|
||||
'connect-src': ["'self'", "*"],
|
||||
'manifest-src': "'self'",
|
||||
'object-src': "'none'", # Explicitly disallow objects
|
||||
'frame-ancestors': "'none'", # Prevent framing
|
||||
'object-src': "'none'", # Still explicitly disallow objects
|
||||
'frame-ancestors': "'none'", # Still prevent framing
|
||||
'base-uri': "'self'",
|
||||
'form-action': "'self'"
|
||||
}
|
||||
|
@ -75,18 +76,16 @@ ui_csp = {
|
|||
if APP_DOMAIN:
|
||||
logger.info(f"Configuring CSP for domain: {APP_DOMAIN}")
|
||||
# Add domain to connect-src if needed
|
||||
if APP_DOMAIN not in ui_csp['connect-src']:
|
||||
if isinstance(ui_csp['connect-src'], list):
|
||||
ui_csp['connect-src'].append(APP_DOMAIN)
|
||||
else:
|
||||
ui_csp['connect-src'] = [ui_csp['connect-src'], APP_DOMAIN]
|
||||
if APP_DOMAIN not in csp['connect-src']:
|
||||
if isinstance(csp['connect-src'], list):
|
||||
csp['connect-src'].append(APP_DOMAIN)
|
||||
|
||||
# Update form-action to include the domain
|
||||
if isinstance(ui_csp['form-action'], list):
|
||||
if APP_DOMAIN not in ui_csp['form-action']:
|
||||
ui_csp['form-action'].append(APP_DOMAIN)
|
||||
if isinstance(csp['form-action'], list):
|
||||
if APP_DOMAIN not in csp['form-action']:
|
||||
csp['form-action'].append(APP_DOMAIN)
|
||||
else:
|
||||
ui_csp['form-action'] = [ui_csp['form-action'], APP_DOMAIN]
|
||||
csp['form-action'] = [csp['form-action'], APP_DOMAIN]
|
||||
|
||||
# Configure Permissions-Policy (formerly Feature-Policy)
|
||||
# Deny access to all browser features that we don't need
|
||||
|
@ -132,11 +131,10 @@ additional_headers = {
|
|||
'Cross-Origin-Opener-Policy': 'same-origin'
|
||||
}
|
||||
|
||||
# Initialize Talisman with the static CSP configuration
|
||||
# We'll handle API routes separately in the after_request handler
|
||||
# Initialize Talisman with the permissive CSP configuration
|
||||
talisman = Talisman(
|
||||
app,
|
||||
content_security_policy=ui_csp,
|
||||
content_security_policy=csp,
|
||||
content_security_policy_nonce_in=['script-src'],
|
||||
feature_policy=permissions_policy,
|
||||
force_https=force_https,
|
||||
|
@ -151,7 +149,7 @@ talisman = Talisman(
|
|||
session_cookie_http_only=True
|
||||
)
|
||||
|
||||
# Add CORS headers for API routes and handle CSP
|
||||
# Add CORS headers for API routes
|
||||
@app.after_request
|
||||
def add_api_headers(response):
|
||||
if request.path.startswith('/api/'):
|
||||
|
@ -160,10 +158,6 @@ def add_api_headers(response):
|
|||
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
|
||||
response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
|
||||
response.headers['Cross-Origin-Resource-Policy'] = 'cross-origin'
|
||||
|
||||
# Remove CSP for API routes to ensure compatibility with clients
|
||||
if 'Content-Security-Policy' in response.headers:
|
||||
del response.headers['Content-Security-Policy']
|
||||
else:
|
||||
# For UI routes, add additional security headers
|
||||
for header, value in additional_headers.items():
|
||||
|
|
Loading…
Reference in New Issue