Back to skill

Security audit

OpenClaw Health Brief

Security checks for vulnerabilities and agentic risk

Overview

This health-brief skill is mostly purpose-aligned, but it handles long-lived health-account tokens and includes under-scoped credential handling that users should review before installing.

Install only if you are comfortable granting the skill access to sensitive health-provider data and long-lived OAuth refresh tokens. Prefer a narrow 1Password vault or dedicated environment file for only these providers, avoid sourcing a broad gateway.env in cron, and treat ~/.openclaw/secrets/health_tokens.json as a sensitive secret file.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
core/util/secrets.py:30
Finding

OAuth Refresh Token Exposed Through Process Command-Line Arguments

Content
View full analysis
``` Command-line arguments can be exposed through process inspection facilities, endpoint monitoring, audit systems, diagnostic tooling, or crash telemetry. Although the writeback path is opt-in through `OPENCLAW_1P_WRITEBACK=1`, enabling the documented token-management feature creates this exposure whenever a provider rotates its refresh token. Using `subprocess.run` with a list prevents shell injection, but it does not protect secrets placed in process arguments. ### Attack Path 1. The user enables 1Password token writeback by setting `OPENCLAW_1P_WRITEBACK=1`. 2. WHOOP or Withings rotates an OAuth refresh token during an ordinary API refresh. 3. The connector passes the new token to `set_secret`. 4. `set_secret` creates an `op item edit` process whose argument list includes the plaintext refresh token. 5. A local process monitor, audit collector, diagnostic agent, or sufficiently privileged local user records or reads the command-line arguments while the process is running. 6. The captured refresh token is submitted to the corresponding provider's OAuth token endpoint with any additionally required client credentials. 7. If the token remains valid and the other OAuth requirements are met, the attacker obtains an acces ...[truncated 645 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Note
Location
SKILL.md:60
Finding

Scheduled Health Task Imports Unrelated Gateway Credentials

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (38)

Credential Access

High
Category
Privilege Escalation
Confidence
82% confidence
Finding

The README directs users to place client secrets and access/refresh tokens into environment variables and persistent storage. While common, this creates real credential exposure risk because environment variables can leak via shell history, process inspection, crash logs, CI output, or inherited subprocesses, and the skill handles long-lived OAuth refresh tokens that can maintain ongoing access to health data.

Content

Scanner excerpt · README.md (reported line 156)May include surrounding context.

md
4. Store in 1Password (item: `OpenClaw Oura`, fields: `client_id`, `client_secret`) or export as env vars
5. Run `python3 ./bin/health-reauth oura`

> **Note:** Oura deprecated personal access tokens in Dec 2025. OAuth is now required.

### Withings

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description focuses on generating a health brief, but the setup and operation materially involve secret storage, token writeback, and 1Password integration. Understating secret-management behavior is dangerous because users may authorize persistent handling of highly sensitive OAuth credentials and health data without understanding the storage and rotation implications.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description focuses on generating a health brief, but the setup and operation materially involve secret storage, token writeback, and 1Password integration. Understating secret-management behavior is dangerous because users may authorize persistent handling of highly sensitive OAuth credentials and health data without understanding the storage and rotation implications.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill description focuses on generating a health brief, but the setup and operation materially involve secret storage, token writeback, and 1Password integration. Understating secret-management behavior is dangerous because users may authorize persistent handling of highly sensitive OAuth credentials and health data without understanding the storage and rotation implications.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill description focuses on generating a health brief, but the setup and operation materially involve secret storage, token writeback, and 1Password integration. Understating secret-management behavior is dangerous because users may authorize persistent handling of highly sensitive OAuth credentials and health data without understanding the storage and rotation implications.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connectors/oura/__init__.py (reported line 67)May include surrounding context.

python
def _oura_refresh_access_token(refresh_token: str, client_id: str, client_secret: str) -> Dict[str, Any]:
    """Refresh Oura access token.

    Per Oura docs, client_id/client_secret can be supplied either as body params OR via HTTP Basic Auth.
    We prefer Basic Auth because it is the most widely compatible OAuth2 pattern.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connectors/whoop/__init__.py (reported line 69)May include surrounding context.

python
def _oura_refresh_access_token(refresh_token: str, client_id: str, client_secret: str) -> Dict[str, Any]:
    """Refresh Oura access token.

    Per Oura docs, client_id/client_secret can be supplied either as body params OR via HTTP Basic Auth.
    We prefer Basic Auth because it is the most widely compatible OAuth2 pattern.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connectors/whoop/__init__.py (reported line 142)May include surrounding context.

python
def _oura_refresh_access_token(refresh_token: str, client_id: str, client_secret: str) -> Dict[str, Any]:
    """Refresh Oura access token.

    Per Oura docs, client_id/client_secret can be supplied either as body params OR via HTTP Basic Auth.
    We prefer Basic Auth because it is the most widely compatible OAuth2 pattern.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connectors/whoop/__init__.py (reported line 288)May include surrounding context.

python
def _oura_refresh_access_token(refresh_token: str, client_id: str, client_secret: str) -> Dict[str, Any]:
    """Refresh Oura access token.

    Per Oura docs, client_id/client_secret can be supplied either as body params OR via HTTP Basic Auth.
    We prefer Basic Auth because it is the most widely compatible OAuth2 pattern.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connectors/withings/__init__.py (reported line 110)May include surrounding context.

python
def _oura_refresh_access_token(refresh_token: str, client_id: str, client_secret: str) -> Dict[str, Any]:
    """Refresh Oura access token.

    Per Oura docs, client_id/client_secret can be supplied either as body params OR via HTTP Basic Auth.
    We prefer Basic Auth because it is the most widely compatible OAuth2 pattern.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · docs/OURA.md (reported line 9)May include surrounding context.

md
- By default, if credentials are present, performs live API calls; otherwise falls back to samples.

Credentials
Personal access tokens were deprecated (Dec 2025). Use OAuth.

1) Create an Oura API application.
2) Register redirect URI (default used by this repo):

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · docs/WHOOP.md (reported line 7)May include surrounding context.

md
- CLI: `./bin/whoop --date YYYY-MM-DD`
- Auth helper: `./bin/whoop-auth` (prints auth URL; can exchange code for tokens)
- Reads credentials from 1Password item **"OpenClaw Whoop"** (recommended) or env vars.
  - Access token: field `token` or env `WHOOP_ACCESS_TOKEN`
  - Refresh token: field `refresh_token` (back-compat: `refresh_password`) or env `WHOOP_REFRESH_TOKEN`
  - Client creds (for refresh): fields `client_id` / `client_secret` or env `WHOOP_CLIENT_ID` / `WHOOP_CLIENT_SECRET`
- If no access token is available, falls back to sample data.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · docs/1PASSWORD_CONVENTIONS.md (reported line 12)May include surrounding context.

md
- Access token: field `token` or env `WHOOP_ACCESS_TOKEN`
  - Refresh token: field `refresh_token` (back-compat: `refresh_password`) or env `WHOOP_REFRESH_TOKEN`
  - Client creds (for refresh): fields `client_id` / `client_secret` or env `WHOOP_CLIENT_ID` / `WHOOP_CLIENT_SECRET`
- If no access token is available, falls back to sample data.

Credentials
WHOOP uses OAuth 2.0 (authorization code flow).

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · docs/1PASSWORD_CONVENTIONS.md (reported line 21)May include surrounding context.

md
- Access token: field `token` or env `WHOOP_ACCESS_TOKEN`
  - Refresh token: field `refresh_token` (back-compat: `refresh_password`) or env `WHOOP_REFRESH_TOKEN`
  - Client creds (for refresh): fields `client_id` / `client_secret` or env `WHOOP_CLIENT_ID` / `WHOOP_CLIENT_SECRET`
- If no access token is available, falls back to sample data.

Credentials
WHOOP uses OAuth 2.0 (authorization code flow).

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · docs/WHOOP.md (reported line 10)May include surrounding context.

md
- Access token: field `token` or env `WHOOP_ACCESS_TOKEN`
  - Refresh token: field `refresh_token` (back-compat: `refresh_password`) or env `WHOOP_REFRESH_TOKEN`
  - Client creds (for refresh): fields `client_id` / `client_secret` or env `WHOOP_CLIENT_ID` / `WHOOP_CLIENT_SECRET`
- If no access token is available, falls back to sample data.

Credentials
WHOOP uses OAuth 2.0 (authorization code flow).

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · docs/WHOOP.md (reported line 34)May include surrounding context.

md
- Access token: field `token` or env `WHOOP_ACCESS_TOKEN`
  - Refresh token: field `refresh_token` (back-compat: `refresh_password`) or env `WHOOP_REFRESH_TOKEN`
  - Client creds (for refresh): fields `client_id` / `client_secret` or env `WHOOP_CLIENT_ID` / `WHOOP_CLIENT_SECRET`
- If no access token is available, falls back to sample data.

Credentials
WHOOP uses OAuth 2.0 (authorization code flow).

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · docs/WITHINGS.md (reported line 31)May include surrounding context.

md
- Access token: field `token` or env `WHOOP_ACCESS_TOKEN`
  - Refresh token: field `refresh_token` (back-compat: `refresh_password`) or env `WHOOP_REFRESH_TOKEN`
  - Client creds (for refresh): fields `client_id` / `client_secret` or env `WHOOP_CLIENT_ID` / `WHOOP_CLIENT_SECRET`
- If no access token is available, falls back to sample data.

Credentials
WHOOP uses OAuth 2.0 (authorization code flow).

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · docs/WITHINGS.md (reported line 38)May include surrounding context.

md
- Access token: field `token` or env `WHOOP_ACCESS_TOKEN`
  - Refresh token: field `refresh_token` (back-compat: `refresh_password`) or env `WHOOP_REFRESH_TOKEN`
  - Client creds (for refresh): fields `client_id` / `client_secret` or env `WHOOP_CLIENT_ID` / `WHOOP_CLIENT_SECRET`
- If no access token is available, falls back to sample data.

Credentials
WHOOP uses OAuth 2.0 (authorization code flow).

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

The skill is designed to persist OAuth tokens, including refresh tokens, across sessions in both 1Password and a local file. Persistent session material is not inherently malicious, but in this context it increases the blast radius of compromise because stolen refresh tokens can provide durable access to sensitive health-provider APIs without repeated user interaction.

Content

Scanner excerpt · README.md (reported line 34)May include surrounding context.

export OPENCLAW_1P_VAULT="YourVault" # your vault name

text

Create items in your vault (see `docs/1PASSWORD_CONVENTIONS.md` for field details):
- `OpenClaw Whoop` → `client_id`, `client_secret`, `token`, `refresh_token`
- `OpenClaw Oura` → `client_id`, `client_secret`, `token`, `refresh_token`
- `OpenClaw Withings` → `client_id`, `client_secret`, `access_token`, `refresh_token`, `user_id`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly states that OAuth tokens are automatically saved to both 1Password and a local file, and that health output is written to disk, but it does not give a clear privacy warning about the sensitivity of those artifacts. In this skill's context, the stored data includes refresh tokens and personal health metrics, so users may unknowingly leave long-lived credentials and regulated/sensitive personal data on shared systems, backups, or world-readable temp locations.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 104)May include surrounding context.

md
## Token persistence

Refreshed tokens persist to `~/.openclaw/secrets/health_tokens.json` (chmod 600). If a provider rotates your refresh token during a refresh, the new one is saved immediately. You should never need to re-auth unless you revoke access at the provider.

Override location: `OPENCLAW_LOCAL_SECRETS_PATH=/path/to/health_tokens.json`

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill requests or implies capabilities to read environment variables, read/write files, use the network, and run shell commands, but the manifest does not declare any explicit tool scope or permissions boundary. This creates unclear trust boundaries and can enable over-privileged execution, especially since the documented workflow handles secrets, OAuth tokens, and cron-triggered automation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill design intentionally persists long-lived session material and refresh tokens in 1Password and in a local secrets file so automated jobs can continue accessing health accounts. This increases the blast radius of host compromise or secret leakage because an attacker can reuse refresh tokens to maintain access to sensitive health data over time.

Content

Scanner excerpt · SKILL.md (reported line 20)May include surrounding context.

export OPENCLAW_1P_VAULT="Assistant" # or your vault name

text

Create items in your vault with these titles and fields:
- `OpenClaw Whoop` → `client_id`, `client_secret`, `token`, `refresh_token`
- `OpenClaw Oura` → `client_id`, `client_secret`, `token`, `refresh_token`
- `OpenClaw Withings` → `client_id`, `client_secret`, `access_token`, `refresh_token`, `user_id`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users that tokens will be saved to ~/.openclaw/secrets/health_tokens.json automatically, but does not prominently warn that this file contains highly sensitive OAuth credentials tied to health-provider accounts. Silent local persistence increases the risk of credential theft from backups, shared accounts, weak filesystem permissions, or later compromise of the host.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · connectors/whoop/__init__.py (reported line 12)May include surrounding context.

python
from core.util.local_secrets import get_local_secret, set_local_secret

# WHOOP Developer API base URLs
WHOOP_API_V2 = "https://api.prod.whoop.com/developer/v2"
WHOOP_TOKEN_URL = "https://api.prod.whoop.com/oauth/oauth2/token"

Static analysis

No suspicious patterns detected.