Back to skill

Security audit

CareMax Auth

Security checks for vulnerabilities and agentic risk

Overview

This skill authenticates to a health API but also gives broad medical-data read/write tools and stores or prints tokens in ways users should review before installing.

Install only if you are comfortable with this skill doing more than login: it can use CareMax tokens to read and write health data, upload and OCR medical files, download files, and delete upload sessions. Review the scripts first, avoid custom base URLs except trusted local development endpoints, and treat any command output as sensitive because it may include tokens.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/auth-flow.sh:43
Finding
Remote API responses are interpolated into executable Python source<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auth-flow.sh:43-59`; `scripts/refresh-token.sh:18-34` **Vulnerability Type**: Python source injection through untrusted remote responses **Risk Level**: Critical ### Vulnerable Code `scripts/auth-flow.sh:43-59`: ```bash if echo "$TOKEN_RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); assert 'access_token' in d" 2>/dev/null; then # 保存 credentials mkdir -p "$HOME/.caremax" python3 -c " import json from datetime import datetime, timedelta resp = json.loads('''$TOKEN_RESPONSE''') creds = { 'access_token': resp['access_token'], 'refresh_token': resp['refresh_token'], 'expires_at': (datetime.utcnow() + timedelta(seconds=resp['expires_in'])).isoformat() + 'Z', 'scope': resp['scope'], 'base_url': '$BASE_URL' } json.dump(creds, open('$CREDS_FILE', 'w'), indent=2) print(json.dumps({'status': 'authorized', 'access_token': resp['access_token'], 'base_url': '$BASE_URL'})) " ``` `scripts/refresh-token.sh:18-34`: ```bash if echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); assert 'access_token' in d" 2>/dev/null; then python3 -c " import json from datetime import datetime, timedelta resp = json.loads('''$RESPONSE''') creds = json.load(open('$CREDS_FILE')) creds['access_token'] = resp['access_token'] creds['expires_at'] = (datetime.utcnow() + timedelta(seconds=resp['expires_in'])).isoformat() + 'Z' json.dump(creds, open('$CREDS_FILE', 'w'), indent=2) print(json.dumps({ 'status': 'refreshed', 'access_token': resp['access_token'], 'base_url': creds.get('base_url', 'https://api.caremax.ai') })) " ``` ### Technical Analysis Both scripts retrieve JSON from a remote endpoint and first confirm that the response parses as JSON and contains an `access_token`. They subsequently interpolate the original, untrusted response directly into the source text passed to `python3 -c`. JSON validation does not make this interpolation safe. A valid JS ...[truncated 2276 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Never insert network responses, tokens, URLs, file paths, or other variable data into dynamically generated Python source. Pass the response through standard input: ```bash printf '%s' "$TOKEN_RESPONSE" | python3 -c ' import json import os import sys from datetime import datetime, timedelta, timezone resp = json.load(sys.stdin) required = { "access_token": str, "refresh_token": str, "expires_in": int, "scope": str, } for field, expected_type in required.items(): if not isinstance(resp.get(field), expected_type): raise ValueError(f"Invalid or missing field: {field}") creds = { "access_token": resp["access_token"], "refresh_token": resp["refresh_token"], "expires_at": ( datetime.now(timezone.utc) + timedelta(seconds=resp["expires_in"]) ).isoformat(), "scope": resp["scope"], "base_url": os.environ["CAREMAX_BASE_URL"], } # Write credentials safely here. ' ``` Apply the same pattern to `refresh-token.sh`. Pass the credential path and base URL through validated command-line arguments or environment variables rather than embedding them in Python code. Additional hardening should include: - Validate the complete response schema and field types. - Reject unexpected response sizes and malformed token fields. - Restrict custom endpoints as described in the separate endpoint-trust finding. - Add regression tests containing apostrophes, triple quotes, newlines, and Python-like text in every server-controlled field. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auth-flow.sh:44
Finding
OAuth credentials are stored without explicit restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auth-flow.sh:44-57` **Vulnerability Type**: Insecure local secret storage **Risk Level**: High ### Vulnerable Code ```bash # 保存 credentials mkdir -p "$HOME/.caremax" python3 -c " import json from datetime import datetime, timedelta resp = json.loads('''$TOKEN_RESPONSE''') creds = { 'access_token': resp['access_token'], 'refresh_token': resp['refresh_token'], 'expires_at': (datetime.utcnow() + timedelta(seconds=resp['expires_in'])).isoformat() + 'Z', 'scope': resp['scope'], 'base_url': '$BASE_URL' } json.dump(creds, open('$CREDS_FILE', 'w'), indent=2) ``` ### Technical Analysis The script creates `~/.caremax` and writes `credentials.json` without setting a restrictive `umask` or explicit filesystem modes. The effective permissions therefore depend on the environment. Under a common `022` umask, a newly created regular file can be mode `0644`, allowing other local users to read it. The file contains both the short-lived access token and the more sensitive refresh token. The script also writes directly to the final path instead of creating a securely permissioned temporary file and atomically replacing the destination. It does not verify that the destination is a regular file owned by the current user or reject a pre-existing symbolic link. Persistent credential storage is necessary for the declared automatic token-refresh functionality, but storing bearer credentials without explicit access controls exceeds the minimum safe privilege model. ### Attack Path 1. The user completes the OAuth Device Flow. 2. `auth-flow.sh` creates or overwrites `~/.caremax/credentials.json`. 3. The process has a permissive umask, causing the file or directory to be accessible more broadly than intended. 4. Another local account or process reads the access and refresh tokens. 5. The attacker reuses the tokens against the configured CareMax API. A separate local attack may pre-create or manipulat ...[truncated 771 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Enforce private permissions before handling credentials: ```bash umask 077 install -d -m 0700 "$HOME/.caremax" ``` Write credentials to a securely created temporary file in the same directory, set mode `0600`, and atomically replace the final file: ```bash TMP_FILE=$(mktemp "$HOME/.caremax/credentials.json.XXXXXX") trap 'rm -f "$TMP_FILE"' EXIT chmod 600 "$TMP_FILE" # Write validated JSON to "$TMP_FILE". mv -f "$TMP_FILE" "$HOME/.caremax/credentials.json" trap - EXIT ``` Further hardening should include: - Verify that `~/.caremax` is owned by the current user and is not a symbolic link. - Reject a credential destination that is not a regular file owned by the current user. - Reapply mode `0600` after refresh operations, including when overwriting an existing file. - Prefer an operating-system credential store or keychain when available. - Document token revocation and secure cleanup procedures. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/check-token.sh:25
Finding
Authentication scripts expose raw access and refresh tokens through standard output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auth-flow.sh:58`; `scripts/check-token.sh:25-39`; `scripts/refresh-token.sh:29-33` **Vulnerability Type**: Sensitive token disclosure through command output **Risk Level**: High ### Vulnerable Code `scripts/auth-flow.sh:58`: ```python print(json.dumps({'status': 'authorized', 'access_token': resp['access_token'], 'base_url': '$BASE_URL'})) ``` `scripts/check-token.sh:25-39`: ```python print(json.dumps({ 'status': 'valid', 'access_token': creds['access_token'], 'base_url': creds.get('base_url', 'https://api.caremax.ai'), 'expires_at': expires_at, 'scope': creds.get('scope', '') })) ... print(json.dumps({ 'status': 'expired', 'refresh_token': creds.get('refresh_token', ''), 'base_url': creds.get('base_url', 'https://api.caremax.ai') })) ... print(json.dumps({'status': 'expired', 'refresh_token': creds.get('refresh_token', ''), 'base_url': creds.get('base_url', 'https://api.caremax.ai')})) ``` `scripts/refresh-token.sh:29-33`: ```python print(json.dumps({ 'status': 'refreshed', 'access_token': resp['access_token'], 'base_url': creds.get('base_url', 'https://api.caremax.ai') })) ``` ### Technical Analysis The authentication, status-check, and refresh scripts emit complete bearer credentials to standard output. This is unnecessary for status reporting and increases the number of components that receive sensitive tokens. The documented workflow also recommends running `auth-flow.sh` in the background and observing its output. Agent runtimes, terminal multiplexers, CI systems, command wrappers, and debugging tools commonly capture standard output in transcripts or logs. A token printed once may therefore persist outside the protected credential file. `check-token.sh` is used internally by other scripts, but it is also documented as directly invocable. It returns an access token for valid credentials and a refresh token for expired credentials. The latte ...[truncated 970 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not return tokens in user-visible or generally captured output. Status commands should emit only non-sensitive state: ```json { "status": "valid", "base_url": "https://api.caremax.ai", "expires_at": "..." } ``` Recommended architectural changes: - Make `check-token.sh` return only `valid`, `expired`, or `missing` plus non-sensitive metadata. - Have API scripts read the credential file directly through a narrowly scoped internal helper. - Make `auth-flow.sh` return only an authorization status and base URL. - Make `refresh-token.sh` return only `{"status":"refreshed"}`. - Ensure errors never include complete remote responses, because those responses may contain tokens. - Add centralized secret redaction to Agent and CI logs. - Avoid placing tokens in command-line arguments, where process-list inspection may expose them. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:14
Finding
Unrestricted custom base URLs can receive credentials and sensitive medical data over untrusted transports<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:14-18,101-104`; `scripts/auth-flow.sh:8-14,38-55`; `scripts/api-call.sh:38-49` **Vulnerability Type**: Unvalidated endpoint trust and plaintext transport support **Risk Level**: Medium ### Vulnerable Code `SKILL.md:14-18`: ```markdown 4. **BASE URL DETECTION**: If the user specifies a custom URL (local dev 默认 `http://localhost:8788`,须与后端 wrangler `[dev]` 端口一致), you MUST: - Pass it as the first argument: `bash ./scripts/auth-flow.sh http://localhost:8788` (run from **this** skill root — see path convention below) - After auth completes, `credentials.json` will have `base_url` set to that URL - All subsequent `api-call.sh`, `list-system-presets.sh`, `quick-log.sh`, `upload.sh`, `ocr-stream.sh` will auto-use it - Look for URL patterns like `http://localhost:XXXX`, `caremax(http://...)`, or explicit "use local" / "use localhost" ``` `scripts/auth-flow.sh:8-14`: ```bash BASE_URL="${1:-https://api.caremax.ai}" CREDS_FILE="$HOME/.caremax/credentials.json" # Step 1: 申请设备码 DEVICE_RESPONSE=$(curl -s -X POST "$BASE_URL/api/auth/device" \ -H "Content-Type: application/json" \ -d '{"client_id":"caremax-agent","scope":"read:indicators read:records read:members write:upload write:ocr search:records"}') ``` `scripts/auth-flow.sh:38-55`: ```bash TOKEN_RESPONSE=$(curl -s -X POST "$BASE_URL/api/auth/device/token" \ -H "Content-Type: application/json" \ -d "{\"device_code\":\"$DEVICE_CODE\",\"grant_type\":\"device_code\"}") ... creds = { 'access_token': resp['access_token'], 'refresh_token': resp['refresh_token'], 'expires_at': (datetime.utcnow() + timedelta(seconds=resp['expires_in'])).isoformat() + 'Z', 'scope': resp['scope'], 'base_url': '$BASE_URL' } ``` `scripts/api-call.sh:38-49`: ```bash ACCESS_TOKEN=$(echo "$TOKEN_STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])") BASE_URL=$(echo "$TOKEN_STATUS" | python3 -c "import sys,json; pr ...[truncated 2525 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use a strict endpoint policy: 1. Default to the exact production origin `https://api.caremax.ai`. 2. Require explicit, informed user confirmation before using or persisting any custom origin. 3. Permit plaintext HTTP only when the parsed host is a loopback address such as `localhost`, `127.0.0.1`, or `::1`. 4. Require HTTPS for all non-loopback endpoints. 5. Normalize the URL and reject user information, fragments, unexpected paths, control characters, and ambiguous encodings. 6. Consider an allowlist for approved staging hosts. 7. Display the destination origin before sending health records or uploading files. 8. Bind credentials to their issuing origin and prevent silent reuse after an origin change. 9. Avoid inferring endpoint changes from arbitrary text; require a deliberate configuration action. 10. Consider separate credential files or profiles for production and development environments. The scripts should parse and validate URLs with a real URL parser rather than relying on shell pattern matching. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (61)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
File upload workflows are unrelated to core authentication but are documented inside this auth skill. In practice, this can cause the agent to access and transmit local medical files under a skill that users and routers may trust as merely establishing login.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
File upload workflows are unrelated to core authentication but are documented inside this auth skill. In practice, this can cause the agent to access and transmit local medical files under a skill that users and routers may trust as merely establishing login.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
File upload workflows are unrelated to core authentication but are documented inside this auth skill. In practice, this can cause the agent to access and transmit local medical files under a skill that users and routers may trust as merely establishing login.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
File upload workflows are unrelated to core authentication but are documented inside this auth skill. In practice, this can cause the agent to access and transmit local medical files under a skill that users and routers may trust as merely establishing login.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
File upload workflows are unrelated to core authentication but are documented inside this auth skill. In practice, this can cause the agent to access and transmit local medical files under a skill that users and routers may trust as merely establishing login.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
File upload workflows are unrelated to core authentication but are documented inside this auth skill. In practice, this can cause the agent to access and transmit local medical files under a skill that users and routers may trust as merely establishing login.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
File upload workflows are unrelated to core authentication but are documented inside this auth skill. In practice, this can cause the agent to access and transmit local medical files under a skill that users and routers may trust as merely establishing login.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
File upload workflows are unrelated to core authentication but are documented inside this auth skill. In practice, this can cause the agent to access and transmit local medical files under a skill that users and routers may trust as merely establishing login.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The manifest says the skill is for OAuth Device Flow, but the body documents broad authenticated read/write/content-management actions. This kind of scope deception is especially dangerous in a medical-data environment because it undermines user consent and safe routing assumptions.

