T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/quickstart.mjs:65
- Finding
- Credential file is created without explicit restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/quickstart.mjs`, lines 65–67 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: Medium ### Vulnerable Code ```javascript mkdirSync(`${homedir()}/.openclaw/credentials`, { recursive: true }); const creds = { agentId, apiKey: regData.apiKey || regData.api_key, privateKey }; writeFileSync(CREDS_PATH, JSON.stringify(creds, null, 2)); ``` ### Technical Analysis The script stores a bearer API key and an RSA private key in a plaintext JSON file but does not explicitly apply owner-only permissions to either the credentials directory or the file. The resulting permissions depend on the process umask and the permissions of any pre-existing directory or file. On systems with a permissive umask or an improperly configured `~/.openclaw/credentials` directory, other local users may be able to read the credentials. Additionally, `writeFileSync` follows an existing symbolic link. If an attacker with local access can prepare the destination path before the script runs, the write could be redirected to another file accessible to the victim account. ### Attack Path 1. An attacker obtains local access sufficient to inspect or manipulate the victim's credential directory. 2. The attacker either: - waits for the script to create `quack.json` under permissive filesystem permissions; or - places a symbolic link at `~/.openclaw/credentials/quack.json` before registration. 3. The victim runs the quick-start script. 4. The script writes the API key and private key without validating the destination or enforcing owner-only access. 5. The attacker reads the credentials or causes the write to affect the symbolic-link target. 6. The attacker reuses the exposed API key or private key to impersonate the registered agent. ### Impact Assessment Successful exploitation may expose the Quack bearer API key and RSA private key to another local user or compromised process. The attacker could perf ...[truncated 367 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Create the credentials directory with owner-only permissions: ```javascript mkdirSync(credentialsDir, { recursive: true, mode: 0o700 }); ``` - Create the credential file with mode `0o600`. - Use exclusive creation where appropriate to avoid silently overwriting an attacker-prepared file. - Validate the destination with `lstatSync` and reject symbolic links. - Correct permissions on pre-existing directories and files rather than assuming the requested creation mode was applied. - Prefer an atomic write process using a securely created temporary file in the same protected directory, followed by a rename. - Consider using an operating-system credential store instead of a plaintext JSON file. ]]>
