Back to skill

Security audit

sales-report-parser

Security checks for vulnerabilities and agentic risk

Overview

This tool appears to parse sales-report images as advertised, but it can send business data to a third-party model and exposes API keys in command examples, so it needs review before use.

Review this before installing if your sales reports contain confidential revenue, transaction, customer, or operational data. Use a dedicated virtual environment or container, pin and audit dependencies, avoid putting real API keys directly in shell commands, restrict the input directory to only intended files, and only use the MiniMax or custom base URL if you are comfortable sending the OCR/report contents there.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding
Unpinned Third-Party Dependencies Create a Supply-Chain Risk## Vulnerability Details **File Location**: `scripts/requirements.txt:1-7`; installation command at `SKILL.md:18` **Vulnerability Type**: Unpinned and unverifiable third-party dependencies **Risk Level**: Medium ### Vulnerable Code ```text cnocr langchain-openai langchain-core pandas openpyxl pillow pydantic ``` The documented installation process resolves these dependencies directly from the configured Python package repository: ```bash pip install -r requirements.txt ``` ### Technical Analysis None of the dependencies has an exact version constraint or an integrity hash. Consequently, the installed code can change between installations without any modification to this Skill. If a dependency account, package release, package index, or dependency-resolution path is compromised, a user may install attacker-controlled code. Python packages can execute code during installation, import, or normal runtime. The affected packages are imported by the Skill and therefore execute with the same operating-system privileges as the user running it. The finding does not establish that any currently named package is malicious. It identifies the absence of controls needed to make dependency installation reproducible and resistant to supply-chain substitution. ### Attack Path 1. An attacker compromises a dependency publisher, a package-index account, or another component in the dependency distribution chain. 2. The attacker publishes a malicious or backdoored release under one of the accepted package names. 3. A user follows the documented `pip install -r requirements.txt` procedure. 4. Because no exact version or hash is required, the package resolver accepts the malicious release. 5. Attacker-controlled code executes during installation, import, OCR processing, report conversion, or LLM interaction. ### Impact Assessment Malicious dependency code would run with the privileges of the user installing or invokin ...[truncated 521 chars]
Remediation
## Remediation Suggestions 1. Pin every direct dependency to an exact reviewed version using `==`. 2. Generate a lock file that also records resolved transitive dependencies. 3. Record package hashes and install with hash verification, for example: ```bash pip install --require-hashes -r requirements.lock ``` 4. Build dependencies in a controlled environment and test updates before publication. 5. Use automated dependency vulnerability and provenance scanning. 6. Install and run the Skill in an isolated virtual environment or container with access only to required images and output directories. 7. Periodically update pinned versions through an explicit security-review process rather than allowing automatic resolution to the latest release.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/llm_json.py:83
Finding
MiniMax API Key Is Accepted Through Process Command-Line Arguments## Vulnerability Details **File Location**: `scripts/llm_json.py:83`; `scripts/batch_extract.py:120`; usage examples at `SKILL.md:28-32` and `SKILL.md:39-43` **Vulnerability Type**: Exposure of credentials through command-line arguments **Risk Level**: Medium ### Vulnerable Code In `scripts/llm_json.py`: ```python parser.add_argument('--api_key', '-k', required=True, help='MiniMax API 密钥') ``` In `scripts/batch_extract.py`: ```python parser.add_argument('--api_key', '-k', required=True, help='MiniMax API 密钥') ``` The documented usage instructs users to place the key directly in the command: ```bash python llm_json.py \ --content "OCR识别结果文本" \ --prompt "你的提示词" \ --api_key "你的API密钥" \ --output result.json ``` ### Technical Analysis Supplying a secret as a command-line argument can expose it outside the intended process. Depending on the operating system and environment, command arguments may be available through: - Shell command-history files. - Process-listing tools. - Process metadata interfaces. - Endpoint monitoring or audit telemetry. - Terminal logging and copied command transcripts. - Wrapper scripts, job schedulers, or CI logs. The key is legitimately required to authenticate to the MiniMax API, but command-line transmission is not the minimum-exposure credential mechanism. The code does not intentionally transmit the key to an unrelated destination; the weakness concerns local secret handling. ### Attack Path 1. A user runs one of the documented commands and supplies a real API key using `--api_key`. 2. The shell records the complete command in its history, or a local process-monitoring mechanism captures the argument vector while the process is running. 3. A local user, support operator, telemetry reader, or attacker with access to those records retrieves the key. 4. The recovered key is submitted to the applicable MiniMax-compatible API. 5. The attacker consumes t ...[truncated 915 chars]
Remediation
## Remediation Suggestions 1. Read the API key from a protected environment variable such as `MINIMAX_API_KEY`. 2. Support an interactive hidden prompt using `getpass.getpass()` when the environment variable is absent. 3. Prefer an operating-system credential store or managed secret service in production deployments. 4. Remove the required command-line secret from documented examples. 5. If backward compatibility requires `--api_key`, mark it as deprecated and print a warning explaining the history and process-list exposure. 6. Ensure application logs never print request headers, authentication values, or complete client configuration. 7. Rotate any key that has already been entered into a shared terminal, CI command, shell history, or diagnostic log. 8. Restrict API keys to the minimum provider-side permissions and spending limits required by this Skill.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (32)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation instructs users to send OCR-extracted sales-report text to the MiniMax API, but it does not warn that this may transmit potentially sensitive business data to a third-party service. This creates a real data-handling and privacy risk because users may unknowingly expose sales figures, transaction counts, or other confidential operational data outside their environment.

