Back to skill

Security audit

CRS Tax Calculator

Security checks for vulnerabilities and agentic risk

Overview

The skill is purpose-aligned for tax statement processing, but it should be reviewed because the remote API can control output filenames and potentially overwrite files outside the chosen output folder.

Only install this if you trust wealthlplantation.com with full brokerage statements and the CRS_API_KEY. Until the output filename handling is fixed, run it with a least-privileged user and an empty dedicated output directory, and avoid running it on systems where overwriting user-owned files would be high impact.

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

Error
Location
do_audit.py:91
Finding

Server-Controlled Arbitrary File Write via Unsanitized Output Filename

Content
View full analysis

Vulnerability Details

File Location: do_audit.py, lines 91–94
Vulnerability Type: Path traversal leading to arbitrary file write
Risk Level: High

Vulnerable Code

python
fname = yr['excel']['filename']
out_path = os.path.join(out_dir, fname)
with open(out_path, 'wb') as f:
    f.write(base64.b64decode(yr['excel']['data']))

Technical Analysis

The filename and file contents are taken from the remote API response. The code passes yr['excel']['filename'] directly to os.path.join() without rejecting absolute paths, removing traversal components, resolving the resulting path, or verifying that it remains inside out_dir.

os.path.join() does not enforce directory containment. A filename containing ../ components can escape the designated output directory. On supported platforms, an absolute filename can also cause the preceding output directory to be discarded.

The decoded response data is consequently written to a server-selected filesystem location. Exploitation requires control over, or compromise of, the configured HTTPS API endpoint or its response-generation path. TLS reduces network interception risk but does not protect against a compromised or malicious server.

Attack Path

  1. A threat actor compromises the configured API service or gains control over the response returned for a processing request.
  2. The user runs the Skill with ordinary brokerage-statement inputs.
  3. The malicious response reports success and supplies an Excel object such as:
json
{
  "filename": "../../../../home/user/.bashrc",
  "data": "<Base64-encoded attacker-controlled content>"
}
  1. The script joins this filename with out_dir but does not enforce containment.
  2. base64.b64decode() produces attacker-controlled bytes.
  3. open(out_path, 'wb') creates or truncates the selected file and writes those bytes.
  4. If the chosen file is subsequently loaded or executed, such as a shell startup file, the attacker-controlled behavio ...[truncated 804 chars]
Remediation
View remediation

Remediation Suggestions

Treat all API-provided filenames and file contents as untrusted.

  1. Reject absolute paths and filenames containing path separators or traversal components.
  2. Reduce the response filename to a safe basename and preferably generate the local filename independently.
  3. Resolve both the output directory and destination path, then verify containment before opening the file.
  4. Restrict expected filename extensions, such as .xlsx.
  5. Avoid overwriting existing files by default; use exclusive creation or require explicit user confirmation.
  6. Validate the decoded output format before saving it.
  7. Apply a maximum decoded-file size to prevent resource exhaustion.
  8. Consider cryptographically authenticating response metadata if the API architecture supports it.

Example containment pattern:

python
base_dir = os.path.realpath(out_dir)
fname = os.path.basename(yr['excel']['filename'])

if not fname or not fname.lower().endswith('.xlsx'):
    raise ValueError('Invalid output filename')

out_path = os.path.realpath(os.path.join(base_dir, fname))
if os.path.commonpath([base_dir, out_path]) != base_dir:
    raise ValueError('Output path escapes the selected directory')

with open(out_path, 'xb') as f:
    f.write(base64.b64decode(yr['excel']['data'], validate=True))
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (11)

Tainted flow: 'req' from os.environ.get (line 75, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · do_audit.py (reported line 81)May include surrounding context.

python
})

    try:
        with urllib.request.urlopen(req, timeout=600) as resp:
            result = json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        result = json.loads(e.read().decode())

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill handles brokerage statements containing highly sensitive financial data and states that AI parsing is performed server-side, but it does not prominently warn users that their files are transmitted to a third-party remote service. This undermines informed consent and can lead to unintended disclosure of personal financial records.

Content

No source excerpt is available for this finding.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
88% confidence
Finding

The skill instructs the agent to search under ~/.claude and ~/.openclaw, which are agent configuration areas that may contain unrelated skills, configs, and potentially sensitive local metadata. Accessing these directories exceeds the minimum needed for the user task and can expose internal agent state or other installed components.

Content

Scanner excerpt · SKILL.md (reported line 84)May include surrounding context.

bash
# 查找 skill 目录下的 do_audit.py
SCRIPT=$(find ~/.claude/skills/crs-tax-calculator ~/.openclaw/skills/crs-tax-calculator -name "do_audit.py" 2>/dev/null | head -1)
echo "Script: $SCRIPT"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares environment and network-dependent behavior but does not define an explicit tool/permission scope. That increases the chance an agent can access secrets and remote endpoints without clear least-privilege boundaries or user-visible consent controls.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill description is broad enough that an agent may invoke it without clear user intent boundaries, even though it handles sensitive financial statements and sends data to a remote service. Ambiguous trigger conditions can cause accidental processing or disclosure of highly sensitive documents.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The data safety section states that uploaded files are used only for parsing and are immediately discarded without storage. However, later instructions explicitly direct the tool to generate Excel audit outputs and save them to a user-specified or default local directory, which is persistent storage of processed file contents. This is a manifest/documentation-level mismatch about storage behavior.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Using find over ~/.claude/skills and ~/.openclaw/skills can reveal the presence and naming of other installed skills, which is unnecessary for the task and leaks local environment information. Enumeration of installed agent capabilities can aid profiling or chained attacks if combined with other weaknesses.

Content

Scanner excerpt · SKILL.md (reported line 84)May include surrounding context.

bash
# 查找 skill 目录下的 do_audit.py
SCRIPT=$(find ~/.claude/skills/crs-tax-calculator ~/.openclaw/skills/crs-tax-calculator -name "do_audit.py" 2>/dev/null | head -1)
echo "Script: $SCRIPT"

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The script is explicitly designed to transmit local user-supplied documents to an external domain for processing. In the context of tax and brokerage statement handling, this is security-relevant because the data is highly sensitive, and users may not appreciate that all document contents leave the local machine and are entrusted to a remote service.

Content

Scanner excerpt · do_audit.py (reported line 13)May include surrounding context.

python
"""
import base64, json, os, sys, urllib.request, urllib.error

API_URL = 'https://api.wealthlplantation.com/api/process'

def main():
    # --- 解析参数 ---

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This tool base64-encodes and uploads full local brokerage statements, which likely contain highly sensitive financial and personal data, to a third-party remote API. The script prints upload progress but does not present a clear, explicit consent warning at the point of transmission, increasing the risk of users unknowingly sending confidential documents off-device.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file-processing rules state '严禁读取或查看文件内容' and prohibit any reading of PDF or Excel content, yet the very next line instructs use of do_audit.py to internally handle the files for parsing and API submission. This is an active contradiction in the documentation: the skill forbids reading file contents while requiring a script whose purpose is to read and process them.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The natural-language interface, usage guidance, and error/help messages are all presented in Chinese only. Under the stated policy, forcing a specific language without user opt-in can be a locale-policy violation unless the restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.