T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/bring-cli.js:26
- Finding
- Plaintext Credential and Session Token Storage Without Enforced Access Controls<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bring-cli.js:26-38, 121-123` **Vulnerability Type**: Plaintext sensitive-data storage **Risk Level**: High ### Vulnerable Code ```javascript function saveConfig(config) { fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2)); } // Token caching to avoid re-login on every command function loadTokenCache() { if (fs.existsSync(TOKEN_FILE)) { try { const cache = JSON.parse(fs.readFileSync(TOKEN_FILE, 'utf8')); // Tokens valid for ~30 days; treat as expired after 7 days for safety if (cache.savedAt && (Date.now() - cache.savedAt) < 7 * 24 * 60 * 60 * 1000) { return cache; } } catch (_) { /* stale cache, ignore */ } } return null; } function saveTokenCache(uuid, bearerToken, refreshToken) { fs.writeFileSync(TOKEN_FILE, JSON.stringify({ uuid, bearerToken, refreshToken, savedAt: Date.now() }, null, 2)); } ``` The password is assigned to the persisted configuration before authentication is tested: ```javascript config.email = args[0]; config.password = args[1]; saveConfig(config); ``` ### Technical Analysis The Skill writes the user's Bring! email address, password, bearer token, and refresh token to plaintext JSON files under `~/.openclaw/bring/`. The file writes do not specify an owner-only mode such as `0600`, and directory creation does not explicitly specify mode `0700`. Effective access therefore depends on the process umask and any pre-existing filesystem permissions. The password is persisted before the login attempt succeeds. Consequently, even a mistyped or invalid password remains on disk. Storing the reusable account password is also unnecessary once a suitable session or refresh-token mechanism is available. Bearer and refresh tokens are authentication secrets. Anyone able to read them may be able to impersonate the user until the tokens expire or are revoked. ### Attack Path 1. The user configures the Skill ...[truncated 1133 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not persist the account password in `config.json`. - Store credentials in an operating-system credential manager or another dedicated secret store. - Prefer a revocable, narrowly scoped session or refresh token over retaining the reusable account password. - Create `~/.openclaw/bring/` with mode `0700`. - Create secret-bearing files with mode `0600`, and verify or repair permissions when existing files are loaded. - Write files atomically using a securely created temporary file followed by a rename. - Persist configuration only after authentication succeeds. - Remove expired token files rather than merely ignoring their contents. - Provide a logout or credential-removal command that deletes cached secrets. - Document the locally persisted data, retention period, and revocation procedure. ]]>