External Transmission

Medium
Category
Data Exfiltration
Content
- `--prompt/-p`: 提示词(必需)
- `--api_key/-k`: API 密钥(必需)
- `--output/-o`: 输出 JSON 路径(必需)
- `--base_url`: API 地址(默认 https://api.minimaxi.com/v1)
- `--model`: 模型名(默认 MiniMax-M2.5)
- `--temperature`: 温度(默认 1.0)
Confidence
92% confidence
Finding
The skill documents a default external API endpoint for MiniMax, confirming that extracted content can be transmitted off-host to a third-party service. In the context of OCR on sales reports, this is materially sensitive because the transmitted data may include confidential commercial information, and the documentation does not clearly disclose the security/privacy implications.

External Transmission

Medium
Category
Data Exfiltration
Content
image_path: str,
    api_key: str,
    max_retries: int = 3,
    base_url: str = "https://api.minimaxi.com/v1",
) -> Optional[List[dict]]:
    """单张图片提取"""
    for attempt in range(max_retries):
Confidence
89% confidence
Finding
The hardcoded default base URL points to an external API, and the function later transmits OCR-derived report content to that service. In this business-report extraction context, external transmission can disclose sensitive commercial data if users are unaware or if the endpoint is changed to an untrusted service via configuration.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script sends OCR-extracted sales report text to a third-party LLM API, which may expose business-sensitive data such as revenue, transaction counts, and operational details. Although this is the tool's intended workflow, the code does not provide an explicit disclosure, consent step, or masking option before transmitting potentially sensitive content off-host.

External Transmission

Medium
Category
Data Exfiltration
Content
parser.add_argument('--api_key', '-k', required=True, help='MiniMax API 密钥')
    parser.add_argument('--image', '-i', required=True, help='图片文件路径或目录')
    parser.add_argument('--output', '-o', default='output', help='输出文件名(不含扩展名)')
    parser.add_argument('--base_url', default='https://api.minimaxi.com/v1', help='API 地址')
    parser.add_argument('--retries', type=int, default=3, help='最大重试次数')
    
    args = parser.parse_args()
Confidence
87% confidence
Finding
Accepting a configurable `--base_url` for the API increases the risk of sending OCR-extracted sales data and API credentials to an unintended or malicious endpoint. This is especially relevant because the script is designed for automated batch processing, so a misconfiguration could leak multiple reports at once.

External Transmission

