Back to skill

Security audit

Oura (API v2)

Security checks for vulnerabilities and agentic risk

Overview

This Oura skill appears intended to fetch and summarize ring data, but it needs review because it directs sensitive health data into predictable temporary files without privacy safeguards.

Review before installing. Use a private, user-owned directory for outputs instead of /tmp, protect OURA_ACCESS_TOKEN like a password, delete raw exports when no longer needed, and set OURA_TZ or --tz explicitly for the user's actual timezone.

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
scripts/oura_fetch_daily.py:81
Finding

Sensitive Oura health data written to a predictable temporary file without restrictive permissions

Content
View full analysis
None: ap = argparse.ArgumentParser() ap.add_argument("--date", required=True, help="today|yesterday|YYYY-MM-DD") ap.add_argument("--out", required=True) ap.add_argument("--tz", default=os.environ.get("OURA_TZ", "Asia/Shanghai")) args = ap.parse_args() token = must_env("OURA_ACCESS_TOKEN") day = resolve_date(args.date, args.tz) start_date, end_date = day_range(day) bundle: Dict[str, Any] = { "requested_date": day, "requested_tz": args.tz, "fetched_at": datetime.utcnow().isoformat() + "Z", "api_base": API_BASE, "endpoints": { "sleep": fetch_collection("/usercollection/sleep", token, start_date, end_date), "readiness": fetch_collection("/usercollection/readiness", token, start_date, end_date), "activity": fetch_collection("/usercollection/daily_activity", token, start_date, end_date), }, } with open(args.out, "w", encoding="utf-8") as f: json.dump(bundle, f, indent=2, sort_keys=True) f.write("\n") ``` ### Technical Analysis The raw bundle contains sensitive sleep, readiness, and activity ...[truncated 2318 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code does match part of the description: it uses an Oura Personal Access Token and fetches Oura v2 usercollection data for sleep, readiness, and activity/daily_activity. However, key declared behaviors are missing. The script simply bundles raw endpoint responses plus metadata into an output file; it does not transform the data into a stable normalized daily JSON shape. It also contains no logic for generating or rendering a short summary message for any chat channel. There are no suspicious undeclared capabilities beyond normal network access to the Oura API and local file output, but the implemented behavior is materially narrower than the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The implemented code is a local normalization utility, not a full Oura data source connector. Its behavior is limited to parsing a raw JSON file, extracting matching daily records from preexisting endpoint data, and emitting a normalized JSON object. The normalization portion aligns with the description, but key declared capabilities—account connection, token-based access, remote data fetching, and chat summary rendering—are absent. Because the declared purpose describes a broader skill whose main workflow includes data acquisition and message rendering, while the supplied code chunk only performs one intermediate transformation step, this is a material description/behavior mismatch.

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 · SKILL.md (reported line 3)May include surrounding context.

md
---
name: openclaw-oura
description: Oura Ring data source for OpenClaw (Tier 1). Use to connect an Oura account using an Oura Personal Access Token, fetch Oura v2 usercollection data (sleep, readiness, activity), normalize it into a stable daily JSON shape for the Wellness hub, and render a short summary message for any chat channel.
---

# Oura (Personal Access Token)

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 · SKILL.md (reported line 6)May include surrounding context.

md
---
name: openclaw-oura
description: Oura Ring data source for OpenClaw (Tier 1). Use to connect an Oura account using an Oura Personal Access Token, fetch Oura v2 usercollection data (sleep, readiness, activity), normalize it into a stable daily JSON shape for the Wellness hub, and render a short summary message for any chat channel.
---

# Oura (Personal Access Token)

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 · references/oura_api.md (reported line 7)May include surrounding context.

md
---
name: openclaw-oura
description: Oura Ring data source for OpenClaw (Tier 1). Use to connect an Oura account using an Oura Personal Access Token, fetch Oura v2 usercollection data (sleep, readiness, activity), normalize it into a stable daily JSON shape for the Wellness hub, and render a short summary message for any chat channel.
---

# Oura (Personal Access Token)

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 · scripts/oura_fetch_daily.py (reported line 4)May include surrounding context.

python
---
name: openclaw-oura
description: Oura Ring data source for OpenClaw (Tier 1). Use to connect an Oura account using an Oura Personal Access Token, fetch Oura v2 usercollection data (sleep, readiness, activity), normalize it into a stable daily JSON shape for the Wellness hub, and render a short summary message for any chat channel.
---

# Oura (Personal Access Token)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documentation indicates capabilities involving environment variables, local file reads/writes, and network access, but it does not declare any explicit tool scope or permissions boundaries. That makes the skill harder to review safely and increases the risk of overbroad execution in environments that rely on manifest-declared restrictions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill handles a personal access token and sensitive wellness data, but the documentation lacks an explicit warning about protecting credentials, limiting sharing, and safely storing exported health data. In a health-data context, insufficient guidance materially raises the chance of accidental disclosure of private biometric information or token compromise.

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 · references/oura_api.md (reported line 4)May include surrounding context.

md
ZoneInfo = None  # type: ignore


API_BASE = "https://api.ouraring.com/v2"


def must_env(name: str) -> str:

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 · scripts/oura_fetch_daily.py (reported line 26)May include surrounding context.

python
ZoneInfo = None  # type: ignore


API_BASE = "https://api.ouraring.com/v2"


def must_env(name: str) -> str:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

Defaulting the timezone to Asia/Shanghai without user opt-in can lead to silent data misclassification by day, which is especially relevant for daily wellness summaries. While not a classic security bug, it can create privacy and integrity issues if users act on incorrect dates or aggregate data under the wrong locale assumptions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file documents authentication with a bearer token, which is a credential-sensitive operation. The reference provides the token format but does not warn users to keep the PAT secret, avoid committing it, or avoid exposing it in logs or shared output.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script defaults --tz to Asia/Shanghai, which imposes a specific locale assumption when the user does not explicitly choose one. The policy allows locale constraints when the user is given a choice or the constraint is clearly justified, but no justification is provided here beyond an environment-variable override.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script performs file write operations to the path supplied by --out, including truncating/creating the file and appending a newline. While this is a code file and file writes are safety-relevant under the rule, there is no confirmation prompt, logging/print statement, or inline comment/docstring warning about the write behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.