T05 · Unauthorized Access and Privilege Escalation
- Location
app/main.py:40- Finding
Authentication Is Disabled by Default on Externally Published Task APIs
- Content
View full analysis
None: if not settings.api_token: return if x_doctor_token != settings.api_token: ``` `app/config.py:9-11`: ```python class Settings: env: str = "dev" api_token: str = "" task_store: str = "sqlite" ``` `app/config.py:39`: ```python api_token=os.getenv("OPENCLAW_DOCTOR_API_TOKEN", "").strip(), ``` `docker-compose.yml:5-6`: ```yaml ports: - "8010:8010" ``` ### Technical Analysis The authentication dependency treats an empty API token as an instruction to allow every request. Because the default value is an empty string, all task endpoints are unauthenticated unless an operator explicitly supplies `OPENCLAW_DOCTOR_API_TOKEN`. The Docker Compose port mapping publishes port 8010 on all host interfaces by default, rather than limiting it to loopback. This contradicts the documentation’s implication that the service is available only at `127.0.0.1` and makes the fail-open authentication behavior reachable from other systems whenever host or network firewall rules permit it. The affected endpoints support creating and executing tasks, listing all stored tasks, retrieving individual task records, cancelling tasks, and retrying failed or cancelled tasks. Stored records can include `doctor_id`, clinical queries, case summaries, attachment references, generated results, and error details. ### Attack Path 1. An operator starts the service through Docker Compose without setting `OPENCLAW_DOCTOR_API_TOKEN`. 2. Docker publishes TCP port 8010 on every host interface. 3. An attacker with network access sends `GET /api/tasks` without an `X-Doct ...[truncated 968 chars]- Remediation
View remediation
