Skip to main content

max / makenotwork

Add S3, CDN, and Stripe domains to CSP connect-src was 'self' only, blocking S3 uploads and Stripe API calls. Added S3_ENDPOINT, CDN_BASE_URL, api.stripe.com to connect-src; js.stripe.com to script-src and frame-src; storage domains to media-src. Also added base-uri and form-action. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-05-10 19:47 UTC
Commit: 2a4d1213bd8ce0358aa8e557b5f6c839382a31a9
Parent: 5a48d23
1 file changed, +20 insertions, -6 deletions
@@ -234,14 +234,28 @@ async fn security_headers_middleware(
234 234 HeaderValue::from_static("DENY"),
235 235 );
236 236 // Build CSP with the configured CDN domain for media-src
237 - let media_src = match state.config.cdn_base_url.as_deref() {
238 - Some(cdn) => format!("media-src 'self' {cdn}"),
239 - None => "media-src 'self'".to_string(),
237 + // Build CSP with storage and payment domains
238 + let s3_origin = std::env::var("S3_ENDPOINT").unwrap_or_default();
239 + let s3_origin = s3_origin.as_str();
240 + let cdn = state.config.cdn_base_url.as_deref().unwrap_or("");
241 + let storage_origins = match (s3_origin.is_empty(), cdn.is_empty()) {
242 + (false, false) => format!(" {s3_origin} {cdn}"),
243 + (false, true) => format!(" {s3_origin}"),
244 + (true, false) => format!(" {cdn}"),
245 + (true, true) => String::new(),
240 246 };
241 247 let csp = format!(
242 - "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; \
243 - img-src 'self' data: https:; font-src 'self'; connect-src 'self'; \
244 - {media_src}; frame-ancestors 'none'"
248 + "default-src 'self'; \
249 + script-src 'self' 'unsafe-inline' https://js.stripe.com; \
250 + style-src 'self' 'unsafe-inline'; \
251 + img-src 'self' data: https:; \
252 + font-src 'self'; \
253 + connect-src 'self' https://api.stripe.com{storage_origins}; \
254 + media-src 'self'{storage_origins}; \
255 + frame-src 'self' https://js.stripe.com; \
256 + base-uri 'self'; \
257 + form-action 'self'; \
258 + frame-ancestors 'none'"
245 259 );
246 260 if let Ok(value) = HeaderValue::from_str(&csp) {
247 261 headers.insert(