hugin/scripts/csp/server.py
2026-10-27 08:33:21 +01:00

28 lines
2.1 KiB
Python

# Testserver für scripts/csp-test.sh: liefert Dateien mit strenger CSP aus und
# schiebt Prüfskripte ein (Zählen von CSP-Verstößen, Klicktest der Aktionen).
import http.server, sys, functools, os
CSP = ("default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; "
"connect-src 'self'; form-action 'self'; frame-ancestors 'none'; base-uri 'self'; object-src 'none'")
TRIAL = b"""window.__csp=[];document.addEventListener('securitypolicyviolation',function(e){
window.__csp.push(e.violatedDirective+' '+(e.sample||'').slice(0,40)+' @'+e.lineNumber);});
window.addEventListener('load',function(){setTimeout(function(){var m=document.createElement('pre');
m.id='csp-result';m.textContent='VIOLATIONS '+window.__csp.length+'\\n'+window.__csp.join('\\n');
document.body.appendChild(m);},500);});"""
class H(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
if self.server.csp: self.send_header("Content-Security-Policy", CSP)
super().end_headers()
def do_GET(self):
if self.path == "/__actions.js":
self.send_response(200); self.send_header("Content-Type","text/javascript"); self.end_headers(); self.wfile.write(open(sys.argv[4],"rb").read()); return
if self.path == "/__probe.js":
self.send_response(200); self.send_header("Content-Type","text/javascript"); self.end_headers(); self.wfile.write(TRIAL); return
if self.path.endswith(".html"):
raw = open(os.path.join(self.server.folder, self.path.lstrip("/")), "rb").read()
raw = raw.replace(b"<head>", b'<head><script src="/__probe.js"></script>', 1).replace(b"</body>", b'<script src="/__actions.js"></script></body>', 1)
self.send_response(200); self.send_header("Content-Type","text/html; charset=utf-8"); self.end_headers(); self.wfile.write(raw); return
super().do_GET()
def log_message(self, *a): pass
folder, port, csp = sys.argv[1], int(sys.argv[2]), sys.argv[3] == "1"
s = http.server.ThreadingHTTPServer(("127.0.0.1", port), functools.partial(H, directory=folder)); s.csp = csp; s.folder = folder
s.serve_forever()