Vague Triggers

High
Confidence
97% confidence
Finding
Trigger terms such as 'blood test,' 'medical record,' and 'upload report' are far broader than authentication and can cause this skill to auto-activate for many healthcare tasks. Given the skill's hidden broad capabilities and automatic behavior, overbroad triggers increase the chance of unintended credential use, browser launches, and data operations.

Missing User Warnings

High
Confidence
99% confidence
Finding
The metadata directs the agent to run browser-based authentication automatically and explicitly not ask the user first. That bypasses informed consent for opening a browser, initiating account linking, and storing tokens, which is particularly sensitive for health accounts.

Credential Access

High
Category
Privilege Escalation
Content
3. **NEVER split auth into multiple steps manually**. Use `./scripts/auth-flow.sh` (from this skill root) — it opens browser AND auto-polls until done.
4. **BASE URL DETECTION**: If the user specifies a custom URL (local dev 默认 `http://localhost:8788`,须与后端 wrangler `[dev]` 端口一致), you MUST:
   - Pass it as the first argument: `bash ./scripts/auth-flow.sh http://localhost:8788` (run from **this** skill root — see path convention below)
   - After auth completes, `credentials.json` will have `base_url` set to that URL
   - All subsequent `api-call.sh`, `list-system-presets.sh`, `quick-log.sh`, `upload.sh`, `ocr-stream.sh` will auto-use it
   - Look for URL patterns like `http://localhost:XXXX`, `caremax(http://...)`, or explicit "use local" / "use localhost"
