Back to skill

Security audit

Drug Safety Review

Security checks for vulnerabilities and agentic risk

Overview

This healthcare skill needs review because it can treat simulated medication-safety output as a successful result and its local tracking and self-evolution artifacts are not clearly or accurately disclosed.

Install only after reviewing the clinical and privacy limitations. Do not rely on this skill for real patient decisions unless demo mode is explicitly disabled, credential/free-trial behavior is fixed, the drug database coverage is validated, and local trial/output files are protected. Treat user IDs as potentially identifying health-usage metadata.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/safety_review.py:324
Finding

Implicit Demo Mode Returns Simulated Results for Real Medication Input

Content
View full analysis

Vulnerability Details

File Location: scripts/safety_review.py:324-326, scripts/safety_review.py:481-482, and scripts/safety_review.py:529-535
Vulnerability Type: Unsafe fail-open behavior and clinical output integrity failure
Risk Level: High

Vulnerable Code

python
def __init__(self, demo_mode: bool = False):
    self.billing = SkillPayBilling()
    self.trial = TrialManager("drug-safety-review")
    self.demo_mode = demo_mode or not API_KEY
python
def review(self, medications: List[Dict], allergies: List[Dict] = None,
           patient_data: Dict = None) -> Dict[str, Any]:
    if self.demo_mode:
        return DemoDataGenerator.generate_demo_review()
python
def process(self, medications: List[Dict], allergies: List[Dict] = None,
            patient_data: Dict = None, user_id: str = "") -> Dict[str, Any]:
    if self.demo_mode:
        print(self.get_message('demo_mode_active'), file=sys.stderr)
        return {
            'success': True, 'demo_mode': True, 'trial_mode': False,
            'trial_remaining': 0, 'balance': None, 'review': self.review(medications, allergies, patient_data)
        }

Technical Analysis

The reviewer automatically enables demo mode whenever the module-level SKILLPAY_API_KEY value is absent. Demo mode is therefore not restricted to an explicit user request such as --demo.

Once enabled, review() ignores the supplied medication, allergy, and patient data and calls DemoDataGenerator.generate_demo_review(). The result is nevertheless returned with "success": True. This is a fail-open design: missing billing configuration changes the semantic meaning of the operation from a patient-specific review to a simulated review rather than stopping execution with a clear error.

The behavior conflicts with documentation that advertises real free-trial reviews without an API key. A caller following that documentation can r ...[truncated 2233 chars]

Remediation
View remediation

Remediation Suggestions

  1. Require explicit activation of demo mode. Replace implicit fallback behavior with logic equivalent to:
    python
    self.demo_mode = demo_mode
    
  2. When credentials are unavailable outside explicit demo mode, either perform the advertised local free-trial analysis or return a clear configuration error.
  3. Never return "success": True for a simulated review submitted through a normal patient-review workflow.
  4. Reject real medication or patient input in demo mode, or require an explicit acknowledgement that the output is simulated and unrelated to the input.
  5. Add a prominent machine-readable result type, such as "result_type": "simulated_demo", in addition to human-readable warnings.
  6. Add automated tests confirming that changing medication, allergy, condition, and renal-function inputs changes real review output.
  7. Add integration tests covering missing credentials, explicit demo mode, free-trial mode, and paid mode.
  8. Correct the documented database and interaction coverage so it accurately reflects the implemented data.
  9. Subject clinical rules and recommendations to qualified clinical validation before production use.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/safety_review.py:58
Finding

Raw User Identifiers Are Persisted in Plaintext Contrary to the Security Policy

Content
View full analysis

Vulnerability Details

File Location: scripts/safety_review.py:58-93
Vulnerability Type: Plaintext sensitive identifier storage and insecure file permissions
Risk Level: Medium

Vulnerable Code

