In this activity, you will configure Content Security Policy (CSP) headers to prevent unauthorized scripts from executing.
Scenario:
Your API is returning a webpage that has a Cross-Site Scripting (XSS) bug. We cannot fix the code bug right now, so we must block the attack at the Browser Level.
An attacker is trying to load: <script src="http://evil.com/hack.js">.
Your Task
Update the get_security_headers function:
Add a new key: "Content-Security-Policy".
Set the value to: "default-src 'self'".
This instructs the browser to only trust scripts coming from your own domain.
Why Headers?
Modern security is often about "Defense in Depth". Even if your code has bugs, good headers can prevent the bugs from being exploited.
PYTHON EDITOR (middleware.py)
1
BROWSER CONSOLE SIMULATION
Waiting for server headers...
from js import document, window
import sys
def setup():
loading = document.getElementById("loading")
if loading:
loading.style.display = "none"
setup()
class ConsoleOutput:
def write(self, text):
if text.strip():
log(text.strip(), "normal")
def flush(self):
pass
sys.stdout = ConsoleOutput()
sys.stderr = ConsoleOutput()
def log(message, type="normal"):
console = document.getElementById("console-output")
if type == "clear":
console.innerHTML = ""
return
color = "#ffffff"
if type == "pass": color = "#2ecc71"
if type == "fail": color = "#e74c3c"
if type == "info": color = "#3498db"
if type == "system": color = "#d4d4d4"
safe_message = message.replace("<", "<").replace(">", ">")
console.innerHTML += f'
{safe_message}
'
console.scrollTop = console.scrollHeight
def run_tests(*args):
log("", "clear")
log("[SYSTEM] Inspecting HTTP Headers...", "system")
user_code = document.getElementById("code-editor").value
test_env = {}
window.submissionStatus = "INCOMPLETE / FAILED"
try:
exec(user_code, test_env)
if "get_security_headers" not in test_env:
log("[!] Error: Function 'get_security_headers' not found.", "fail")
return
headers = test_env["get_security_headers"]()
if not isinstance(headers, dict):
log("[!] Error: Function must return a dictionary.", "fail")
return
headers_lower = {k.lower(): v for k, v in headers.items()}
# TEST 1: Check for CSP Key
log("--- TEST 1: Header Presence ---", "system")
if "content-security-policy" not in headers_lower:
log(" -> FAIL: CSP Header missing entirely.", "fail")
log(" [Browser] Script from 'evil.com' executed!", "fail")
window.submissionStatus = "FAILED - Missing CSP"
return
else:
log(" -> PASS: CSP Header found.", "pass")
# TEST 2: Check Value
log("--- TEST 2: Policy Strength ---", "system")
val = headers_lower["content-security-policy"]
if "default-src 'self'" in val:
log(f" -> PASS: Policy '{val}' allows self only.", "pass")
log(" [Browser] Blocked loading resource from 'http://evil.com/hack.js'", "pass")
log(" SUCCESS: Attack Mitigated.", "pass")
window.submissionStatus = "PASSED - Secure"
elif "'none'" in val:
log(" -> PASS: Strict 'none' policy detected.", "pass")
window.submissionStatus = "PASSED - Secure"
else:
log(f" -> FAIL: Policy '{val}' is too weak or incorrect.", "fail")
log(" [Browser] 'evil.com' might still be allowed.", "fail")
window.submissionStatus = "FAILED - Weak Policy"
except Exception as e:
log(f"[!] Runtime Error: {e}", "fail")
window.submissionStatus = "ERROR - Syntax/Runtime"