From 123d6af430c01a7be127d1e5933cb63a85c4e2d7 Mon Sep 17 00:00:00 2001 From: Keith Smith Date: Fri, 26 Dec 2025 22:29:00 -0700 Subject: [PATCH] Update middleware to ADD security headers for browsers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Middleware now: - Detects mobile app vs browser via User-Agent - Mobile app: Removes frame-blocking headers (allows iframe) - Browsers: Adds CSP and X-Frame-Options headers (security) This ensures: ✓ Browsers get full CSP protection ✓ Mobile app can embed content ✓ No need for django-csp package ✓ All security managed in one place 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- tasks/middleware/mobile_app.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/tasks/middleware/mobile_app.py b/tasks/middleware/mobile_app.py index 890ac08..b7d6586 100644 --- a/tasks/middleware/mobile_app.py +++ b/tasks/middleware/mobile_app.py @@ -26,7 +26,6 @@ class AllowMobileAppFramingMiddleware: user_agent = request.META.get('HTTP_USER_AGENT', '') # Detect Capacitor/Android WebView patterns - # Note: We're being permissive here to catch all mobile app requests is_mobile_app = ( 'wv' in user_agent.lower() or # Android WebView 'CapacitorHttp' in user_agent or @@ -34,19 +33,29 @@ class AllowMobileAppFramingMiddleware: ('KeepItGoing' in user_agent and 'Mobile' in user_agent) ) - # Remove frame-blocking headers for mobile app requests if is_mobile_app: - # Remove X-Frame-Options + # Mobile app: Allow iframe embedding - don't add frame-blocking headers + # Remove any existing frame headers if 'X-Frame-Options' in response: del response['X-Frame-Options'] - - # Remove or modify Content-Security-Policy if 'Content-Security-Policy' in response: - csp = response['Content-Security-Policy'] - # Remove frame-ancestors directive - if 'frame-ancestors' in csp: - # Remove the entire CSP header for simplicity - # In production, you'd want to parse and modify it properly - del response['Content-Security-Policy'] + del response['Content-Security-Policy'] + else: + # Regular browsers: Add security headers for clickjacking protection + if 'X-Frame-Options' not in response: + response['X-Frame-Options'] = 'DENY' + + if 'Content-Security-Policy' not in response: + response['Content-Security-Policy'] = ( + "default-src 'self'; " + "script-src 'self' 'unsafe-inline'; " + "style-src 'self' 'unsafe-inline'; " + "img-src 'self' data: https:; " + "font-src 'self' data:; " + "connect-src 'self'; " + "frame-ancestors 'none'; " + "base-uri 'self'; " + "form-action 'self';" + ) return response