5692 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / backend.py PY
"""
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()