T09 · Insecure Skill Coding Practices
- Location
scripts/token.sh:8- Finding
OAuth Access Token Cached Without Restrictive File Permissions
- Content
View full analysis
"$CACHE_FILE" ``` ### Technical Analysis The script stores a Google OAuth bearer token in a plaintext cache file without explicitly applying restrictive permissions to either the cache directory or the token file. The effective permissions therefore depend on the invoking process's `umask`. With a common `022` umask, a newly created directory may receive mode `0755` and a newly created file may receive mode `0644`. In a multi-user environment, this can make the access token readable by other local accounts or processes. The token is reused for up to 50 minutes. According to the Skill documentation, the associated OAuth authorization can cover Gmail, Drive, Docs, Sheets, Slides, Calendar, and Forms. Possession of the bearer token is sufficient to call APIs within its granted scopes; the attacker does not need the original client secret or refresh token while the access token remains valid. The credential-file access itself is necessary for the declared token-refresh functionality. However, storing the resulting access token without enforcing least-privilege filesystem permissions exceeds the minimum safe access required. ### Attack Path 1. A user invokes `scripts/token.sh` to obtain a Google OAuth access token. 2. The script creates the cache directory and writes the token while operating under a permissive `umask`. 3. The cache file is consequently created with permissions that allow another local account or process to read it. 4. A local attacker reads `~/.cache/clawemail/access_token`, or the corresponding path under `XDG_CACHE_HOME`. 5. The attacker supplies the stolen value in an `Authorizatio ...[truncated 837 chars]- Remediation
View remediation
"$tmp_file" mv -f "$tmp_file" "$CACHE_FILE" ``` 4. Before reading an existing cache file, verify that it is a regular file, is owned by the current user, is not a symbolic link, and has no group or other permissions. 5. Consider using an operating-system credential store or keyring instead of a plaintext file. 6. Preserve the short cache lifetime and document how users can delete the cached token and revoke OAuth authorization after suspected exposure. ]]>
