Back to skill

Security audit

Intelligent Triage Symptom Analysis

Security checks for vulnerabilities and agentic risk

Overview

This is a medical-triage skill with real code, but it needs review because it stores sensitive symptom history by default and makes safety and privacy claims that the implementation does not support.

Review this skill carefully before installing or using it with real patient information. Treat it as a limited rule-based demo unless clinically validated, avoid putting names, emails, patient IDs, or real medical details in user_id or symptoms, disable history with --no-save-history when possible, and do not run the auto-evolution daemon. Do not rely on its output for emergency or clinical decisions without qualified human review.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/triage.py:135
Finding

Path Traversal in Symptom History File Handling

Content
View full analysis
List[Dict[str, Any]]: if os.path.exists(self.history_file): try: with open(self.history_file, 'r', encoding='utf-8') as f: return json.load(f) except: pass return [] ``` ### Technical Analysis The caller-controlled `user_id` is inserted directly into a filesystem path without validation, normalization, or containment checking. A value containing traversal components such as `../` can cause the resolved history path to escape `~/.openclaw/symptom_history`. A value beginning with an absolute path can also cause `os.path.join()` to discard the intended base directory. The `.json` suffix limits target names but does not prevent access to JSON configuration or data files. The `--history` command exposes the contents of a selected JSON file through `load_history()`. During an assessment, `save_assessment()` can overwrite a selected file if the existing JSON is compatible with the expected list structure. ### Attack Path 1. An attacker who can invoke the CLI or API supplies a cr ...[truncated 1041 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/triage.py:143
Finding

Plaintext Storage of Sensitive Medical Assessments by Default

Content
View full analysis
Dict[str, Any]: ``` ```python if trial_remaining > 0: self.trial.use_trial(user_id) analysis = self.analyze(symptoms, age, gender, vital_signs, duration) if save_history: self.history_manager = SymptomHistoryManager(user_id) self.history_manager.save_assessment(analysis) ``` ```python analysis = self.analyze(symptoms, age, gender, vital_signs, duration) if save_history: self.history_manager = SymptomHistoryManager(user_id) self.history_manager.save_assessment(analysis) ``` The stored assessment includes the raw input: ```python 'input': {'symptoms': symptoms, 'age': age, 'gender': gender, 'vital_signs': vital_signs, 'duration': duration}, ``` ### Technical Analysis History storage is enabled by default through `save_history=True`. Each successful non-demo assessment writes symptoms, age, gender, vital signs, duration, derived diagnoses, and recommendations to plaintext JSON. The implementation does not: - Encrypt the medical information at rest. - Explicitly set restrictive file or directory permissions. - Apply a time-based retention policy. - Obtain affirmative consen ...[truncated 1658 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/triage.py:122
Finding

Raw User Identifiers Are Stored Locally and Sent to the Billing Provider

Content
View full analysis
int: if not user_id: return 0 data = self._load_trial_data() user_data = data.get(user_id, {}) used_calls = user_data.get('used_calls', 0) return max(0, self.max_free_calls - used_calls) def use_trial(self, user_id: str) -> bool: if not user_id: return False data = self._load_trial_data() if user_id not in data: data[user_id] = {'used_calls': 0, 'first_use': datetime.now().isoformat()} data[user_id]['used_calls'] += 1 data[user_id]['last_use'] = datetime.now().isoformat() self._save_trial_data(data) return True ``` ```python class SkillPayBilling: def __init__(self, api_key: str = API_KEY, skill_id: str = SKILL_ID): self.api_key = api_key self.skill_id = skill_id self.headers = {'X-API-Key': api_key, 'Content-Type': 'application/json'} ``` ```python def charge_user(self, user_id: str) -> Dict[str, Any]: result = self._make_request('/charge', method='POST', data={ 'user_id': user_id, 'skill_id': self.skill_id, 'amount': 0, }) ``` ### Technical Analysis The user identifier is used verbatim as a key in the local trial-state JSON. It is also posted verbatim to the external SkillPay billing endpoint after the trial is exhausted. The billing request is an explicitly declared feature, uses HTTPS, and does not include symptoms or vital signs. Therefore, the audit did not identify covert medical-data exfiltration. However, no hashing or pseudonymization occurs despite documentation stating that the stored user ID is hashed. If callers use an email address, patient number, account name, or other real-world identifier, that information becomes linkabl ...[truncated 1142 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/triage.py:529
Finding

Billing API Key Can Be Exposed Through Command-Line Arguments

Content
View full analysis
...`. 2. The shell records the complete command in its history. 3. While the process is active, a local process-monitoring user or system may inspect its arguments. 4. Logging or automation infrastructure may retain the command. 5. An attacker who gains access to one of these sources obtains the billing API key and can attempt unauthorized billing API operations within that key's permissions. ### Impact Assessment The maximum impact is determined by the permissions granted to the SkillPay API key. Potential consequences include: - Unauthorized requests to the billing provider. - Fraudulent or disruptive billing activity. - Exposure of billing-account metadata. - Service denial if the key is revoked or rate-limited after abuse. This does not itself grant broader host privileges, but it can compromise the external billing account represented by the key. ]]>
Remediation
View remediation

