# API Headers Testing Scripts This directory contains scripts for testing the security headers and API compatibility of the Ploughshares application. ## Scripts Overview 1. **test_headers.sh** - Tests general HTTP headers for both UI and API endpoints 2. **test_api_curl.sh** - Tests API endpoints with various curl commands and parameters 3. **test_api_headers.sh** - Specifically analyzes security headers for API compatibility ## Usage All scripts accept an optional URL parameter. If not provided, they default to `http://localhost:5005`. ```bash # Test against local development environment ./test_headers.sh # Test against production ./test_headers.sh https://ploughshares.nixc.us ``` ## Security Headers Analysis The scripts check for the following important headers: ### Content Security Policy (CSP) - Ensures `unsafe-inline` and `unsafe-eval` are present for API compatibility - Verifies `connect-src` includes wildcard (*) for API access - Checks critical protections like `object-src: 'none'` and `frame-ancestors: 'none'` ### CORS Headers - `Access-Control-Allow-Origin` - `Access-Control-Allow-Methods` - `Access-Control-Allow-Headers` ### Resource Policies - `Cross-Origin-Resource-Policy` should be `cross-origin` for API endpoints - `Cross-Origin-Resource-Policy` should be `same-origin` for UI endpoints ## Troubleshooting If API requests are failing, check the following: 1. **CSP Issues**: The Content-Security-Policy header must include: - `'unsafe-inline'` and `'unsafe-eval'` in script-src - `*` in connect-src - `data:` and `blob:` in appropriate directives 2. **CORS Issues**: API endpoints must have: - `Access-Control-Allow-Origin: *` (or specific origins) - `Access-Control-Allow-Methods` with appropriate HTTP methods - `Access-Control-Allow-Headers` with at least `Content-Type` and `Authorization` 3. **Resource Policy Issues**: API endpoints should have: - `Cross-Origin-Resource-Policy: cross-origin` ## Current Configuration The current configuration uses a permissive CSP that works for both UI and API routes: ```python 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:", "blob:"], 'font-src': ["'self'", "data:"], 'connect-src': ["'self'", "*"], 'manifest-src': "'self'", 'object-src': "'none'", # Still explicitly disallow objects 'frame-ancestors': "'none'", # Still prevent framing 'base-uri': "'self'", 'form-action': "'self'" } ``` CORS headers are added for API routes in an after_request handler: ```python @app.after_request def add_api_headers(response): if request.path.startswith('/api/'): # Add CORS headers for API routes response.headers['Access-Control-Allow-Origin'] = '*' 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' else: # For UI routes, add additional security headers for header, value in additional_headers.items(): response.headers[header] = value return response ```