T09 · Insecure Skill Coding Practices
- Location
scripts/parse_resume.py:6- Finding
Indirect prompt injection through untrusted resume content
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This resume skill is not clearly malicious, but it overstates its local/private behavior while handling sensitive hiring data through LLM prompts without enough safeguards.
Review before installing. Use an isolated virtual environment, pin dependencies, run only with a confirmed local model if privacy matters, redact unnecessary PII such as age and gender, and treat all parsing and matching outputs as untrusted until validated by a human.
scripts/parse_resume.py:6Indirect prompt injection through untrusted resume content
scripts/match_jd.py:4Indirect prompt injection through resume JSON and job description content
SKILL.md:178Unpinned third-party dependencies create supply-chain exposure
The declared description promises a full local resume analysis system with multi-format support (PDF/Word/image), structured extraction, JD matching, suggestion generation, and data export. The supplied code only reads a DOCX file using python-docx, concatenates paragraph and table cell text, and prints unstructured text. While DOCX text extraction could be a supporting component of a Word-resume pipeline, this code chunk by itself materially underimplements the declared functionality and does not demonstrate the system’s core advertised capabilities.
The declared description presents a broader resume analysis system with multiple capabilities: multi-format resume ingestion, structured extraction, JD matching, optimization suggestions, and structured export, all locally. The supplied code chunk only implements one narrow supporting function: OCR text extraction from an image file using pytesseract. While image OCR could be a component of such a system, this chunk by itself materially underdelivers on the declared purpose and behaves as a generic OCR utility rather than a resume parsing and analysis system. Therefore, the description does not accurately represent what this code chunk actually does.
The declared description presents a full-featured resume analysis system with multi-format support and downstream analytical features. The supplied code only implements basic PDF text extraction and outputs raw text to stdout. While PDF extraction could be a supporting component of such a system, this code chunk by itself does not substantiate most of the declared capabilities, and its actual behavior is much narrower than the stated purpose.
声明描述的是一个完整的本地简历解析与分析系统,但代码片段只实现了JD匹配提示词的构造器。它要求输入已经结构化好的resume_json,而不是从PDF/Word/图片中提取信息;也没有任何本地评分、规则执行或建议生成逻辑,真正的分析被外包给“将上述提示词传入大模型”这一步。因而其主要功能与声明存在实质差异,尤其是“完全本地运行、无需外部API”和“支持多格式简历解析/结构化提取”两点与代码行为明显不符。
The declared description presents a complete intelligent resume analysis system with multiple capabilities and fully local execution. This code chunk implements only a narrow preparatory step: it reads an extracted text file and builds a prompt template for a language model to perform parsing. The script explicitly returns the prompt instead of executing the model inference, so even the core resume parsing is not actually carried out here. There is also no evidence of handling PDF, Word, or image formats, no job-description matching, no suggestion generation, and no export logic. Therefore, the description materially overstates the implemented behavior.
The script does not perform local JD matching at all; instead it packages the full resume and JD into a prompt for an external LLM. This creates a material security and privacy risk because sensitive resume data may be transmitted outside the claimed local boundary, and the mismatch between implementation and metadata can cause operators to deploy it under false assumptions.
The README describes processing resumes and job descriptions, which routinely contain highly sensitive personal data such as names, contact details, employment history, and education records, but it provides no handling, retention, masking, or access-control guidance. In this skill context, the omission is more dangerous because users may assume 'local-only' processing is inherently safe and therefore use real candidate data without applying basic privacy safeguards.
The skill advertises file-processing behavior and explicitly instructs users to pass local file paths into parsing scripts, but it does not declare any tool scope or permission boundary. In an agent environment, missing file-read constraints can lead to overbroad access to local files beyond intended resume inputs, especially because the skill handles arbitrary user-supplied paths.
The skill is designed to process highly sensitive personal data from resumes, including phone numbers, email addresses, age, gender, and work history, yet it provides no privacy notice, retention guidance, redaction advice, or handling restrictions. In this context, missing data-handling safeguards materially increase the risk of inadvertent exposure, overcollection, or noncompliant processing of personal information.
L07-L08 明确允许“从出生年份计算”年龄、或“从其他信息推断”性别,这超出了对简历原文字段的直接提取。与此同时,L41-L42 又要求“所有提取的信息必须完全来自简历原文,不要编造”“信息不确定时留空,不要猜测”,两者在提取意图上直接冲突,可能导致实现者在是否允许推断个人敏感属性时产生相反理解。
The guide explicitly directs the system to extract gender and even infer it from other information, which creates unnecessary collection of a sensitive personal attribute. In a resume-parsing skill used for hiring workflows, this increases privacy, discrimination, and compliance risk because the system may process protected demographic data without clear necessity, user choice, or legal basis.
The file is entirely written as mandatory Chinese-language instructions and does not indicate that users may choose another language or locale. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.
The OCR call hard-codes lang='chi_sim+eng', which imposes a specific language/locale configuration on all users. This is a natural-language policy concern because the file does not offer any user opt-in, override mechanism, or explanation for why only these languages are used.
The docstring and the embedded prompt are entirely in Chinese and require the model to return specific Chinese labels such as "完全匹配/基本匹配/勉强匹配/不匹配". This imposes a language/locale constraint on the skill's behavior without any user opt-in or justification that the skill is region-specific.
The manifest describes a working resume parser that extracts structured information locally, but the function only builds a prompt and returns it with a note asking another LLM to process it. No parsing, matching, optimization, PDF/Word/image handling, or actual structured extraction occurs in this file, so the implemented behavior is materially narrower than the claimed capability.
The docstring at L007 states that the function uses a large model to parse resume text into structured JSON. In reality, the function never invokes a model or returns parsed JSON; it returns a dictionary containing the generated prompt and a note telling the caller to send it to a model.
The docstring, prompt text, and usage comments are written to require Chinese-language interaction, including explicit Chinese instructions for how the model should parse the resume. This imposes a specific language/locale behavior without any user opt-in or explanation that the skill is intentionally region-specific.
The natural-language content forces a specific language for the skill documentation and example invocations. The policy allows locale constraints only when users are given a choice or when the restriction is clearly documented and justified, which is not present here.
The skill’s natural-language description and usage instructions are entirely in Chinese, which effectively imposes a language constraint on users. There is no indication that the skill supports multiple languages, offers user opt-in for language selection, or is intentionally limited to a Chinese-speaking context.
No suspicious patterns detected.