Back to skill

Security audit

Oura Ring

Security checks for vulnerabilities and agentic risk

Overview

The skill has a legitimate Oura health-data purpose, but it asks users to run unpinned third-party code and grant broad access to sensitive biometric data.

Only install this after reviewing or pinning the external oura-cli code you will run. Prefer minimal OAuth scopes for the specific Oura data you need, avoid exposing client secrets in shell history or transcripts, treat all outputs as sensitive health information, and revoke Oura authorization if you no longer need the skill.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:43
Finding
Unpinned Remote Code Is Downloaded and Executed<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 43–57 **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```bash # 1. Clone the repo (one-time) git clone https://github.com/zqchris/oura-cli ~/oura-cli cd ~/oura-cli # 2. Register an Oura API app at: # https://cloud.ouraring.com → My Applications → New Application # - Redirect URI: http://localhost:8080/callback # - Scopes: enable all # 3. Authorize (opens browser; one-time per machine) uv run oauth-authorize.py --client-id <ID> --client-secret <SECRET> # 4. Verify uv run oura-data.py today ``` ### Technical Analysis The Skill instructs users or agents to clone the default branch of an external GitHub repository and immediately execute Python programs from it. The dependency is not pinned to a reviewed commit or immutable release, and the instructions provide no checksum, signature verification, or source-review step. Consequently, the code executed at installation time can differ from the code present when this Skill was audited. The external repository is not included in the audited artifact, so claims concerning its token handling, telemetry, and network behavior cannot be independently verified here. This behavior is best classified as remote payload retrieval and execution rather than an ordinary package dependency issue: the effective executable payload is obtained directly from a mutable remote source after Skill review. The OAuth client secret is also supplied as a command-line argument. Depending on the operating system, shell configuration, and process-monitoring permissions, this value could be exposed through shell history, process listings, diagnostic logs, or Agent transcripts. ### Attack Path 1. An attacker compromises the upstream repository, its maintainer account, or the repository's default branch. 2. The attacker modifies `oauth-authorize.py`, `oura-data.py`, or another file executed by `uv`. 3 ...[truncated 1157 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Vendor the required scripts into the Skill so they can be reviewed together with the Skill. 2. If remote retrieval is unavoidable, pin the repository to a specific reviewed commit hash rather than cloning a mutable default branch. 3. Publish and verify a cryptographic checksum or signed release before any downloaded file is executed. 4. Use a repository and release verification process that checks maintainer signatures and provenance. 5. Review downloaded code before execution and run it in a constrained environment with minimal filesystem and network access. 6. Do not pass the OAuth client secret through a command-line argument. Read it through protected interactive input, an appropriately secured credential store, or a permission-restricted configuration file. 7. Document the exact domains the client needs to contact and block unrelated outbound destinations where practical. 8. Re-audit the pinned external code, particularly token storage, refresh behavior, subprocess use, logging, and outbound network requests. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:47
Finding
OAuth Setup Requests Excessive Access to Sensitive User Data<![CDATA[ ## Vulnerability Details **File Locations**: `SKILL.md`, lines 47–54; `references/api-reference.md`, lines 69–85 **Vulnerability Type**: Excessive OAuth authorization scope **Risk Level**: Medium ### Vulnerable Code From `SKILL.md`: ```bash # 2. Register an Oura API app at: # https://cloud.ouraring.com → My Applications → New Application # - Redirect URI: http://localhost:8080/callback # - Scopes: enable all # 3. Authorize (opens browser; one-time per machine) uv run oauth-authorize.py --client-id <ID> --client-secret <SECRET> ``` From `references/api-reference.md`: ```markdown ## OAuth scopes The skill's `oauth-authorize.py` requests all scopes by default. Reference for completeness: | Scope | Endpoints unlocked | |---|---| | `personal` | `personal_info` | | `email` | email field in user info | | `daily` | all daily summary endpoints | | `heartrate` | `heartrate` | | `workout` | `workout` | | `tag` | `enhanced_tag` | | `session` | `session` | | `spo2` | `daily_spo2` | | `ring_configuration` | `ring_configuration` | | `stress` | `daily_stress` | | `heart_health` | `daily_cardiovascular_age`, `vO2_max` | ``` ### Technical Analysis The setup instructions explicitly tell the user to enable every available OAuth scope, and the reference states that the authorization program requests all scopes by default. This violates least-privilege principles because many supported tasks need only a small subset of those permissions. For example, answering a sleep question does not require access to the user's email, workouts, tagged events, sessions, ring configuration, or cardiovascular-age information. Email access is not required for the Skill's core biometric-analysis functionality. Similarly, personal-information access is only needed when the user explicitly requests age, weight, height, or biological-sex data. The resulting token therefore carries substantially more authority than is necessary for most invocations. Although network acces ...[truncated 1527 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace “Scopes: enable all” with a minimal-scope authorization procedure. 2. Request scopes according to the feature the user intends to use: - Sleep, readiness, and activity operations should receive only the required daily-data permissions. - Heart-rate, workout, SpO2, stress, and heart-health scopes should be optional and enabled only when requested. - `personal` should be requested only for explicit personal-profile queries. - `email` should be omitted by default because it is unnecessary for the declared biometric-analysis workflows. 3. Present a clear explanation of each optional scope before authorization and obtain explicit user consent. 4. Support incremental reauthorization when the user later requests a feature requiring an additional scope. 5. Store tokens using operating-system credential protection or a file with restrictive permissions. 6. Ensure tokens, client secrets, personal information, and health data are never written to logs or Agent memory. 7. Document revocation procedures and advise users to revoke and reauthorize existing all-scope tokens after the least-privilege flow is introduced. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Credential Access

High
Category
Privilege Escalation
Content
## Rate limits

- **5000 requests / 24h** per access token (rolling window)
- **300 requests / 5 min** burst cap
- HTTP `429` on exceed; respect `Retry-After` header
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The trigger scope is overly broad because it includes 'any other biometric' tracked by Oura Ring, which can cause the skill to activate for a wide range of sensitive health-related requests without precise boundaries. In a personal-health context, over-triggering increases the chance of unnecessary retrieval and exposure of highly sensitive biometric data beyond what the user specifically intended.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The example phrases are common conversational questions like 'how did I sleep' or 'should I rest,' which can appear in general wellness conversations that do not necessarily imply consent to access Oura data. In this context, ambiguous triggers risk invoking the skill and pulling sensitive health data when the user may have expected a general discussion rather than data access.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The skill handles highly sensitive personal health data via the Oura API, but the main description does not present a clear, user-facing privacy warning before use. Even though the document later mentions privacy rules, the lack of up-front notice can reduce informed consent and increase the risk of users unintentionally exposing intimate biometric information through routine assistant interactions.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The reference explicitly tells the assistant to go beyond the declared `oura-cli` boundary by suggesting direct `curl` use or extending the CLI for unsupported endpoints. That weakens tool-use constraints and can lead the agent to access additional sensitive health endpoints or perform unsanctioned API interactions outside the reviewed skill behavior.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The documentation states that OAuth authorization requests all scopes by default, including access to sensitive categories such as personal info, stress, SpO2, tags, sessions, and heart-health data. Requesting blanket scopes violates least-privilege principles and increases the blast radius if the token is misused, leaked, or if the assistant accesses data unrelated to the user's request.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The file documents broad access to highly sensitive biometric and health endpoints without instructing the assistant to warn users, obtain explicit consent, or explain privacy implications. In a health-data skill, omission of privacy safeguards makes overcollection and unexpected disclosure more likely, especially when paired with all-scopes-by-default authorization.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The file displays realistic examples of highly sensitive health and biometric outputs immediately at the top, without an upfront privacy warning or minimization guidance. In a skill specifically designed to retrieve personal Oura data, this increases the chance that users or downstream tools will expose sleep, HRV, temperature, stress, and other health information in logged, shared, or screen-visible contexts.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The documentation states that a temperature deviation is 'a strong signal of illness' without adequate qualification, which can encourage the assistant to make medical-style inferences from a noisy wellness metric. In a health-data skill, even soft overclaiming is risky because users may rely on it for recovery or illness decisions despite the data being non-diagnostic.

Static analysis

No suspicious patterns detected.