T09 · Insecure Skill Coding Practices
Warning
- Location
- golist_cli.py:78
- Finding
- Authorization-Related State Stored Without Restrictive File Permissions<![CDATA[ ## Vulnerability Details **File Location**: `golist_cli.py`, lines 78-94 **Vulnerability Type**: Insecure local storage of authorization-related state **Risk Level**: Medium ### Vulnerable Code ```python def save_state(state: RuntimeState) -> None: state_path = resolve_state_file() state_path.parent.mkdir(parents=True, exist_ok=True) with state_path.open("w", encoding="utf-8") as handle: json.dump( { "device_id": state.device_id, "active_list_id": state.active_list_id, "known_lists": [ { "id": known_list.id, "name": known_list.name, } for known_list in state.known_lists ], }, handle, indent=2, ) ``` ### Technical Analysis The CLI persists its device identifier, active list ID, known list IDs, and list names in `~/.openclaw_golist_state.json` or a path selected through `OPENCLAW_STATE_FILE`. The file is opened without an explicit restrictive permission mode. Its resulting permissions depend on the process umask and could allow other local users or processes to read it. The implementation also does not verify whether the target is a symbolic link, validate ownership, repair insecure permissions on an existing file, or write the state atomically. The device identifier is transmitted in the `X-Device-Id` header on every API request. If the GoList backend uses that identifier as an authentication or authorization identity, disclosure may allow another party to impersonate the device. Even if it is not sufficient for authentication, the state file reveals private list names and identifiers. ### Attack Path 1. A victim invokes a command that calls `ensure_device_id`, causing `save_state` to create or update the state file. 2. The state file is created with permissions derived from the current umask rather th ...[truncated 970 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Create the state file atomically with mode `0600`. - Ensure that a dedicated parent directory is created with mode `0700`. - Validate that the state path is a regular file owned by the current user. - Refuse to follow symbolic links when opening the state file. - Check and repair permissions on existing state files before reading sensitive values. - Write updates to a protected temporary file, flush and synchronize it, and atomically replace the destination. - Do not use a device UUID as the sole authentication secret. Use a revocable, scoped credential issued by the server. - Minimize persisted metadata and document that `OPENCLAW_STATE_FILE` must point to a private location. ]]>
