T09 · Insecure Skill Coding Practices
- Location
parse_ocr.py:26- Finding
Unrestricted Transmission of Complete Documents to Plaintext-Capable, Caller-Controlled Endpoints
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it claims, but it can send complete exam documents and extracted question-bank content to configurable network services without strong scoping, transport safeguards, or clear sensitivity warnings.
Install only if you trust the configured OCR service and DeepSeek for the exam materials you process. Use HTTPS or an isolated trusted internal OCR endpoint, avoid shared/cloud archive folders for confidential papers, and do not run auto_run.py on proprietary or restricted exams unless sending OCR text to DeepSeek is acceptable.
parse_ocr.py:26Unrestricted Transmission of Complete Documents to Plaintext-Capable, Caller-Controlled Endpoints
声明描述的是一个“真题 PDF/图片 → OCR 解析 → 题库 Excel”的核心转换技能;但代码块 archive.py 的功能是将已有产物复制到调用方指定的归档目录,属于交付物归档/文件管理的辅助步骤。它不调用任何 OCR 服务,不处理 PDF/图片内容,不抽取题目,也不生成 Excel。根据评估标准,这属于主目的显著不同,且代码执行了声明未体现的文件归档能力,因此应判定为不匹配。
声明描述的是一个完整的“试卷转题库”技能:接收 PDF/图片,调用内网 exam-ocr 服务做 OCR,再抽取并生成题库 Excel。给出的代码块却只是一个辅助校验工具 check_missing.py,用于检查已经抽取好的 JSON 题目记录是否存在漏题,并可参考 OCR markdown 中的题数说明做数量比对。它不调用任何 OCR 服务,不处理 PDF/图片,不抽取题目为 Excel,也不体现 17 列表头导出能力。虽然该脚本可能属于整体流程中的辅助质检环节,但就该代码块本身而言,其主要行为与声明的核心用途明显不一致,因此应判定为描述与代码行为不匹配。
声明描述的是一个完整的“试卷转题库”流程:OCR 解析后还要抽取成固定 17 列表头的题库 Excel。但这段代码只负责调用 exam-ocr 服务做文件解析,并把返回的 markdown 写入本地文件。代码中没有任何 Excel 生成、表头映射、题目字段结构化抽取、入库转换等逻辑。因此其行为只覆盖了声明中的前半段 OCR 解析步骤,未覆盖核心的“转题库 Excel”能力,属于实质性描述不符。代码访问内网 OCR 服务这一点与声明一致,但主输出和主要能力明显更窄。
The README instructs users to send exam PDFs/images to an OCR service and optionally use a DeepSeek API key for automated processing, but it does not clearly warn that exam contents may be transmitted to external or separate network services. Because exam materials can contain sensitive or proprietary content, this omission can lead users to disclose data without informed consent, especially since the skill is explicitly designed around service-to-service transfer.
The skill documents access to environment variables, network endpoints, and file-writing/archiving behavior, but it declares no explicit tool scope or permission boundaries. In an agent setting, that omission weakens reviewability and can let the skill invoke broader capabilities than users expect, especially when it can contact OCR services and write or copy files to chosen locations.
The skill instructs users to provide a DeepSeek API key for automated extraction but does not clearly warn that exam PDFs/OCR text and derived question content may be sent to an external model service. This creates a data exfiltration and compliance risk, especially if the source exams are proprietary, licensed, or internally restricted.
The skill encourages archiving original PDFs plus OCR markdown, JSON extractions, and validation reports to arbitrary local, NAS, or cloud-synced locations without warning about sensitivity or access control. These artifacts may contain copyrighted exam material, answer keys, and structured content that becomes easier to search, copy, and leak once broadly archived.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import sys, os, re, json, argparse, requests
DEFAULT_URL = os.environ.get("EXAM_OCR_URL", "http://exam-ocr:8000")
API_URL = "https://api.deepseek.com/chat/completions"
SCHEMA = ["课程", "知识点", "题型", "题目内容", "选项A", "选项B", "选项C", "选项D", "选项E",
"正确答案", "难度", "状态", "是否真题", "是否模拟试卷", "是否考前押题", "年份", "解析"]
The extract function sends the full OCR text, which may contain sensitive exam content or personal data, to DeepSeek's external API. Although this is functionally intended, the script does not provide a strong runtime consent/warning boundary, so users may inadvertently exfiltrate confidential internal documents off-box.
This POST request transmits OCR-derived document contents and metadata to an external internet service. In the context of exam-bank conversion for potentially internal or copyrighted materials, the main risk is data leakage and compliance/privacy breach rather than code execution.
"response_format": {"type": "json_object"},
}
h = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
r = requests.post(API_URL, json=body, headers=h, timeout=300)
r.raise_for_status()
content = r.json()["choices"][0]["message"]["content"]
data = json.loads(content)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def write_excel(url, records, out):
r = requests.post(f"{url}/write-excel", json={"schema": SCHEMA, "records": records}, timeout=120)
r.raise_for_status()
with open(out, "wb") as f:
f.write(r.content)
The file’s natural-language instructions and user-facing behavior are entirely specified in Chinese, including usage, parsing expectations, and output descriptions. This appears to impose a specific language/locale without opt-in or justification, which matches the language/locale policy-violation criterion.
The script automatically uploads the full contents of a local PDF/image to a network OCR service, which can expose sensitive exam materials or personal data if the operator does not realize a network transfer is occurring. In this skill’s context, the destination defaults to an internal service, which reduces but does not remove risk because internal endpoints still expand the data exposure boundary and the URL can be overridden.
The script sends the full JSON-derived records payload to /write-excel over HTTP, which may include user or system data. Although the module docstring describes usage, it does not clearly warn that record contents are transmitted to a remote service, and there is no confirmation prompt or user-facing notice before the request.
The script sends the full extracted record set to a network service endpoint specified by argument or environment variable, with no authentication, allowlist enforcement, or transport-security guarantees. In this skill context, exam content may be sensitive or proprietary, so a misconfigured or attacker-controlled URL could cause unintended data exfiltration to an untrusted host.
if isinstance(records, dict):
records = records.get("records", [])
payload = {"schema": SCHEMA, "records": records}
r = requests.post(f"{a.url}/write-excel", json=payload, timeout=120)
r.raise_for_status()
out = a.out or (a.json_path + ".xlsx")
with open(out, "wb") as f:
The archive section explains how to copy generated Excel files and source papers into a user-specified archive directory, but it does not clearly warn that potentially sensitive source and output files will be duplicated to another location. This can increase accidental data exposure, especially if the target is a shared NAS, synced cloud folder, or broadly accessible project directory.
The code saves OCR output to the path provided by --ocr-md, which is a file write of potentially sensitive exam text. Although this behavior is optional, there is no adjacent comment, prompt, or user-facing warning explaining that the OCR content will be persisted to disk.
All natural-language instructions, usage notes, and help context in the module docstring are Chinese-only. This effectively forces a specific language for users of the skill without offering an alternative or documenting that the tool is intended only for a Chinese-speaking context.
All user-facing documentation strings in the file are written in Chinese, which can impose a language constraint on users without opt-in or explanation. The policy allows locale constraints when documented and justified, but no such justification or language alternative is provided here.
No suspicious patterns detected.