T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- server.py:123
- Finding
- Unauthenticated State-Changing HTTP Tools with Permissive CORS## Vulnerability Details **File Location**: `server.py:123-127`, `server.py:143-148`, `server.py:177-201`, and `server.py:226` **Vulnerability Type**: Missing authentication and authorization; unrestricted cross-origin access **Risk Level**: High ### Vulnerable Code ```python self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS") self.send_header("Access-Control-Allow-Headers", "Content-Type") self.end_headers() self.wfile.write(body) ``` ```python def do_OPTIONS(self) -> None: """Handle CORS preflight.""" self.send_response(200) self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS") self.send_header("Access-Control-Allow-Headers", "Content-Type") self.end_headers() ``` ```python def do_POST(self) -> None: """Handle POST tool calls: POST /tools/{tool_name}""" path = urllib.parse.urlparse(self.path).path.rstrip("/") if not path.startswith("/tools/"): self.send_json({"error": "Not found"}, 404) return tool_name = path[len("/tools/"):] if tool_name not in TOOL_REGISTRY: self.send_json( { "error": f"Unknown tool: {tool_name}", "available": list(TOOL_REGISTRY.keys()), }, 404, ) return params = self.read_body() tool_fn = TOOL_REGISTRY[tool_name]["fn"] try: result = tool_fn(**params) ``` ```python server = HTTPServer(("localhost", PORT), GitMapHandler) ``` ### Technical Analysis The HTTP service executes tool functions directly from attacker-supplied JSON without authenticating the caller or authorizing the requested operation. The exposed registry includes state-changing operations such as committing changes, deleting branches, pulling data, and pushing change ...[truncated 2272 chars]
- Remediation
- ## Remediation Suggestions - Require authentication for every tool endpoint, using a cryptographically strong bearer token or another local authentication mechanism. - Perform operation-level authorization and restrict destructive tools to explicitly authorized clients. - Replace wildcard CORS with an explicit allowlist of trusted origins. Reject requests with absent or untrusted `Origin` headers where browser access is supported. - Restrict `cwd` to canonical paths beneath explicitly configured repository roots: 1. Resolve the path with `Path.resolve()`. 2. Reject nonexistent paths and symbolic-link escapes. 3. Verify that the resolved path is beneath an approved root. 4. Confirm that the path is a valid GitMap repository. - Add request body size limits, strict JSON validation, and per-tool parameter schemas. - Consider exposing the service through a Unix-domain socket protected by filesystem permissions instead of a TCP port. - Run the server under a dedicated least-privileged account and avoid inheriting credentials that are unnecessary for a given operation. - Disable destructive tools by default and require explicit configuration before enabling push, pull, commit, or branch deletion.
