Back to skill

Security audit

Ultrahuman (OpenClaw)

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but it handles sensitive health credentials through an unpinned third-party MCP server and under-scoped subprocess environment.

Review before installing. Use a pinned and reviewed Ultrahuman MCP server version, avoid running it in an environment containing unrelated secrets, prefer explicit environment variables over stored local config fallback, and treat both the Ultrahuman token and generated health summaries as sensitive personal data.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:23
Finding

Unpinned Third-Party MCP Server Receives Sensitive Credentials

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 23-43
Vulnerability Type: Unpinned external dependency with access to credentials and health data
Risk Level: Medium

Vulnerable Code

markdown
2) **Ultrahuman MCP server**

Repository:
- https://github.com/Monasterolo21/Ultrahuman-MCP

Build it (example):
- `bun install && bun run build`
- You should end up with an entrypoint like: `dist/main.js`

3) **mcporter config** that defines an MCP server named `ultrahuman`

Example `config/mcporter.json` (adjust path to your built `main.js`):

```json
{
  "mcpServers": {
    "ultrahuman": {
      "transport": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/Ultrahuman-MCP/dist/main.js"],
      "env": {
        "ULTRAHUMAN_AUTH_TOKEN": "${ULTRAHUMAN_AUTH_TOKEN}",
        "ULTRAHUMAN_USER_EMAIL": "${ULTRAHUMAN_USER_EMAIL}"
      }
    }
  }
}
text

### Technical Analysis

The installation instructions direct users to clone and build a third-party GitHub repository without identifying a reviewed commit, immutable release, integrity hash, or signature. The resulting code is then launched as an MCP server and explicitly receives the user's Ultrahuman authentication token and email.

Authentication and network communication with Ultrahuman are necessary for the declared functionality. However, delegating those operations to mutable, unpinned third-party code creates avoidable supply-chain risk. The effective implementation can change after this Skill has been reviewed. Running `bun install` also installs the dependency versions selected by the external project, which may introduce additional unreviewed code.

No evidence in the audited repository proves that the referenced MCP server is malicious. The vulnerability is the absence of controls ensuring that users execute the same dependency version that was reviewed.

### Attack Path

1. An attacker com
...[truncated 1203 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin the MCP server to a specific reviewed commit hash or cryptographically signed release rather than referencing a mutable repository branch.
  2. Document the exact reviewed repository URL, commit, runtime version, and build commands.
  3. Publish and verify an integrity checksum or signature for the built server artifact.
  4. Require a committed dependency lockfile and install dependencies using a frozen-lockfile mode.
  5. Review the MCP server and its transitive dependencies before recommending them to users.
  6. Prefer an official Ultrahuman-maintained client or API integration where available.
  7. Use a narrowly scoped and revocable token, and document token rotation and revocation procedures.
  8. Isolate the MCP server in a restricted container or sandbox with minimal filesystem and network access.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ultrahuman_summary.py:87
Finding

Configurable MCP Subprocess Inherits the Entire Parent Environment

Content
View full analysis

Vulnerability Details

File Location: scripts/ultrahuman_summary.py, lines 87-99; credential-loading context at lines 234-249; invocation at line 262
Vulnerability Type: Excessive environment exposure to a config-selected subprocess
Risk Level: Medium

Vulnerable Code

python
def _mcporter_call(date_str: str, config_path: str) -> Dict[str, Any]:
    config_path = _resolve_mcporter_config(config_path)

    cmd = [
        "mcporter",
        "--config",
        config_path,
        "call",
        "ultrahuman.ultrahuman_metrics",
        f"date={date_str}",
        "--output",
        "json",
    ]

    p = subprocess.run(cmd, capture_output=True, text=True)

The script also imports credentials from the general OpenClaw configuration into the process environment:

python
# Ensure we have creds in env for mcporter substitution.
# Prefer process env; fallback to OpenClaw config env.vars.
if not os.environ.get("ULTRAHUMAN_AUTH_TOKEN") or not os.environ.get("ULTRAHUMAN_USER_EMAIL"):
    cfg_path = os.path.expanduser("~/.openclaw/openclaw.json")
    try:
        with open(cfg_path, "r", encoding="utf-8") as f:
            cfg = json.load(f)
        vars_ = (cfg.get("env") or {}).get("vars") or {}
        if not os.environ.get("ULTRAHUMAN_AUTH_TOKEN") and vars_.get("ULTRAHUMAN_AUTH_TOKEN"):
            os.environ["ULTRAHUMAN_AUTH_TOKEN"] = vars_["ULTRAHUMAN_AUTH_TOKEN"]
        if not os.environ.get("ULTRAHUMAN_USER_EMAIL") and vars_.get("ULTRAHUMAN_USER_EMAIL"):
            os.environ["ULTRAHUMAN_USER_EMAIL"] = vars_["ULTRAHUMAN_USER_EMAIL"]
    except Exception:
        pass

The call is then made without a restricted environment:

python
payload = _mcporter_call(date_str, args.mcporter_config)

Technical Analysis

subprocess.run() inherits the complete parent environment when its env argument is omitted. Consequently, mcporter and ...[truncated 2303 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pass an explicit, minimal environment to subprocess.run():
python
child_env = {
    "PATH": os.environ.get("PATH", ""),
    "ULTRAHUMAN_AUTH_TOKEN": os.environ["ULTRAHUMAN_AUTH_TOKEN"],
    "ULTRAHUMAN_USER_EMAIL": os.environ["ULTRAHUMAN_USER_EMAIL"],
}

p = subprocess.run(
    cmd,
    capture_output=True,
    text=True,
    env=child_env,
    check=False,
)
  1. Include only runtime variables proven necessary for mcporter; do not copy the entire parent environment.
  2. Validate that the selected configuration file is owned by the expected user and is not group- or world-writable.
  3. Restrict the configured MCP command to an expected, pinned executable path and reviewed server artifact.
  4. Warn before accepting configurations outside a trusted workspace directory.
  5. Store Ultrahuman credentials in a dedicated secret provider rather than reading them from a broad application configuration file where feasible.
  6. Run the MCP server in a sandbox with restricted filesystem access and outbound network access limited to required Ultrahuman endpoints.
  7. Avoid including captured subprocess output in exceptions when it may contain credentials or sensitive health information.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill instructs users to run shell commands, read local config files, and consume environment-provided secrets, but it does not declare an explicit tool/permission scope. That creates an avoidable trust gap: an agent or operator cannot easily tell what capabilities the skill expects, which increases the chance of over-broad execution and accidental exposure of credentials or local files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill handles highly sensitive data: personal auth tokens plus health and biometric metrics such as sleep, HRV, RHR, and recovery data. Without explicit privacy and secret-handling guidance, users may store tokens insecurely, log raw health data, or share summaries inappropriately, leading to confidentiality and compliance risks.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ultrahuman_summary.py (reported line 99)May include surrounding context.

python
"json",
    ]

    p = subprocess.run(cmd, capture_output=True, text=True)
    if p.returncode != 0:
        raise RuntimeError(
            f"mcporter failed (exit {p.returncode}).\nSTDOUT:\n{p.stdout}\nSTDERR:\n{p.stderr}"

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script silently reads ~/.openclaw/openclaw.json and loads Ultrahuman credentials into the process environment when they are absent, which broadens access to sensitive secrets beyond explicit user input. For a summary skill, auto-harvesting local credentials is a trust-boundary violation because it accesses stored secrets without clear user consent or disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script loads sensitive credentials from a local OpenClaw config file without explicit notice or opt-in, causing stored secrets to be consumed implicitly during normal execution. This increases the chance of unintended secret use and weakens the user's ability to understand when private authentication material is being accessed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script invokes mcporter to call the Ultrahuman metrics endpoint and then prints a summary derived from personal health data. Although the module docstring explains the purpose for developers, there is no runtime confirmation, warning, or user-facing disclosure before retrieving and displaying sensitive data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The helper function hard-codes Asia/Singapore time for determining today and yesterday, and the CLI help also presents yesterday in that timezone. This imposes a locale-specific behavior without offering the user a choice or requiring explicit opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.