Medium
Category
Data Exfiltration
Content
--prompt/-p      : 给大模型的提示词
    --api_key/-k     : MiniMax API 密钥
    --output/-o      : 输出 JSON 文件路径
    --base_url       : API 地址(可选,默认 https://api.minimaxi.com/v1)
    --model          : 模型名称(可选,默认 MiniMax-M2.5)
    --temperature    : 温度参数(可选,默认 1.0)
"""
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
--prompt/-p      : 给大模型的提示词
    --api_key/-k     : MiniMax API 密钥
    --output/-o      : 输出 JSON 文件路径
    --base_url       : API 地址(可选,默认 https://api.minimaxi.com/v1)
    --model          : 模型名称(可选,默认 MiniMax-M2.5)
    --temperature    : 温度参数(可选,默认 1.0)
"""
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
--prompt/-p      : 给大模型的提示词
    --api_key/-k     : MiniMax API 密钥
    --output/-o      : 输出 JSON 文件路径
    --base_url       : API 地址(可选,默认 https://api.minimaxi.com/v1)
    --model          : 模型名称(可选,默认 MiniMax-M2.5)
    --temperature    : 温度参数(可选,默认 1.0)
"""
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
content: str,
    prompt: str,
    api_key: str,
    base_url: str = "https://api.minimaxi.com/v1",
    model: str = "MiniMax-M2.5",
    temperature: float = 1.0,
    use_structured_output: bool = True,
Confidence
90% confidence
Finding
The default base_url points to an external LLM API, and the surrounding function is specifically designed to transmit provided content and prompts there. In context, this is a real external data transmission path and becomes dangerous when the input may contain sensitive or regulated information without guardrails or user awareness.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The function sends arbitrary user-supplied content and prompt text to a third-party LLM service without any explicit consent flow, warning, redaction, or classification of sensitive data. In a skill context, this can expose OCR results, documents, credentials, or personal data to an external processor, creating confidentiality and compliance risk even if the transmission is expected for functionality.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The image chat paths base64-encode local images and send them to a third-party API endpoint without any consent check, warning, or data-handling disclosure. If users process receipts, reports, IDs, or other sensitive images, confidential content may be transmitted off-device unexpectedly, creating privacy and compliance risk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code prints full OCR-recognized document text directly to stdout, which can expose sensitive business or personal information in terminal history, logs, CI output, or centralized logging systems. This creates a local data leakage path even if the remote model call were otherwise controlled.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
OCR-derived report text is forwarded to the remote LLM as part of the prompt without any user disclosure or approval. Because the text may contain sales, financial, or customer information, this can leak sensitive extracted content to an external provider and may violate privacy expectations or data-handling requirements.

Ssd 1

Medium
Confidence
91% confidence
Finding
The OCR text is embedded verbatim into the LLM prompt, so attacker-controlled text inside an image can inject instructions such as altering extraction behavior, exfiltrating embedded secrets from surrounding prompt context, or causing malformed output. Since the function asks the model to 'reasonably infer and correct data,' the model may be especially susceptible to obeying adversarial text masquerading as report content.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This Python file includes its title, usage instructions, argument descriptions, and runtime messages only in Chinese. The policy requires flagging language/locale constraints when a skill forces a specific language without user opt-in, and this file provides no alternative language option or justification that it is region-specific.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The natural-language instructions throughout the file are effectively limited to Chinese, which can impose a language constraint on users without opt-in. The file does not state that the skill is region-specific or offer an alternative language path.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The batch-processing workflow encourages users to process images or directories and generate output files at scale, but it does not warn about bulk handling of potentially sensitive records or accidental overwriting/export of derived data. While this is primarily a documentation issue, it increases the chance of unintentional large-scale data exposure or mishandling.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
Natural-language strings in the docstring, prompt, and command help are exclusively in Chinese, which effectively forces a specific language/locale for users. The file does not offer an alternative language option or explain that the tool is intentionally limited to a Chinese-speaking context.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The model schema fields, prompts, and operational messaging are written entirely in Chinese, effectively forcing a specific language for users and outputs. The file does not provide any opt-in, language selection mechanism, or documented justification for this locale restriction.

Unpinned Dependencies

Low
Category
Supply Chain
Content
cnocr
langchain-openai
langchain-core
pandas
Confidence
95% confidence
Finding
The dependency list leaves cnocr unpinned, so builds may resolve to different versions over time, including newly introduced vulnerable or incompatible releases. This weakens supply-chain integrity and makes it difficult to audit or reproduce a known-safe environment.

Unpinned Dependencies

Low
Category
Supply Chain
Content
cnocr
langchain-openai
langchain-core
pandas
openpyxl
Confidence
98% confidence
Finding
langchain-openai is unpinned, which allows installation of whatever version is current at install time. Because this package family has had security advisories, leaving it unversioned increases the chance of silently pulling an affected release and prevents reliable vulnerability verification.

Unverifiable Dependency: langchain-openai has 2 known advisory(ies) (CVE-2026-41488 (langchain-openai: Image token counting SSRF protection can be bypassed via DNS r); CVE-2026-41488 (LangChain is a framework for building agents and LLM-powered applications. Prior)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding
The manifest includes langchain-openai without a pinned version even though the package has known advisories, so the deployed version cannot be verified as safe. In an LLM/agent skill, that uncertainty is more significant because vulnerable LangChain components can expose SSRF-style behavior or other network-adjacent attack paths depending on usage.

Unpinned Dependencies

Low
Category
Supply Chain
Content
cnocr
langchain-openai
langchain-core
pandas
openpyxl
pillow
Confidence
99% confidence
Finding
langchain-core is unpinned, creating a reproducibility and supply-chain risk because future installs may bring in different code than originally tested. In this context that is more concerning than a generic library because LangChain-related packages have a history of impactful advisories, including file read, SSRF, and template-injection issues.

Unverifiable Dependency: langchain-core has 16 known advisory(ies) (CVE-2026-26013 (LangChain affected by SSRF via image_url token counting in ChatOpenAI.get_num_to); CVE-2024-10940 (langchain-core allows unauthorized users to read arbitrary files from the host f); CVE-2025-65106 (LangChain Vulnerable to Template Injection via Attribute Access in Prompt Templa) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
98% confidence
Finding
langchain-core has multiple known advisories, but the requirements file does not pin a version, so there is no way to verify whether the installed release is affected. Given the package’s role in agent orchestration and the history of file-read, SSRF, and template-injection issues, this materially increases risk in this skill context.

Unpinned Dependencies

Low
Category
Supply Chain
Content
cnocr
langchain-openai
langchain-core
pandas
openpyxl
pillow
pydantic
Confidence
94% confidence
Finding
pandas is unpinned, so installation is not deterministic and may pull vulnerable or breaking versions unexpectedly. Even if no active exploit path is evident from this file alone, unpinned dependencies are a recognized supply-chain weakness.

Static analysis

No suspicious patterns detected.