T09 · Insecure Skill Coding Practices
Warning
- Location
- lib/tokens.js:17
- Finding
- OAuth Tokens Stored Without Explicit Restrictive File Permissions## Vulnerability Details **File Location**: `lib/tokens.js`, lines 17-20 **Vulnerability Type**: Plaintext sensitive-token storage with insufficiently enforced filesystem permissions **Risk Level**: Medium ```js function writeTokens(tokens) { fs.mkdirSync(CACHE_DIR, { recursive: true }); fs.writeFileSync(TOKENS_PATH, JSON.stringify(tokens, null, 2) + '\n'); } ``` ### Technical Analysis The `writeTokens` function serializes OAuth token data, potentially including access and refresh tokens, directly into `~/.cache/whoop-morning/tokens.json`. Neither the cache directory nor the token file is created with an explicit restrictive permission mode. Node.js therefore derives the permissions from its defaults and the process umask. The directory is ordinarily based on mode `0777` and the file on mode `0666`, each modified by the active umask. In an environment with an unexpectedly permissive umask, other local users may be able to traverse the directory or read the token file. If the paths already exist, this implementation also does not verify or correct their ownership, permissions, or file type. The file is stored in plaintext. Although plaintext storage may be operationally necessary when an OS credential store is unavailable, explicit access controls are required to restrict token access to the owning account. The documentation also instructs users to store the WHOOP client secret and refresh token in `~/.clawdbot/.env`. Sending OAuth credentials and authorization codes to WHOOP's documented OAuth endpoint is necessary for the declared integration, and no transmission to an unrelated destination was identified. However, the referenced authorization and reporting executables were absent from the supplied project, so their network and credential-handling behavior could not be independently verified. ### Attack Path 1. The skill runs under a process whose umask allows group or global access to newly created files or directori ...[truncated 1235 chars]
- Remediation
- ## Remediation Suggestions - Create the cache directory with mode `0700` and verify that it is owned by the current user. - Create the token file with mode `0600`, and explicitly correct permissions on an existing file with `chmod`. - Reject symbolic links and non-regular files before reading or writing the token cache to reduce link-based attacks. - Write tokens atomically to a securely created temporary file in the same protected directory, set mode `0600`, flush it, and rename it over the destination. - Where available, store refresh tokens in an operating-system credential manager or secret store rather than a plaintext JSON file. - Avoid logging or returning complete token objects, and retain only fields required for authentication and expiration checks. - Document the token-cache location, required permissions, OAuth scopes, revocation procedure, and cleanup process. - Apply equivalent permission hardening to `~/.clawdbot/.env`, which the setup documentation uses for the client secret and refresh token.
