""" Dummy backend for the CVE-2026-48020 PoC. It is a tiny HTTP server that echoes the exact request path it receives and returns a canned secret for the protected paths. This lets us observe what Traefik forwarded after routing + StripPrefix + normalisation. """ from http.server import BaseHTTPRequestHandler, HTTPServer import json # Each path is guarded by the `protected` router in dynamic.yml and must # only ever be reachable after the basicAuth middleware succeeds. PROTECTED = { "/admin": {"secret": "ADMIN_SECRET_REACHED", "role": "administrator"}, "/internal/config": {"secret": "TRAEFIK_LAB_INTERNAL_CONFIG", "scope": "internal"}, "/admin/exec": {"secret": "EXEC_ENDPOINT_REACHED", "note": "conditional RCE primitive"}, } class Handler(BaseHTTPRequestHandler): def log_message(self, fmt, *args): # Keep stdout clean; the PoC client prints the interesting part. return def _json(self, status, obj): body = json.dumps(obj).encode() self.send_response(status) self.send_header("Content-Type", "application/json") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def do_GET(self): # The backend faithfully reflects the (possibly normalised) path # Traefik handed to it. Any "secret" here means an unauthenticated # caller reached a protected resource. if self.path in PROTECTED: payload = dict(PROTECTED[self.path]) payload["seen_path"] = self.path payload["bypassed_auth"] = True self._json(200, payload) else: self._json(404, {"seen_path": self.path, "secret": None}) if __name__ == "__main__": HTTPServer(("0.0.0.0", 9000), Handler).serve_forever()