python
class TrialManager:
    def __init__(self, skill_name: str):
        self.skill_name = skill_name
        self.trial_dir = os.path.expanduser("~/.openclaw/skill_trial")
        self.trial_file = os.path.join(self.trial_dir, f"{skill_name}.json")
        self.max_free_calls = 10
        os.makedirs(self.trial_dir, exist_ok=True)
    
    def _load_trial_data(self) -> Dict[str, Any]:
        if os.path.exists(self.trial_file):
            try:
                with open(self.trial_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except (json.JSONDecodeError, IOError):
                return {}
        return {}
    
    def _save_trial_data(self, data: Dict[str, Any]):
        try:
            with open(self.trial_file, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
        except IOError as e:
            print(f"Warning: Could not save trial data: {e}", file=sys.stderr)
    
    def get_trial_remaining(self, user_id: str) -> 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 T
...[truncated 2570 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not store raw user identifiers. Derive a pseudonymous key using an HMAC with a locally protected secret:
    python
    pseudonymous_id = hmac.new(secret, user_id.encode(), hashlib.sha256).hexdigest()
    
  2. Avoid a plain unsalted hash for predictable identifiers such as email addresses; use a keyed construction to resist dictionary attacks.
  3. Create ~/.openclaw/skill_trial with mode 0700.
  4. Create the trial file with mode 0600, and verify permissions when opening an existing file.
  5. Write updates to a securely created temporary file in the same directory, flush and synchronize it, then use an atomic replacement.
  6. Use file locking or another concurrency-safe store to prevent lost updates and corruption.
  7. Define and implement a retention period that removes inactive trial records automatically.
  8. Document a deletion procedure and ensure uninstall operations remove trial state where appropriate.
  9. Correct SECURITY.md immediately if raw identifiers remain in use; security documentation must match actual behavior.
  10. Remove guidance that broadly applies mode 0755 to ~/.openclaw, or clearly document safe permissions for sensitive subdirectories and files.
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
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (29)

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 directly invokes a script named self_evolve.py on a recurring schedule, which strongly indicates self-modifying or self-updating behavior. In a skill environment, self-modification is especially risky because it can change future behavior outside normal review, potentially introducing persistence, bypassing trust assumptions, or pulling the system into unsafe or unauthorized states over time.

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

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The FAQ makes a strong security/privacy claim that no medication data is ever stored or transmitted, yet other sections describe online billing, balance checks, top-up URLs, and external support channels. Even if only billing metadata is transmitted, the absolute wording is misleading and could cause users to submit sensitive health information under false assumptions about data flows.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document claims the tool works completely offline and has no external dependencies, but later describes network-based billing via SkillPay and external endpoints for support. This inconsistency can mislead operators in regulated or air-gapped environments into deploying the tool where network isolation is assumed, creating compliance and operational risk.

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

Create the required directory:

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

Drug not recognized

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 243)May include surrounding context.

Create the required directory:

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

Drug not recognized

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The quick-start examples explicitly encourage users to submit medications, allergies, and patient data, which are sensitive health data, without any nearby warning about privacy, retention, transmission, or whether the review runs locally versus through a remote service. In a medical context, this can lead users to disclose protected or highly sensitive information under unsafe assumptions, increasing privacy and compliance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation recommends saving the safety report to a file but does not warn that the output may contain sensitive medical information, including medications, allergies, conditions, and risk assessments. Users may store these reports insecurely, commit them to source control, or share them unintentionally, causing data exposure.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

The troubleshooting guidance creates a persistent directory under the user's home directory for trial or skill state without explaining what data may be stored there, how long it persists, or any privacy implications. In a health-related skill, persistent local state can expose usage history, identifiers, or derived medical outputs to other local processes or users if not properly controlled.

Content

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

Permission Denied

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

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

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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The quick-start and review examples encourage submission of highly sensitive health-related data including medications, allergies, age, weight, and renal function, but the markdown does not clearly warn users that this data may be processed remotely or transmitted to external services. In a healthcare context, lack of transparent data-handling disclosure can cause users to expose protected or highly sensitive information without informed consent, increasing privacy, compliance, and data-governance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This script runs indefinitely and repeatedly executes a local Python program that is explicitly named for self-evolution, while silently appending output to a log file. In an agent skill context, an unattended background loop that continually triggers code changes or autonomous behavior without user approval, execution bounds, or integrity checks is dangerous because it can persistently alter the skill or environment and obscure when those actions occur.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This reference presents extensive medication, contraindication, and interaction information without any warning that it is informational only and not a substitute for clinician, pharmacist, or poison-control judgment. In an agent setting, users or downstream components may over-trust the content for dosing, interaction, or safety decisions, increasing the risk of harmful medical advice or unsafe self-medication.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file provides detailed drug interaction, contraindication, allergy, and monitoring guidance without any prominent disclaimer that it is informational and not a substitute for clinician or pharmacist judgment. In a healthcare context, users may over-rely on the content as authoritative or complete, which can contribute to unsafe self-medication, missed patient-specific contraindications, or harmful treatment decisions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This medication safety tool includes billing and payment-gating logic that is unrelated to its core clinical function. In a healthcare context, coupling access to safety review with monetization increases privacy and availability risk because users may unknowingly trigger billing flows and the skill’s behavior depends on external commercial configuration.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script persistently stores per-user trial usage data under the user's home directory without notice or protections. Even though it stores limited fields, the user ID plus timestamps create trackable usage records that may expose identity, behavior, or regulated workflow metadata on shared systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The tool writes trial usage data to a persistent file in the home directory without informing the user. In a medical-assistance context, hidden persistence is more concerning because it can reveal which users accessed a healthcare-related function and when, particularly on multi-user or managed machines.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code performs outbound network requests to an external billing API from within a drug-safety skill. In a healthcare-related tool, unsolicited external communication expands the attack surface and creates data-governance risk, especially when users may reasonably expect the analysis to be local.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code sends a user identifier to an external billing endpoint, and the overall skill processes medication, allergy, and patient-condition data, but there is no comment, docstring, prompt, or visible notice in this file warning that external billing/network access occurs. For a healthcare-related skill, undisclosed external transmission is a meaningful privacy concern even if only the user_id is explicitly sent here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The reviewer initializes self.lang to 'zh' and falls back to Chinese for unsupported values, and the CLI also defaults --language to 'zh'. This forces a specific language by default rather than prompting for user preference or preserving the user's locale, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script can write full review output to an arbitrary file without warning that it may contain medications, allergies, renal data, contraindications, and other sensitive medical information. In a healthcare setting, silent export to disk materially increases the risk of local data exposure, accidental sharing, backup leakage, or insecure retention.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The changelog entries are written in Chinese with no indication that language choice is optional or tied to a documented regional requirement. This can violate a language/locale policy when the skill documentation implicitly enforces a specific language for users without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The example prints 剩余免费次数, which forces a Chinese-language user-visible message in otherwise English documentation. This appears to impose a locale-specific output without user opt-in or explanation, which is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.