Back to skill

Security audit

WHOOP

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent WHOOP integration, but it asks users to keep long-lived health-data access tokens in local plaintext files without adequate protection guidance.

Review this before installing if you are not comfortable storing WHOOP OAuth secrets locally. Use owner-only permissions for ~/.clawdbot/.env and ~/.cache/whoop-morning, confirm the WHOOP app requests only needed scopes, and revoke or rotate the WHOOP authorization if those files may have been exposed.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
lib/tokens.js:15
Finding
OAuth Tokens Persisted Without Restrictive File Permissions## Vulnerability Details **File Location**: `lib/tokens.js:15-18` **Related Documentation**: `SKILL.md:30-35`, `SKILL.md:47` **Vulnerability Type**: Plaintext sensitive data stored with umask-dependent permissions **Risk Level**: Medium ### Vulnerable Code ```js function writeTokens(tokens) { fs.mkdirSync(CACHE_DIR, { recursive: true }); fs.writeFileSync(TOKENS_PATH, JSON.stringify(tokens, null, 2) + '\n'); } ``` The related setup instructions also direct users to store credentials in a plaintext environment file without requiring restrictive permissions: ```markdown 3) Put secrets into `~/.clawdbot/.env`: ```bash WHOOP_CLIENT_ID=... WHOOP_CLIENT_SECRET=... ``` ``` The documentation further states: ```markdown This writes `WHOOP_REFRESH_TOKEN=...` into `~/.clawdbot/.env`. ``` ### Technical Analysis `writeTokens` serializes the complete OAuth token object into `tokens.json`. This object may include a WHOOP access token, refresh token, expiration metadata, and other OAuth response fields. Neither the cache directory nor the token file is created with an explicit restrictive mode. Node.js consequently creates the directory and file according to platform defaults modified by the process umask. For example, a permissive or typical umask may result in a token file readable by users other than its owner. Existing files with insecure permissions are also not corrected. The same concern applies to the documented `~/.clawdbot/.env` storage. It contains the client secret and refresh token, but the instructions do not tell users to create it with mode `0600` or otherwise protect it through a secret manager. Storing OAuth credentials locally is necessary for the declared WHOOP integration, especially because WHOOP rotates refresh tokens. However, making those credentials potentially accessible to unrelated local users exceeds the minimum access required. Only the account running the Skill should be ab ...[truncated 1755 chars]
Remediation
## Remediation Suggestions 1. Create the cache directory with owner-only permissions: ```js fs.mkdirSync(CACHE_DIR, { recursive: true, mode: 0o700 }); fs.chmodSync(CACHE_DIR, 0o700); ``` 2. Write the token file with mode `0600` and correct permissions on existing files: ```js fs.writeFileSync( TOKENS_PATH, JSON.stringify(tokens, null, 2) + '\n', { mode: 0o600 } ); fs.chmodSync(TOKENS_PATH, 0o600); ``` 3. Use atomic replacement to reduce corruption and partial-write risks. Create a temporary file in the protected directory with mode `0600`, flush it, and rename it over the destination. 4. Before replacing existing credential files, verify that the destination is owned by the expected user and is not a symbolic link or unexpected file type. 5. Prefer an operating-system credential store or managed secret service instead of plaintext files where the execution environment supports one. 6. Update `SKILL.md` to require secure environment-file creation, for example: ```bash mkdir -p ~/.clawdbot chmod 700 ~/.clawdbot install -m 600 /dev/null ~/.clawdbot/.env ``` 7. Avoid printing access tokens, refresh tokens, client secrets, or full OAuth responses in command output or logs. 8. Document credential revocation and rotation procedures for users who suspect that either local file was exposed.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill requires access to sensitive environment variables but does not declare an explicit tool scope or permissions boundary. This can lead to overbroad execution in agent environments, making secret access implicit rather than auditable and increasing the chance of unintended exposure or misuse.

Session Persistence

Medium
Category
Rogue Agent
Content
### What the user does (one-time)

1) Create a WHOOP app and get credentials:
- `WHOOP_CLIENT_ID`
- `WHOOP_CLIENT_SECRET`
Confidence
82% confidence
Finding
The skill establishes persistent authentication by obtaining and storing a refresh token with offline access, which enables long-term session reuse. While this is functionally necessary for automation, persistent tokens materially increase risk if stolen because they can be used to mint new access tokens without re-prompting the user.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill instructs users to store OAuth client credentials and a long-lived refresh token in a local .env file without clearly warning that these are sensitive secrets. If that file is readable by other local users, accidentally committed, logged, or exfiltrated by another skill, an attacker could obtain persistent API access to the user's WHOOP account.

External Transmission

Medium
Category
Data Exfiltration
Content
## Notes

- OAuth endpoints:
  - auth: `https://api.prod.whoop.com/oauth/oauth2/auth`
  - token: `https://api.prod.whoop.com/oauth/oauth2/token`
- Requires `offline` scope to receive refresh tokens.
- WHOOP rotates refresh tokens; the newest refresh token must be saved.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## Notes

- OAuth endpoints:
  - auth: `https://api.prod.whoop.com/oauth/oauth2/auth`
  - token: `https://api.prod.whoop.com/oauth/oauth2/token`
- Requires `offline` scope to receive refresh tokens.
- WHOOP rotates refresh tokens; the newest refresh token must be saved.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code persists OAuth-style token material to a predictable file under the user's home directory without setting restrictive file permissions or warning the user that long-lived credentials are being stored locally. If the file is readable by other local users, included in backups, or exposed through other local compromise, an attacker could reuse the tokens to access the user's WHOOP account until expiry or refresh.

Static analysis

No suspicious patterns detected.