T09 · Insecure Skill Coding Practices
- Location
scripts/lsp_client.py:433- Finding
Optional Authentication Exposes State-Changing Local HTTP Endpoints
- Content
View full analysis
Vulnerability Details
File Location:
scripts/lsp_client.py:433-440,scripts/lsp_client.py:462-503
Vulnerability Type: Missing authentication for a state-changing service
Risk Level: MediumVulnerable Code
python def _check_auth(self) -> bool: """Validate Bearer token if daemon was started with --token.""" expected = getattr(self.server, "auth_token", None) if expected is None: return True # No token required header = self.headers.get("Authorization", "") if header == f"Bearer {expected}": return True self._respond({"error": "unauthorized"}, 401) return FalseThe unauthenticated access applies to all POST routes, including the shutdown endpoint:
python def do_POST(self): if not self._check_auth(): return client = self.server.lsp_client # type: ignore if not client.is_alive(): self._respond({"error": "Language server is not running"}, 503) return try: body = self._read_body() except Exception: self._respond({"error": "invalid JSON body"}, 400) return try: if self.path == "/goto": result = client.query_goto(body["file"], body["line"], body["col"]) self._respond({"result": result}) elif self.path == "/refs": result = client.query_refs(body["file"], body["line"], body["col"]) self._respond({"result": result}) elif self.path == "/hover": result = client.query_hover(body["file"], body["line"], body["col"]) self._respond({"result": result}) elif self.path == "/diag": result = client.query_diag(body["file"]) self._respond({"result": result}) elif self.path == "/symbols": query = body.get("query", "") result = client.query_symbols(query) self._respond({"r ...[truncated 2552 chars]- Remediation
View remediation
Remediation Suggestions
- Require authentication by default instead of treating a missing token as authorization.
- Generate a cryptographically random token at startup when the operator does not supply one.
- Reject empty or trivially weak tokens.
- Compare bearer tokens with
hmac.compare_digest()to avoid ordinary string-comparison timing differences. - Apply stricter authorization to
/shutdown, such as a separate administrative token or disabling remote shutdown by default. - Validate
Hostand, where applicable,Originheaders to reduce localhost request abuse. - Consider replacing TCP with a Unix-domain socket protected by filesystem permissions on supported platforms.
- Add request rate limits and maximum processing durations to reduce resource-exhaustion attacks.
- Document that unauthenticated mode is unsafe on shared systems rather than presenting it as the ordinary default.
