T09 · Insecure Skill Coding Practices
- Location
scripts/recognize_invoices.py:48- Finding
OCR API Credentials Stored in Plaintext
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to perform invoice OCR as advertised, but it needs review because it handles sensitive invoices and OCR credentials with weak disclosure and unsafe runtime setup.
Review before installing. Use this only if you are comfortable sending invoice files to netocr.com, avoid pasting OCR secrets into chat, prefer a dedicated low-privilege NetOCR credential, and consider running it in an isolated environment with dependencies installed deliberately.
scripts/recognize_invoices.py:48OCR API Credentials Stored in Plaintext
scripts/recognize_invoices.py:264Automatic Installation of an Unpinned Runtime Dependency
The skill advertises capabilities that imply reading files, writing config, invoking shell commands, and calling a remote OCR API, but it does not declare any tool scope or permissions boundaries. This creates unnecessary ambiguity for the agent/runtime and can enable broader-than-expected access when handling sensitive invoice documents and credentials.
The skill states that invoice files are sent to a third-party OCR provider but does not prominently warn about data exfiltration, privacy, or regulatory implications. Invoices commonly contain PII, tax identifiers, bank details, addresses, and commercial data, so silent external transmission materially increases confidentiality risk.
The skill states that invoice files are sent to a third-party OCR provider but does not prominently warn about data exfiltration, privacy, or regulatory implications. Invoices commonly contain PII, tax identifiers, bank details, addresses, and commercial data, so silent external transmission materially increases confidentiality risk.
Instructing the agent to proactively solicit raw service credentials from the user in ordinary conversation is a direct secret-collection anti-pattern. In the context of invoice OCR, this is more dangerous because the same workflow also handles sensitive financial documents, concentrating both credentials and protected business data in a potentially logged channel.
The script stores netocr_key and netocr_secret in plaintext config.json under the skill directory. Plaintext credential storage makes secrets easy to recover by other local users, backups, logs, or accidental file sharing, and the script does not warn users of this risk or use safer OS-backed secret storage.
The OCR function sends full invoice contents plus API credentials to a third-party remote service, but the script does not present an explicit runtime warning or consent step about external data disclosure. In this skill context, invoices commonly contain sensitive financial and personal data, so silent transmission materially increases privacy and compliance risk.
The Excel export path exceeds the expected OCR/format-conversion scope by mutating the host environment through package installation. This broadens the skill's privileges and creates a supply-chain execution path, especially risky in agent environments where users may not expect a file-processing skill to install software automatically.
The script automatically runs pip install openpyxl during normal execution if the dependency is missing. Even though the subprocess arguments are fixed and not shell-injected, this still grants the skill package-management capability and triggers networked code installation without an explicit user opt-in, which can execute untrusted package code in the current Python environment.
except ImportError:
print("⚠️ 导出 Excel 需要 openpyxl 库,正在自动安装...")
import subprocess
subprocess.check_call([sys.executable, "-m", "pip", "install", "openpyxl", "-q"])
import openpyxl
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
SQP-3 适用于所有文件。该文件中的用户交互指令和示例话术均固定为中文,未见提供语言/locale 选择或声明这是仅面向中文用户/中国发票场景的受限技能;按规则,强制特定语言而无用户选择可能构成自然语言政策问题。
The script's natural-language docstrings, prompts, help text, and status messages are entirely in Chinese, which imposes a language choice on all users. The file does not offer a language selection mechanism or explain that the tool is intentionally limited to a Chinese-speaking or region-specific audience.
No suspicious patterns detected.