Back to skill

Security audit

WHOOP Morning

Security checks for vulnerabilities and agentic risk

Overview

This WHOOP integration is mostly purpose-aligned, but it handles sensitive health-account tokens with weak local storage controls and references runtime executables that were not included for review.

Review this before installing if your WHOOP data is sensitive. Use a dedicated WHOOP OAuth app, restrict permissions on ~/.clawdbot/.env and ~/.cache/whoop-morning/tokens.json, avoid sharing backups or logs containing those files, and be aware that the referenced auth/report executables were not present in the reviewed artifact.

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: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.
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 declares required environment secrets and clearly relies on external networked code paths, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization gap where the runtime may grant broader capabilities than reviewers or users expect, especially around environment access and secret handling.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill processes and transmits personal health data such as recovery, sleep, strain, and profile information to WHOOP APIs, but the description does not warn users about this privacy-sensitive behavior. Users may enable or automate the skill without informed consent about what personal data is being sent and stored.

Session Persistence

Medium
Category
Rogue Agent
Content
## Setup

### 1) Create WHOOP OAuth credentials

You already have:
- `WHOOP_CLIENT_ID`
Confidence
90% confidence
Finding
The skill instructs users to store OAuth client secrets and a long-lived refresh token in a local .env file, which creates session persistence and concentrates sensitive credentials in a reusable plaintext location. If that file is exposed through misconfigured permissions, backups, logs, or broader agent access, an attacker could reuse the refresh token to obtain new access tokens and access health data.

External Transmission

Medium
Category
Data Exfiltration
Content
## Notes

- This skill uses WHOOP OAuth2:
  - auth URL: `https://api.prod.whoop.com/oauth/oauth2/auth`
  - token URL: `https://api.prod.whoop.com/oauth/oauth2/token`
- WHOOP rotates refresh tokens; avoid running multiple refreshes in parallel.
- API availability/fields can change; if WHOOP returns 401/400 during token refresh, re-run `whoop-auth`.
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

- This skill uses WHOOP OAuth2:
  - auth URL: `https://api.prod.whoop.com/oauth/oauth2/auth`
  - token URL: `https://api.prod.whoop.com/oauth/oauth2/token`
- WHOOP rotates refresh tokens; avoid running multiple refreshes in parallel.
- API availability/fields can change; if WHOOP returns 401/400 during token refresh, re-run `whoop-auth`.
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
89% confidence
Finding
The code persists OAuth-style token data to a predictable file under the user's home directory without setting restrictive file permissions or providing any disclosure/consent mechanism. If the file is readable by other local users, included in backups, or exposed through misconfigured tooling, an attacker could reuse the access or refresh tokens to access the user's WHOOP account data.

Static analysis

No suspicious patterns detected.