T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- run.py:5
- Finding
- Unrestricted Target Path Allows Unauthorized Filesystem Modification## Vulnerability Details **File Location**: `run.py`, lines 5-9 **Vulnerability Type**: Unrestricted path resolution and unauthorized file modification **Risk Level**: High ### Vulnerable Code ```python ws=Path("/home/jason/.openclaw/workspace");t=(ws/a.task).resolve() if not Path(a.task).is_absolute() else Path(a.task).resolve() t.exists() or (print(json.dumps({"skill":"AI_AutoTester","status":"error","error":f"Target path not found: {t}"},ensure_ascii=False,indent=2)),sys.exit(1)) (td:=t/"tests").mkdir(parents=True,exist_ok=True) (tf:=td/"test_smoke.py").exists() or tf.write_text('from app.main import app\nfrom fastapi.testclient import TestClient\n\ndef test_root():\n c=TestClient(app)\n r=c.get("/")\n assert r.status_code==200\n',encoding="utf-8") (t/"requirements-test.txt").write_text("pytest==8.3.2\nhttpx==0.27.2\n",encoding="utf-8") ``` ### Technical Analysis The `--task` argument is treated as a filesystem path. Absolute paths are accepted directly, while relative paths are resolved against `/home/jason/.openclaw/workspace`. After resolution, the program does not verify that the resulting path remains inside the intended workspace. Consequently, a relative path containing traversal components such as `../../target`, or an explicitly supplied absolute path, can select any existing directory accessible to the process. The program then: - Creates a `tests` directory. - Creates `tests/test_smoke.py` if it does not already exist. - Unconditionally overwrites `requirements-test.txt`. Calling `Path.resolve()` canonicalizes a path but does not enforce a security boundary. The absence of an allowlist or containment check violates least-privilege principles and permits modifications beyond the documented testing workspace. The `--constraints` option does not mitigate this issue because it is parsed but never consulted before filesystem changes occur. ### Attack Path 1. An attacker or untrusted caller invokes the ...[truncated 1119 chars]
- Remediation
- ## Remediation Suggestions - Reject absolute values for `--task` unless an explicitly authorized administrative mode requires them. - Resolve both the workspace and requested target, then enforce containment: ```python workspace = Path("/home/jason/.openclaw/workspace").resolve() target = (workspace / args.task).resolve() if not target.is_relative_to(workspace): raise ValueError("Target must remain within the configured workspace") ``` - On Python versions without `Path.is_relative_to()`, use a safe containment comparison based on `relative_to()`, handling `ValueError`. - Consider restricting targets to an allowlist of registered project directories. - Verify that the target is a directory rather than merely checking that it exists. - Do not overwrite `requirements-test.txt` unconditionally. Fail safely if it exists, create a uniquely named generated file, or require explicit confirmation. - Require confirmation before modifying project files and clearly report every planned change. - Apply defenses against symlink-based boundary bypasses and revalidate paths immediately before writing where concurrent attackers are in scope. - Honor the supplied constraints before performing any filesystem mutation.
