Back to skill

Security audit

Ai Talent Grader

Security checks for vulnerabilities and agentic risk

Overview

This AI hiring-evaluation skill is mostly purpose-aligned, but it broadly processes sensitive applicant data and saves reports by default without enough privacy, retention, or path-safety controls.

Review before installing. Use it only with explicit permission to process applicant materials, prefer a virtual environment, pin or review dependencies, keep candidate files and generated reports in a controlled directory, avoid untrusted candidate IDs or output paths, and delete reports according to your hiring-data retention policy.

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
install.sh:37
Finding

Unpinned and Unnecessary Third-Party Dependencies Increase Supply-Chain Exposure

Content
View full analysis

Vulnerability Details

File Location: install.sh:37-39; requirements.txt:1-11
Vulnerability Type: Unpinned dependency installation
Risk Level: Medium

Vulnerable Code

install.sh:37-39:

bash
if [[ -f "requirements.txt" ]]; then
    pip install -r requirements.txt
    echo "✓ 依赖安装完成"

requirements.txt:1-11:

text
pypdf2>=3.0.0
python-docx>=0.8.11
pyyaml>=6.0
jinja2>=3.1.0
openai>=1.0.0
pandas>=2.0.0
openpyxl>=3.1.0
rich>=13.0.0
pydantic>=2.0.0
loguru>=0.7.0
click>=8.1.0

Technical Analysis

The installation script installs dependencies directly from the package index using mutable lower-bound constraints. There is no lockfile, exact version pinning, hash verification, or configured package-index restriction.

Constraints such as openai>=1.0.0 allow any future version satisfying the lower bound to be installed. Consequently, two installations performed at different times can execute materially different third-party installation and runtime code, even when the audited project itself has not changed.

The audit also found no imports of openai, pandas, openpyxl, jinja2, rich, pydantic, or click in the project. Installing these unused packages unnecessarily expands the number of package maintainers, transitive dependencies, and installation hooks that must be trusted.

This finding does not establish that any listed package is currently malicious. The vulnerability is the absence of reproducible dependency controls and the unnecessary expansion of the dependency attack surface.