Confidence
90% confidence
Finding
The skill centers subsequent operations around a credentials.json file and instructs callers to rely on it automatically. This creates a sensitive credential dependency that other sibling skills can consume, increasing the blast radius if the file is exposed, overwritten, or reused by unintended workflows.

Ae1

High
Category
analysis-evasion
Content
with **current working directory** = this folder (the directory that contains `SKILL.md` and `scripts/`). Invoke scripts as **`./scripts/<name>.sh`**.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
- **This skill (`caremax-auth`):** run commands with **current working directory** = this folder (the directory that contains `SKILL.md` and `scripts/`). Invoke scripts as **`./scripts/<name>.sh`**.
- **Other `caremax-*` skills** sit as **sibling directories** next to `caremax-auth` (e.g. `skills/caremax-indicators/` and `skills/caremax-auth/` in the repo, or `~/.agents/skills/<name>/` after install). From those folders, call auth as **`../caremax-auth/scripts/<name>.sh`**.

Credentials file location is unchanged: **`~/.caremax/credentials.json`** (not under any product’s config dir).

### api-call.sh — Make authenticated API calls (PRIMARY TOOL)
Confidence
94% confidence
Finding
Documenting a fixed shared credential path under the user's home directory makes credential discovery and reuse easier across tools and skills. In a multi-skill environment, that predictability increases the risk of accidental disclosure, unauthorized reads, or misuse by unrelated automation.

