28 lines
2.1 KiB
Python
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()
|