T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/mesh.py:149
- Finding
- Network-Controlled Path Traversal Allows Arbitrary JSON File Writes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mesh.py:149-150, 163-175, 185-199, 243-253` **Vulnerability Type**: Path traversal and unsafe file creation **Risk Level**: High ### Vulnerable Code ```python def peer_path(agent_id: str) -> pathlib.Path: return PEERS_DIR / f"{agent_id}.json" ``` ```python def cmd_receive_contact(args): payload = load_json(pathlib.Path(args.file)) unsigned = {k: v for k, v in payload.items() if k != "signature"} sender = payload.get("from", {}) ok = verify_signature(unsigned, payload.get("signature", ""), sender.get("public_key", "")) result = {"verified": ok, "request_id": payload.get("request_id")} if ok: path = REQ_IN_DIR / f"{payload['request_id']}.json" save_json(path, payload) result["saved"] = str(path) print(json.dumps(result, indent=2)) ``` ```python def cmd_approve_request(args): p = REQ_IN_DIR / f"{args.request_id}.json" if not p.exists(): raise SystemExit("Request not found") payload = load_json(p) sender = payload["from"] peer = { "agent_id": sender["agent_id"], "display_name": sender.get("display_name"), "endpoint": sender.get("endpoint"), "public_key": sender["public_key"], "fingerprint": sender["fingerprint"], "trusted_at": now_iso(), "source_request_id": payload["request_id"], } save_json(peer_path(sender["agent_id"]), peer) ``` ```python def cmd_receive_message(args): payload = load_json(pathlib.Path(args.file)) sender_id = payload.get("from") peer = load_peer(sender_id) unsigned = {k: v for k, v in payload.items() if k != "signature"} ok = verify_signature(unsigned, payload.get("signature", ""), peer["public_key"]) result = {"verified": ok, "message_id": payload.get("message_id")} if ok: path = MSG_IN_DIR / f"{payload['message_id']}.json" save_json(path, payload) result["saved"] = str(path) ``` # ...[truncated 2161 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Validate identifiers before any filesystem operation. For example: - `request_id`: `^req_[A-Fa-f0-9]{32}$` - `message_id`: `^msg_[A-Fa-f0-9]{32}$` - `agent_id`: a conservative allowlist of letters, digits, underscores, and hyphens with a fixed maximum length. - Resolve each destination path and verify that it remains below its intended root using `Path.resolve()` and `Path.relative_to()`. - Apply containment checks to reads, writes, and deletions, including approval and rejection commands. - Create new inbound records exclusively rather than silently overwriting existing files. - Validate that the supplied fingerprint matches the supplied public key before storing a contact request. - Keep the service account restricted to its dedicated state directory wherever operationally possible. ]]>