Credential Access

High
Category
Privilege Escalation
Content
1. Requests device code from the API
2. Opens the user's browser to the authorize page
3. **Automatically polls every 5 seconds** until the user approves (up to 15 min)
4. Saves token to `~/.caremax/credentials.json`

Output when done: `{"status":"authorized","access_token":"sk-caremax-...","base_url":"..."}`
Confidence
95% confidence
Finding
Saving OAuth tokens to ~/.caremax/credentials.json is a sensitive credential-storage behavior, especially because this skill is designed to run silently and support medical-data access. If that file is readable by other processes or mishandled, attackers or unrelated tools could reuse the bearer token to access protected health information.

Context Leakage

High
Category
Data Exfiltration
Content
### Upload + OCR (save medical reports from images)

This is a **session-based multi-step workflow**. One upload session groups all files + reports together.

#### Step 1: Upload → creates a session
```bash
Confidence
85% confidence
Finding
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
Destructive deletion and report-saving capabilities exceed what an authentication-only skill should do. Because the skill is positioned as a silent prerequisite, these state-changing actions are more dangerous: they may be reachable through an unexpectedly trusted path and can alter or remove medical records.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Delete session (undo entire upload)
```bash
bash ./scripts/api-call.sh DELETE /api/skill/sessions/<session_id>
```
Deletes the session + all files + all reports atomically.
Confidence
91% confidence
Finding
The documented DELETE operation accepts a session_id parameter and can remove a session, files, and reports atomically. In a skill already suffering from scope confusion and broad routing, exposing destructive parameterized shell/API calls increases the risk of accidental or manipulated deletion of medical data.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
This script is not limited to authentication; it accepts arbitrary HTTP methods, paths, and optional bodies, then sends authenticated requests with the CareMax bearer token. In the context of a skill described as an auth prerequisite, this broad post-auth capability materially expands scope and could be abused by downstream prompts or tools to access, modify, or exfiltrate health data under the user's session.

External Script Fetching

High
Category
Supply Chain
Content
CREDS_FILE="$HOME/.caremax/credentials.json"

# Step 1: 申请设备码
DEVICE_RESPONSE=$(curl -s -X POST "$BASE_URL/api/auth/device" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"caremax-agent","scope":"read:indicators read:records read:members write:upload write:ocr search:records"}')
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
for i in $(seq 1 $MAX_ATTEMPTS); do
  sleep "$INTERVAL"

  TOKEN_RESPONSE=$(curl -s -X POST "$BASE_URL/api/auth/device/token" \
    -H "Content-Type: application/json" \
    -d "{\"device_code\":\"$DEVICE_CODE\",\"grant_type\":\"device_code\"}")
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Missing User Warnings

High
Confidence
99% confidence
Finding
The script prints the access token to stdout after successful authorization, which can leak credentials into terminal scrollback, logs, orchestration output, agent traces, or other monitoring systems. In this skill context, that is especially dangerous because the skill is designed for automatic invocation and handles health-data scopes, so a leaked bearer token may immediately expose sensitive records and permit API actions.

Missing User Warnings

High
Confidence
98% confidence
Finding
The script emits the OAuth access token when the credential file is still valid, and emits the refresh token when the access token is expired. Any caller, logger, downstream skill, or transcript layer that captures stdout can obtain bearer credentials and reuse them to access CareMax APIs, which is especially sensitive in a health-data context. The skill metadata also says auth should run automatically without asking the user, which increases the chance of silent token harvesting or accidental disclosure.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The script performs file download and local write operations even though the skill is described as authentication-only. In an agent setting, this scope expansion is dangerous because it enables retrieval of remote health/session content and persistence to disk without being clearly disclosed, increasing the chance of unauthorized access to sensitive medical data.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill is described as authentication-only, but this script performs OCR session processing and streams OCR results from the backend. That mismatch expands the skill's effective capabilities beyond what the user and orchestrator would expect, creating a covert data-processing path for sensitive medical documents. In a health-data context, hidden OCR/report retrieval is especially risky because it can transmit or expose PHI without clear user intent or proper gating.

Static analysis

No suspicious patterns detected.