# 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"", b'', 1).replace(b"", b'', 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()