Back to skill

Security audit

Stock/Industry Tracker

Security checks for vulnerabilities and agentic risk

Overview

This skill coherently generates Chinese industry or stock reports through a declared Eastmoney remote service, with disclosed API-key use and local report attachments, but users should understand the external sharing and local file retention.

Install only if you are comfortable sending report prompts and the EM_API_KEY-authenticated request to Eastmoney's report service. Do not include confidential strategy, account, or personal information in queries unless that disclosure is acceptable, and periodically review or delete generated DOCX/PDF files because the skill saves them locally without a stated cleanup policy.

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
scripts/generate_industry_stock_tracker_report.py:100
Finding

Unbounded Remote Response and Attachment Decoding Enables Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_industry_stock_tracker_report.py, lines 100–101 and 145–160
Vulnerability Type: Unbounded network response processing and file creation
Risk Level: Medium

Vulnerable Code

python
with urllib.request.urlopen(req, timeout=timeout) as resp:
    status_code = getattr(resp, "status", None) or resp.getcode()
    content = resp.read()
python
def _decode_attachment_base64(data: Dict[str, Any], output_dir: str) -> List[Dict[str, str]]:
    attachments: List[Dict[str, str]] = []
    os.makedirs(output_dir, exist_ok=True)

    file_map = [
        ("wordBase64", "docx", "DOCX"),
        ("pdfBase64", "pdf", "PDF"),
    ]
    article_id = _safe_str(data.get("articleId"), default=uuid.uuid4().hex)
    safe_article_id = re.sub(r"[^a-zA-Z0-9_-]+", "_", article_id)

    for key, ext, ftype in file_map:
        b64_str = _safe_str(data.get(key))
        if not b64_str:
            continue
        try:
            raw = base64.b64decode(b64_str)
        except Exception:
            continue
        file_name = "{0}_{1}.{2}".format(safe_article_id, ftype.lower(), ext)
        file_path = os.path.join(output_dir, file_name)
        with open(file_path, "wb") as f:
            f.write(raw)

Technical Analysis

The script reads the entire HTTP response into memory without enforcing a maximum response size. It then accepts remotely supplied Base64 attachment fields, decodes each field into another in-memory byte buffer, and writes the result to disk without per-file or aggregate size limits.

A malicious, compromised, or malfunctioning upstream report service can therefore return an exceptionally large response or Base64 attachment. Processing that response may consume memory for the encoded HTTP body, parsed JSON strings, and decoded attachment simultaneously. The resulting file is also written without checking availab ...[truncated 1651 chars]

Remediation
View remediation

Remediation Suggestions

  1. Enforce a strict maximum HTTP response size. Read the response incrementally in bounded chunks and abort once the cumulative limit is exceeded.
  2. Check Content-Length when present, while retaining the streaming limit because the header can be absent or untrusted.
  3. Before decoding, estimate the decoded size from the Base64 input length and reject attachments exceeding a defined per-file limit.
  4. Apply an aggregate limit across all attachments generated by one request.
  5. Use strict decoding:
    python
    raw = base64.b64decode(b64_str, validate=True)
    
  6. Avoid retaining unnecessary copies of the full encoded and decoded payloads. Where practical, use incremental Base64 decoding into a size-limited temporary file.
  7. Check available disk capacity and enforce an application-level storage quota before writing attachments.
  8. Write through a temporary file with restrictive permissions, then atomically rename it after successful validation. Remove partial files on every failure path.
  9. Add tests covering oversized HTTP responses, oversized attachments, malformed Base64, low-disk conditions, and cleanup after interrupted writes.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 88, 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 · scripts/generate_industry_stock_tracker_report.py (reported line 100)May include surrounding context.

python
},
    )
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            status_code = getattr(resp, "status", None) or resp.getcode()
            content = resp.read()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill requires an environment secret and invokes a remote report service, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates an authorization and review gap: the skill can access network and sensitive runtime capabilities without clear least-privilege constraints, making misuse or unintended data egress harder to detect and govern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The workflow explicitly says the user's original question is passed through unchanged to a remote report service, but the skill description does not warn users about this external transmission. That omission can lead to unintended disclosure of sensitive prompts, proprietary research interests, account information, or other confidential text to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the script to save returned DOCX/PDF attachments locally, but the user-facing description does not clearly warn that files will be written to local storage. This can surprise users, create unintended persistence of potentially sensitive financial queries or reports, and increase data exposure on shared or unmanaged systems.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The language requirement says to always prioritize Chinese output and keep the report body in a Chinese context even when the user uses another language. This is a natural-language locale policy constraint that forces a specific language behavior without giving the user an explicit choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring and all user-facing messages are written only in Chinese, and the file does not indicate that language is selectable or that the skill is intentionally region- or locale-specific. This can violate language/locale policy when a specific language is imposed without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The user's raw query is sent to an external HTTPS API, but the code contains no user-facing disclosure, consent mechanism, or minimization of what gets transmitted. In this skill, users may include sensitive investment intentions, proprietary company names, or personal context, so undisclosed third-party transmission increases privacy and compliance risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script decodes server-provided base64 blobs and writes DOCX/PDF files to local disk, including to an environment-overridable directory. In this skill context, local persistence of generated artifacts can create unintended data retention, leak sensitive report contents to other local users/processes, and enable disk-fill abuse if a remote service returns oversized attachments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code writes generated report artifacts to local disk without any indication to the user that persistent files will be created. In a reporting skill, these files may contain sensitive market research or user-request-derived content, so silent persistence increases the chance of unauthorized local access, retention beyond user expectations, and forensic exposure.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The skill's stated purpose is to generate tracking reports for industries or stocks. Accessing environment variables for an API key and filesystem output configuration introduces host-environment dependency and credential access that is not described in the manifest-level intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code reads EM_API_KEY from the environment and uses it for authentication, but the file provides no user-facing notice or explanatory comment about credential usage. Under the code-file criteria, access to sensitive environment variables should have some disclosure unless it is already clearly documented.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.