T09 · Insecure Skill Coding Practices
- Location
scripts/parse_jd.py:19- Finding
Server-Side Request Forgery Through Unrestricted Job Description URL Fetching
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This resume skill is broadly purpose-aligned, but it needs Review because it handles sensitive resume data and includes unrestricted URL fetching plus unsafe HTML export behavior.
Install only if you are comfortable processing sensitive resume data in this environment. Prefer pasted JD text or trusted local files over arbitrary URLs, avoid exporting attacker-supplied resume content to HTML without sanitization, review generated resume changes carefully, and consider pinning dependencies before use.
scripts/parse_jd.py:19Server-Side Request Forgery Through Unrestricted Job Description URL Fetching
scripts/export_resume.py:207Stored Active-Content Injection in Exported HTML Resumes
{' | '.join(contact_line)}
\n" if contact.get("linkedin"): html += f"LinkedIn: {contact['linkedin']}
\n" if contact.get("website"): html += f"Website: {contact['website']}
\n" html += '{resume_data['summary']}
\n" html += '{exp.get('start_date', '')} - {exp.get('end_date', 'Present')}
\n" if exp.get("description"): html += "scripts/parse_resume.py:156Resume Personal Information Disclosed Through Standard Output
SKILL.md:8Unpinned and Overbroad Runtime Dependency Installation
The core purpose broadly aligns: the script customizes a resume against a job description, performs skill matching, computes match percentage, reorders sections/skills, adjusts summary text, and optionally adds ATS-related metadata. However, the description materially overstates several capabilities. There is no parsing or generation of PDF, Word, Markdown, HTML, or plain text resumes—only JSON input and output. Chinese/English support is not a real implemented feature beyond standard UTF-8 file handling. Industry-specific customization is not actually performed; the provided industry value is merely recorded in metadata. Because these are prominent declared features rather than minor details, this is a description-behavior mismatch.
The declared description promises a resume-tailoring system with substantive matching and optimization capabilities, but this code chunk is a formatter/exporter only. It reads a JSON resume and renders it into several output formats. The --template and --ats-friendly arguments are accepted, but no template logic or ATS-formatting behavior is implemented beyond a note printed to stdout. PDF export is explicitly not fully implemented and falls back to HTML. There is no evidence of job description input, comparison logic, keyword extraction, skill-gap analysis, industry adaptation, or language-specific handling for Chinese and English. Therefore, the code materially underdelivers relative to the declared purpose, making the description inaccurate for this chunk.
The description overstates the implemented functionality. The supplied code only performs ATS-oriented keyword extraction and insertion on structured JSON resume/JD data. It does not implement the declared multi-format resume support, broad tailoring workflow, industry customization, or explicit Chinese/English resume handling. ATS optimization and basic keyword analysis are consistent with the description, but the actual code is materially narrower than the declared purpose, so this is a mismatch.
The declared description presents a resume optimization/tailoring skill whose primary function is to adapt resumes to specific job descriptions across multiple resume formats. The supplied code does something materially different: it only ingests a job description from various sources, extracts basic structured information and keyword matches, and saves the result as JSON. While there is slight thematic overlap in that JD parsing could support a resume-tailoring pipeline, the actual code lacks any resume parsing, editing, generation, ATS optimization, or industry-specific customization logic. Therefore the description does not accurately represent this code chunk's primary behavior.
The declared purpose centers on modifying or optimizing resumes for target job descriptions, including analysis and customization features. The supplied code instead implements a resume parser/converter: it reads resumes from multiple file formats, extracts raw text and a few basic structured fields, and writes JSON output. Multi-format input support does align partially with the description, and the text parser's UTF-8/GBK fallback may incidentally help with Chinese text, but the primary purpose is materially different. There is no code for taking a job description as input, analyzing ATS keywords, matching skills, customizing content, or generating a tailored resume. Therefore the description substantially overstates and misrepresents the actual behavior.
The skill can be activated by very general conversational phrases such as resume optimization or JD matching requests, without requiring a clear invocation boundary or explicit user confirmation. Overly broad triggering increases the chance of unintended activation, causing the agent to ingest sensitive resume data or perform document-processing actions in contexts where the user did not clearly intend to invoke this skill.
The skill documents file parsing, file creation, and URL-based JD retrieval, but it does not declare any explicit tool scope or permissions boundary. That creates unnecessary ambient authority: an agent could read local files, write sensitive resume outputs, or make network requests without the skill clearly constraining or disclosing those capabilities.
Allowing JD input as an arbitrary URL expands the skill from local document processing into network retrieval, which can be abused to contact untrusted endpoints, leak metadata, or fetch internal resources if not restricted. In a resume-processing context, this is more dangerous because users may provide sensitive workflows and expect purely local handling of personal data.
The natural-language configuration sets "language": "en", which imposes a specific language choice. The file does not indicate that English is user-selected, optional, or justified as a region-specific template, so it may violate language/locale choice policy.
The manifest sets the language to "zh", which enforces a specific output language. Under the policy, forcing a language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified as region-specific.
The function accepts an industry parameter and records it in metadata, but no logic applies industry-specific rules, terminology, formatting, or prioritization anywhere in the customization flow. This means the script claims a capability that is not actually implemented in behavior.
The manifest describes support for PDF, Word, Markdown, HTML, and text resumes, but this implementation accepts only JSON input for both the resume and job description and emits only a JSON output. That is a substantive behavior mismatch rather than an implementation detail, because the advertised end-user capability is absent from the code.
The skill manifest describes multi-format support including PDF, but the PDF export path only prints warnings and falls back to generating an HTML file instead of a PDF. This is a direct mismatch between the advertised capability and the code's actual behavior.
The --ats-friendly argument is documented as ensuring ATS-friendly formatting, and the program later prints that ATS-friendly formatting was applied. However, no code changes formatting logic based on this flag, so the documentation and status message contradict the actual behavior.
This code writes an optimized resume JSON file containing altered user resume content, which affects personal data and document integrity. While the script's purpose is optimization, the code lacks any explicit warning, confirmation, or disclosure that it will automatically inject keywords into skills, summary, and work-experience fields before saving the result.
This code writes extracted resume contents, including contact details and full raw text, to a JSON file. Although the script logs success, it does not warn the user that sensitive personal data from the resume will be persisted to disk, which is a safety-relevant disclosure gap for a code file handling personal data.
The skill advertises URL-based JD parsing without clearly warning that using a URL will trigger external network access. That can surprise users, disclose that a URL was accessed from the agent environment, and violate expectations of local-only processing for a personal-document workflow.
The skill describes generating customized resume output files but does not clearly warn that it will write new files containing sensitive personal information. In the context of resumes, silent file creation increases privacy and data-retention risk, especially on shared systems or agent-managed workspaces.
The JSON explicitly sets the skill/example language to "en", which is a natural-language locale constraint. Under the policy, forcing a specific language without user opt-in can be a language or locale policy violation, and this file does not indicate any choice mechanism or justification for the restriction.
This JSON manifest-like example explicitly labels the content as Chinese and sets the language to "zh". Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is clearly documented and justified.
This manifest-like JSON specifies "language": "en", which enforces a specific language setting in natural-language content. Under the policy rules, locale or language constraints should either be optional, user-selectable, or clearly justified as region-specific.
This manifest-like JSON defines a template named "professional-en" and sets the language to "en" without any stated limitation, fallback, or exclusion context. In a template-selection or activation system, this can act as a broad English-only selector without clarifying when users should or should not receive it.
The template name and language fields explicitly specify English only, and the description frames the template as a standard default rather than documenting a user-selected locale. Per the policy, forcing a specific language without opt-in is a natural-language locale constraint that should be disclosed or made optional.
No suspicious patterns detected.