Back to skill

Security audit

express-monitor

Security checks for vulnerabilities and agentic risk

Overview

This courier-tracking skill mostly does what it says, but it mishandles personal delivery data by storing phone numbers in plaintext while claiming encryption and by under-disclosing third-party lookups.

Install only if you are comfortable with tracking numbers being sent to kuaidi100 and phone numbers plus shipment history being stored locally under your OpenClaw workspace. The skill should be revised before broad use to remove unsupported Feishu/automatic-sync claims, stop claiming encryption unless it is implemented, add a delete/unbind command, and protect or minimize stored phone data.

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

T09 · Insecure Skill Coding Practices

Warning
Location
express_monitor.py:25
Finding

Phone Numbers Stored in Plaintext Without Explicit Access Controls

Content
View full analysis

Vulnerability Details

File Location: express_monitor.py:25-28
Vulnerability Type: Plaintext storage of sensitive personal data
Risk Level: Medium

Vulnerable Code

python
def save_phones(phones):
    """保存手机号"""
    with open(PHONE_FILE, 'w') as f:
        json.dump(phones, f, ensure_ascii=False, indent=2)

The destination is defined as follows:

python
DATA_DIR = os.path.expanduser("~/.openclaw/workspace/data/express")
os.makedirs(DATA_DIR, exist_ok=True)

PHONE_FILE = os.path.join(DATA_DIR, "phones.json")

Technical Analysis

Bound phone numbers are serialized directly into ~/.openclaw/workspace/data/express/phones.json as plaintext JSON. The application does not encrypt the data and does not explicitly enforce restrictive permissions on either the data directory or the resulting file.

File accessibility therefore depends on the process environment and its effective umask. In an environment with permissive defaults, another local account or process with workspace access may be able to read the stored phone numbers. The data may also be exposed through workspace backups, support bundles, or accidental directory disclosure.

This behavior contradicts the statement in SKILL.md that phone binding information is stored separately in encrypted form. Users may consequently provide personal data under an inaccurate security assumption.

Attack Path

  1. A user invokes the bind command with a valid phone number.
  2. bind_phone() appends the number to the in-memory phone list.
  3. save_phones() serializes the list into phones.json without encryption.
  4. A local actor, compromised process, backup reader, or other party with access to the workspace reads or copies the JSON file.
  5. The actor obtains every phone number bound through this skill.

This attack requires local filesystem access or another mechanism that exposes the workspace; the code does not itself t ...[truncated 525 chars]

Remediation
View remediation

Remediation Suggestions

  1. Store phone numbers using operating-system-backed credential storage where available.
  2. If file storage is required, encrypt the data with authenticated encryption and keep the encryption key outside the data file, preferably in a platform credential manager.
  3. Create the data directory with mode 0700 and the phone file with mode 0600. Do not rely solely on the ambient umask.
  4. Use atomic writes through a securely created temporary file, set restrictive permissions before adding sensitive content, and then replace the destination file.
  5. Minimize retained data and provide a command that lets users remove bound phone numbers.
  6. Mask phone numbers when displaying them, such as 138****8000, unless full disclosure is explicitly necessary.
  7. Update SKILL.md so its storage claims accurately reflect the implementation, and do not claim encryption until authenticated encryption or secure credential storage is actually implemented.
  8. Review existing installations and securely migrate or delete previously created plaintext phones.json files.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared behavior does not match the described functionality: it claims automatic phone-based courier retrieval and Feishu syncing, while the described implementation only stores phone numbers and lacks any Feishu integration. This mismatch is dangerous because users may disclose sensitive phone numbers under false assumptions, and undisclosed network access plus local persistence creates privacy and trust risks.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares capabilities that imply file access, file persistence, and network use, but it does not explicitly scope or disclose those permissions in the manifest. That weakens least-privilege controls and makes it harder for users or the platform to understand that phone data and courier history may be written locally and sent to external services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill encourages phone-number binding and recurring courier syncing without a clear privacy warning or explicit explanation of network and storage effects. In this context, the data is personally sensitive and may be transmitted to courier or aggregator services, so insufficient notice can lead to unintended exposure or collection of personal information.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill description claims automatic retrieval by bound phone number and Feishu synchronization, but the code only performs manual tracking queries and stores phone numbers/history locally. This mismatch can mislead users about what data is collected, where it is sent, and what functionality is actually implemented, which is a trust and privacy problem in a data-handling skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Tracking numbers are sent to a third-party logistics service without any explicit privacy disclosure or consent mechanism. Shipment identifiers can reveal purchasing activity and delivery status, so transmitting them externally without notice is a real privacy issue in the context of an end-user monitoring skill.

Content

No source excerpt is available for this finding.

Tainted flow: 'data' from requests.post (line 53, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · express_monitor.py (reported line 103)May include surrounding context.

python
}
    
    try:
        resp = requests.post(url, data=data, headers=headers, timeout=10)
        result = resp.json()
        
        if result.get('status') != '200':

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Phone numbers are persisted to a local JSON file under the user's home directory without a clear user-facing disclosure, retention policy, or protection controls. Because phone numbers are personal data, silent storage increases privacy risk, especially on shared systems or environments where workspace files may be backed up or exposed.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

All user-facing instructions and descriptions in the skill file are presented only in Chinese, and the file does not indicate that this language restriction is optional or justified by a region-specific purpose. Per the policy, forcing a specific language without user opt-in can be a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The top-level natural-language description forces a single language/locale presentation without indicating user choice or a justified region-specific constraint. Under the stated policy, language restrictions should be opt-in or clearly documented as region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.