Attack Path

  1. A user executes install.sh.
  2. The script invokes pip install -r requirements.txt.
  3. The package resolver selects the newest releases satisfying the open-ended >= constraints.
  4. If an allowed package release or one of its transitive dependencies has been compromised, its installation or imported runtime code executes.
  5. That code runs w ...[truncated 624 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove dependencies that are not imported or otherwise required, particularly openai, pandas, openpyxl, jinja2, rich, pydantic, and click.
  2. Pin every direct dependency to an exact, reviewed version instead of using unrestricted lower bounds.
  3. Generate a lockfile that records all transitive dependency versions.
  4. Use hash verification, such as a requirements file generated with hashes and installed using pip install --require-hashes.
  5. Configure an approved package index or internal mirror rather than implicitly trusting every package source configured in the environment.
  6. Install dependencies inside a dedicated virtual environment with minimal filesystem and credential access.
  7. Add automated dependency vulnerability and provenance scanning to the release process.
  8. Review and deliberately update pinned dependencies on a controlled schedule.

T09 · Insecure Skill Coding Practices

Warning
Location
main.py:130
Finding

Unsanitized Candidate Identifier Permits Default Report Path Traversal

Content
View full analysis

Vulnerability Details

File Location: main.py:130-133, main.py:467-469; modules/report_generator.py:280-285
Vulnerability Type: Path traversal and unintended file overwrite
Risk Level: Medium

Vulnerable Code

main.py:130-133:

python
if output_path is None:
    output_path = f"report_{candidate_id}_audit.md"

self.report_generator.save_report(report, output_path)

main.py:467-469:

python
audit_parser.add_argument('--resume', required=True, help='简历文件路径')
audit_parser.add_argument('--id', default='', help='候选人编号')
audit_parser.add_argument('--output', help='报告输出路径')

modules/report_generator.py:280-285:

python
def save_report(self, report: str, output_path: str, format: str = 'md'):
    """保存报告到文件"""
    path = Path(output_path)
    path.parent.mkdir(parents=True, exist_ok=True)
    with open(path, 'w', encoding='utf-8') as f:
        f.write(report)
    logger.info(f"报告已保存: {output_path}")

Technical Analysis

The CLI accepts an unrestricted candidate identifier through --id. When the caller does not provide an explicit output path, this identifier is interpolated directly into the default report filename.

The identifier is not restricted to a filename-safe character set. It can therefore contain path separators and .. components. Although the generated path begins with report_, an attacker can first create a normal path component and then traverse upward through later components. For example:

text
--id 'x/../../../tmp/audit'

This produces a default path resembling:

text
report_x/../../../tmp/audit_audit.md

save_report() then creates parent directories and opens the resulting path in write mode. There is no canonical-path containment check, no rejection of traversal components, and no exclusive-create protection. An existing writable file at the resolved destination can consequently be truncated and replac ...[truncated 1464 chars]

Remediation
View remediation

Remediation Suggestions

  1. Restrict candidate identifiers to a filename-safe allowlist:
python
import re

if not re.fullmatch(r"[A-Za-z0-9_-]+", candidate_id):
    raise ValueError("Candidate ID contains unsupported characters")
  1. Store generated reports under a dedicated, application-controlled output directory.
  2. Resolve both the output root and candidate path, then verify containment before writing:
python
output_root = Path("reports").resolve()
target = (output_root / f"report_{candidate_id}_audit.md").resolve()

if output_root not in target.parents:
    raise ValueError("Output path escapes the report directory")
  1. Reject absolute paths, path separators, . components, and .. components in identifiers used for filenames.
  2. Use a server-generated opaque identifier or a sanitized slug rather than using externally supplied identifiers directly.
  3. Where overwriting is not required, open reports in exclusive creation mode or require explicit confirmation before replacing an existing file.
  4. Apply the same containment validation to batch output paths and any future filename fields derived from candidate-controlled data.
  5. Add tests covering Unix and Windows path separators, nested traversal, absolute paths, drive-letter paths, and symbolic-link edge cases.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (49)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述的是一个高层候选人评估/定级系统,核心在分析、评分、分级、生成面试问题与复盘;但提供的代码只是底层文件解析模块,功能集中在多格式文件读取和少量结构化字段提取。虽然解析简历和面试记录可作为该系统的支持组件,但就当前代码块本身而言,其实际行为与声明的主要用途存在显著差异:没有任何L1-L4分级、AI能力评估、评分卡、认知分析、JD比对或题目生成逻辑。因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

声明描述的是一个完整的候选人AI能力分级与认知分析系统,核心输入应包括简历、面试记录和JD,输出应包括L1-L4定级及多维评分与复盘。而当前代码块只是“resume_audit”模块,功能集中在简历文本风险审计和测谎题生成,这与声明中的“简历漏洞穿透审计、测谎面试题生成”部分一致,但远不足以支撑其宣称的主要用途。由于声明强调的是综合定级/认知分析系统,而代码仅覆盖其中一个子能力,存在明显描述-行为不匹配。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README instructs users to upload resumes and interview records, which commonly contain sensitive personal data such as contact details, employment history, and interviewer notes, but it provides no privacy, retention, access control, or consent guidance. In the context of an automated candidate-evaluation skill, this omission increases the risk of improper collection, overexposure, and mishandling of personal data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill advertises operational workflows that read resumes and interview transcripts and may generate reports, but it does not declare any explicit tool scope such as permissions or allowed-tools. Missing scope controls increases the risk that the runtime grants broader file read/write access than reviewers or users expect, especially because the skill explicitly discusses batch processing and report generation over local files.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The activation text is broad enough to trigger on generic resume review or scoring requests, which can cause the skill to process sensitive candidate data outside its stated niche of AI-talent grading. Overbroad triggering is risky in hiring contexts because it may lead to unintended collection, analysis, or retention of personal and potentially sensitive employment information.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The statement that the skill auto-triggers whenever users upload resumes or interview records is ambiguous and lacks firm scope boundaries. In practice, this can over-activate on highly sensitive hiring materials, increasing privacy and inappropriate-use risk, especially because the skill claims deep auditing, contradiction detection, and lie-oriented questioning features.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This YAML config applies a single default language value of "zh-CN" with no nearby indication of user choice, fallback by preference, or region-specific justification. In configuration and manifest-like files, this creates an ambiguous global behavior that may unintentionally force Chinese output for all users and contexts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language policy requires avoiding forced language or locale constraints unless users can choose or the restriction is clearly justified. The setting default_language: "zh-CN" indicates a fixed locale, and the file does not document any opt-in mechanism or regional compliance reason.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

All user-facing strings in the installer are in Chinese, including prompts, warnings, and usage instructions. This creates a natural-language locale restriction for users without any opt-in, fallback language, or documented justification that the skill is intended only for a Chinese-speaking audience.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The program automatically writes candidate assessment reports to disk, and those reports likely contain highly sensitive applicant data derived from resumes and interview notes. In an HR evaluation context, silent persistence increases the risk of unauthorized retention, accidental sharing, backup exposure, and noncompliance with privacy requirements.

Content

No source excerpt is available for this finding.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · main.py (reported line 406)May include surrounding context.

python
"""生成批量处理汇总"""
        lines = [
            "# 批量评估汇总\n",
            f"处理时间: {__import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
            f"总候选人: {len(results)}\n",
            "| 候选人 | 状态 | 级别 | 备注 |",
            "|--------|------|------|------|",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The batch summary is automatically persisted and aggregates multiple candidates' statuses and levels into a single file, creating a concentrated privacy and confidentiality risk. In this skill's hiring-assessment context, aggregation makes exposure more damaging because one file can reveal results for many applicants at once.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code file contains user-facing natural-language strings, comments, docstrings, and logs exclusively in Chinese, including the module description and runtime messages. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code processes resume and interview files into structured candidate records, including raw text and metadata, which implies handling potentially sensitive personal information. There is no confirmation prompt, user-facing disclosure, or warning in this file indicating that personal data from those documents will be read and retained in memory/returned in structured form.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code contains natural-language strings entirely in Chinese, including the module description and verification statuses, with no indication that the skill is China-specific or that users can opt into the locale. Under the policy, forcing a specific language without user choice or documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstrings, headings, labels, and generated report text are all hard-coded in Chinese, indicating the skill produces Chinese-language reports by default. There is no visible option, opt-in, or documented justification for restricting output language, which can violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module title and all user-facing categories, conclusions, and generated interview questions are hard-coded in Chinese, indicating the skill is designed to operate in a single language. There is no visible mechanism for user opt-in, locale selection, or documentation justifying a Chinese-only constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file is written as a normative reference and its title explicitly specifies Chinese-language behavioral anchors, with no indication that other languages are supported or that language choice is optional. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file's natural-language instructions, headings, and examples are all in Chinese, and there is no indication that users may opt into another language or that the skill is intentionally limited to a Chinese-language context. Under the language/locale policy, forcing a specific language without user opt-in is a policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document is entirely written in Chinese and implicitly assumes Chinese-language interaction without any user opt-in or fallback. In a general-purpose agent skill, this can override user language expectations, degrade transparency of evaluation criteria, and cause users or downstream agents to misunderstand scoring rules or outputs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This markdown template is entirely written as Chinese report output formats, including fixed Chinese headings and labels, but it does not state that Chinese is optional, user-selected, or required for a region-specific workflow. That creates a natural-language locale policy concern because the skill appears to enforce a specific language by default.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This markdown file contains natural-language guidance exclusively in Chinese, and nowhere indicates that the skill is region-specific or that users may choose another language. Under the policy rule for language or locale constraints, forcing a specific language without opt-in is a reportable issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This Python file contains natural-language descriptions that force a specific language/locale for users, such as the module docstring and CLI help text being only in Chinese. The policy for SQP-3 flags language/locale constraints when the skill does not offer the user a choice or document a justified regional scope.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

All user-facing documentation in this file is presented only in Chinese, and there is no indication that language selection is optional or that the skill is intended solely for a justified Chinese-language context. Under the policy, forcing a specific language without user opt-in can be a natural-language locale violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module description, usage examples, CLI descriptions, and help strings are all presented only in Chinese. This effectively forces a specific language for users without an explicit opt-in or documented region-specific justification, which matches the language/locale policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.