other

Error
Location
scripts/triage.py:326
Finding

Safety-Critical Medical Recommendations Rely on Unvalidated Keyword Matching

Content
View full analysis
int: if any(rf['priority'] == 'CRITICAL' for rf in red_flags): return 1 critical_systems = ['cardiac', 'neurological', 'respiratory'] if any(rf['category'] in critical_systems for rf in red_flags): return 2 max_severity = max([s['severity'] for s in symptoms], default=5) age_factor = 1 if age and (age < 5 or age > 65) else 0 if max_severity >= 7 or age_factor > 0: return 3 if max_severity >= 4: return 4 return 5 ``` ```python if triage_level == 1: recommendations.extend([ '立即呼叫急救/Call emergency services immedi ...[truncated 2668 chars]
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 Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (26)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

  1. Copy the environment variables file and configure:
bash
cp .env.example .env
# Edit .env with your actual API keys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

  1. Copy the environment variables file and configure:
bash
cp .env.example .env
# Edit .env with your actual API keys

Environment Variables Configuration

Self-Modification

High
Category
Rogue Agent
Confidence
98% confidence
Finding

The daemon repeatedly runs scripts/self_evolve.py, indicating self-modifying or self-updating behavior. Self-evolution is high risk because it can alter the skill's behavior outside normal review, create persistence, and amplify any existing compromise or unsafe logic over time; the infinite loop makes this especially dangerous in an agent skill environment.

Content

Scanner excerpt · auto-evolve-daemon.sh (reported line 9)May include surrounding context.

sh
echo "🧬 Auto-Evolution Started: $(date)" > $LOG_FILE
while true; do
    echo "[$(date)] Evolving..." >> $LOG_FILE
    cd $SKILL_PATH && python3 scripts/self_evolve.py >> $LOG_FILE 2>&1
    sleep 1800
done

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This file provides specific emergency triage levels, response times, and red-flag symptom guidance but does not warn users that the content is informational only and not a substitute for professional medical assessment or emergency services. In a safety-critical medical context, users may rely on the document for self-triage or delay urgent care, which can lead to serious injury or death.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The FAQ makes strong safety and performance claims such as 'Never miss life-threatening conditions' and high sensitivity/accuracy figures without clear qualification, uncertainty bounds, or failure warnings adjacent to the claim. In a medical triage context, users may over-trust the tool and delay urgent care, creating a meaningful risk of physical harm if the system is wrong.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The FAQ encourages users to provide detailed symptom descriptions and vital signs but does not present a nearby privacy warning about the sensitivity of that information or the risks of entering personal health details. Even though the file later claims local processing and no medical data transmission, the omission can mislead users about privacy expectations at the point of collection in a healthcare-related workflow.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The FAQ instructs users to create a persistent directory under ~/.openclaw/skill_trial, confirming local session or usage-state persistence. In context this aligns with the stated storage of free-trial usage counts, so it is not covert, but persistence still has security and privacy implications because local artifacts can reveal usage history or identifiers on shared systems.

Content

Scanner excerpt · FAQ.md (reported line 146)May include surrounding context.

text

### Permission denied errors
Create the required directory:
```bash
mkdir -p ~/.openclaw/skill_trial
chmod 755 ~/.openclaw

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

Create the required directory:

bash
mkdir -p ~/.openclaw/skill_trial
chmod 755 ~/.openclaw

Compliance Questions

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

Create the required directory:

bash
mkdir -p ~/.openclaw/skill_trial
chmod 755 ~/.openclaw

Compliance Questions

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

Multiple examples use Chinese symptom descriptions, and some outputs are bilingual or Chinese-only, such as the free-call status message. The file does not explicitly state that the skill supports multiple languages by user choice or that it is intentionally limited to a Chinese-language workflow, which can violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Lines L031-L035 explicitly state there are no external dependencies and only the Python standard library is used. Elsewhere, the documentation describes a free-trial quota, post-trial billing through skillpay.me, and environment variables for external API credentials, which contradicts the impression that the skill is entirely self-contained and dependency-free.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation encourages submission of symptom descriptions, age, gender, vital signs, duration, and user identifiers, and references external billing/API-backed operation, but it does not clearly disclose storage, transmission, retention, or third-party processing of this potentially sensitive health data. In a medical-triage context, this omission is more serious because users may unknowingly transmit health-related personal information to remote services.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
74% confidence
Finding

The documentation instructs users to create a persistent directory under ~/.openclaw for trial state, implying local session/trial persistence without explaining what is stored there or how it is protected. In the context of a health-related skill that also handles user IDs and symptoms, undocumented persistent local state can expose metadata, usage history, or identifiers to other local users or backups.

Content

Scanner excerpt · GETTING_STARTED.md (reported line 219)May include surrounding context.

Permission Denied

If you see permission errors for ~/.openclaw/:

bash
mkdir -p ~/.openclaw/skill_trial
chmod 755 ~/.openclaw

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The sample symptom input and all printed user-facing output in the usage example are in Chinese, while the rest of the README is in English. This creates a natural-language locale constraint without opt-in or explanation, which can conflict with organizational language-choice policies.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SECURITY.md (reported line 28)May include surrounding context.

md
- **Retention**: Until user deletes the file or uninstalls the skill

### File System Access
- **Purpose**: Read/write trial tracking data
- **Scope**: User's home directory only (`~/.openclaw/`)
- **No access** to: System files, other applications' data, sensitive directories

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The document presents conflicting free-trial terms, including 10 free calls in some sections and 200 free calls in others. In a paid medical triage skill, inconsistent billing and entitlement information can mislead users, create billing disputes, and undermine informed consent around service use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill advertises automatic symptom history tracking for medical data but does not provide a clear privacy warning near that feature about retention, sensitivity, access controls, or consent implications. Because the data involves health symptoms and longitudinal history, inadequate disclosure can expose users to serious privacy harm and regulatory risk if sensitive records are stored unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script launches an infinite background-style automation loop that repeatedly executes code every 30 minutes without any user confirmation, gating, or visible consent mechanism. In a skill context, unattended recurring execution increases the chance of unauthorized actions, persistence, and unnoticed harmful changes, especially because the invoked code is a self-evolution script.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level docstring claims 'AI-powered medical triage with NLP and machine learning', which implies substantive ML/NLP analysis. In the actual code, symptom extraction and triage are implemented with fixed keyword lists and simple conditional logic, while additional code handles billing and local history persistence rather than AI/ML behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The billing flow sends a user identifier to a remote third-party endpoint without any explicit user-facing notice in this execution path. Although the transport uses HTTPS, undisclosed transmission of identifiers from a health-related skill is a privacy concern because it links user activity and potentially medical-service usage to an external billing provider.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill stores symptom assessments, which can contain highly sensitive medical data, as plaintext JSON under the user's home directory by default. In a medical-triage context, silent local persistence increases privacy risk from other local users, backups, endpoint compromise, or accidental disclosure, especially because retention occurs automatically unless the user opts out.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The analyzer initializes self.lang to 'zh' and falls back to Chinese when an unsupported or unspecified language is provided. This enforces a specific locale by default rather than prompting for or preserving user preference, which matches the stated language/locale policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The changelog entries from L5 to L8 are written in Chinese with no indication that the skill is region-specific or that users can choose their preferred language. This can violate language/locale policy when documentation implicitly forces a specific language without opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill metadata says version 1.3.0 while the body prominently states version 1.1.0, creating ambiguity about which release users are evaluating. For a healthcare-related skill, version confusion can hide what features, safeguards, or fixes are actually present, weakening traceability and trust.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The file’s natural-language strings and docstrings are written in Chinese, including the title and class/method descriptions, with no indication that users can choose another language. This can violate a language/locale policy when a skill implicitly constrains interaction language without documenting opt-in or regional justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.