Back to skill

Security audit

Offer 助手

Security checks for vulnerabilities and agentic risk

Overview

This is a plausible resume assistant, but it automatically persists sensitive resume and job-search data to Feishu and includes unsafe helper scripts, so users should review it carefully before installing.

Install only if you are comfortable with resume, contact, JD, application, and interview data being extracted and potentially stored in Feishu. Before use, confirm the Feishu account and folder, avoid automatic document creation until after reviewing extracted data, and consider fixing the PDF scripts and dependency installation first.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/workflow.js:142
Finding
Shell Command Injection Through User-Controlled PDF Paths<![CDATA[ ## Vulnerability Details **File Location**: `scripts/workflow.js:142-146` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```javascript const scriptPath = path.join(__dirname, 'generate-pdf.js'); const cmd = `node "${scriptPath}" "${path.resolve(html)}" ${output ? `"${path.resolve(output)}"` : ''}`; const { execSync } = require('child_process'); try { execSync(cmd, { cwd: WORKSPACE, stdio: 'inherit', timeout: 60000 }); ``` ### Technical Analysis The HTML input path and optional output path are incorporated into a command string that is executed through `execSync()`. String-based `execSync()` invokes a command shell. Although the paths are passed through `path.resolve()`, path resolution does not escape embedded quotation marks, command separators, command substitutions, or other shell metacharacters. On filesystems that permit such characters, an attacker-controlled filename can terminate the intended quoted argument and append another shell command. The vulnerable values originate from command-line arguments: ```javascript const html = args[pdfIdx + 1]; const output = args[pdfIdx + 2]; ``` Consequently, any caller able to influence the supplied input or output filename can potentially inject commands. ### Attack Path 1. An attacker creates or supplies an HTML file with a shell-sensitive filename, such as one containing a quotation mark and command separator. 2. The Agent or user invokes: ```bash node scripts/workflow.js --pdf '<attacker-controlled-path>' ``` 3. `path.resolve()` converts the path to an absolute path but preserves the shell-sensitive filename characters. 4. The application places the path inside the `cmd` string. 5. `execSync()` passes the resulting string to a shell. 6. The shell interprets the injected syntax and executes the attacker's command in addition to, or instead of, the PDF generator. An equivalent attack is possible through the optional output path. ### Impact ...[truncated 613 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Avoid constructing a shell command. Invoke Node.js directly with an argument array: ```javascript const { execFileSync } = require('child_process'); const resolvedHtml = path.resolve(html); const childArgs = [scriptPath, resolvedHtml]; if (output) { childArgs.push(path.resolve(output)); } execFileSync(process.execPath, childArgs, { cwd: WORKSPACE, stdio: 'inherit', timeout: 60000 }); ``` Additional hardening should include: 1. Verify that the input is a regular file and has an expected `.html` extension. 2. Restrict input and output paths to an approved workspace directory using `path.relative()`. 3. Reject null bytes and paths that escape the approved directory. 4. Refuse to overwrite existing files unless explicitly requested. 5. Do not reintroduce `shell: true` when invoking the child process. 6. Add regression tests using filenames containing quotes, semicolons, dollar signs, backticks, spaces, and command-substitution syntax. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate-pdf.js:59
Finding
Resume Data Exposed Through an Unrestricted Local HTTP Server and Unsandboxed Browser<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-pdf.js:59-96` **Vulnerability Type**: Insecure local service exposure and unsafe browser isolation **Risk Level**: Medium ### Vulnerable Code ```javascript const chrome = spawn(findChrome(), [ '--headless', '--disable-gpu', '--no-sandbox', `--remote-debugging-port=${CDP_PORT}`, '--disable-extensions', '--disable-background-networking', '--disable-sync', '--no-first-run' ], { detached: true, stdio: 'ignore' }); ``` ```javascript (async () => { const html = fs.readFileSync(absHtmlPath, 'utf-8'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.end(html); }); server.listen(HTTP_PORT); ``` ### Technical Analysis The script reads the complete resume HTML into memory and starts an HTTP server that returns it for every request. `server.listen(HTTP_PORT)` does not specify a loopback address. Depending on the host's Node.js and network configuration, the service can listen on an unspecified address and become reachable through network interfaces other than localhost. The served document can contain sensitive resume information such as names, phone numbers, email addresses, education history, and employment history. The server has no authentication, request token, path restriction, or client validation. The browser is also started with: ```text --no-sandbox ``` Disabling Chrome's sandbox removes an important containment boundary. If attacker-controlled resume HTML, scripts, external resources, or a browser vulnerability compromises the renderer, the impact can extend to the operating-system account running the Skill. The implementation additionally uses fixed ports: ```javascript const CDP_PORT = 9225; const HTTP_PORT = 18772; ``` Fixed ports make local discovery and interference easier and can cause the script to connect to a pre-existing or attacker-controlled service when a port collision ...[truncated 1689 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind the HTTP server explicitly to loopback: ```javascript server.listen(0, '127.0.0.1', () => { const { port } = server.address(); // Navigate to the dynamically allocated port. }); ``` 2. Use dynamically assigned ports rather than fixed values for both the document server and CDP. 3. Require a cryptographically random URL token and return `404` for any other path: ```javascript const crypto = require('crypto'); const token = crypto.randomBytes(32).toString('hex'); ``` 4. Serve the document only once, then immediately close the HTTP server. 5. Remove `--no-sandbox`. If the environment cannot run Chrome with its sandbox enabled, use a dedicated container or similarly isolated low-privilege runtime instead. 6. Create a unique temporary Chrome user-data directory for every run and delete it afterward. 7. Reject or sanitize active content in generated resume HTML. Block scripts, remote frames, and unnecessary external resources. 8. Add explicit server error handling for port conflicts and ensure cleanup runs in a `finally` block. 9. Ensure CDP is loopback-only and inaccessible to other network hosts. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/setup.sh:21
Finding
Unpinned Dependency Installation With Global Fallback<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:21-27` **Vulnerability Type**: Unsafe dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash # --- ws (WebSocket) --- if node -e "require('ws')" 2>/dev/null; then echo "✅ npm ws: 已安装" else echo "📦 安装 ws..." npm install ws 2>/dev/null || npm install -g ws 2>/dev/null || { echo "⚠️ ws 安装失败,请手动执行: npm install ws" } fi ``` ### Technical Analysis The setup script installs `ws` without specifying an exact version and without using a committed lockfile or integrity-controlled installation process. The effective package version therefore depends on the registry state at installation time and can change after the Skill has been reviewed. The fallback to: ```bash npm install -g ws ``` increases the installation scope from the project to the user's global npm environment. This can modify shared package state and may require or encourage elevated permissions in some environments. The script also does not disable npm lifecycle scripts. If a resolved package or transitive dependency contains installation hooks, those hooks can execute with the privileges of the user running setup. No evidence shows that the legitimate `ws` package is malicious. The vulnerability is the mutable, unpinned supply-chain installation process rather than a confirmed malicious package. ### Attack Path 1. A user follows the documented setup process and runs `bash scripts/setup.sh`. 2. The local environment does not already resolve `require('ws')`. 3. The script requests the current registry version of `ws` without an exact version or lockfile. 4. npm resolves and downloads the package and applicable dependencies from the configured registry. 5. A compromised release, registry response, dependency, or lifecycle hook executes during installation. 6. If local installation fails, the script attempts a global installation, broadening the affected environment. ### Impact Assessment A com ...[truncated 630 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a project-local `package.json` containing an exact audited version of `ws`. 2. Commit a generated `package-lock.json`. 3. Replace mutable installation with: ```bash npm ci --ignore-scripts ``` 4. Remove the global installation fallback. 5. Verify that the installed dependency resolves from the project-local `node_modules`. 6. Review dependency provenance and update versions through a controlled review process. 7. Use registry integrity metadata and dependency scanning in continuous integration. 8. If lifecycle scripts are required by future dependencies, review them explicitly rather than enabling them globally. 9. Document the supported dependency version instead of relying on the registry's current latest release. ]]>

other

Warning
Location
config/guide.md:18
Finding
Automatic Persistence of Sensitive Resume Data to a Fixed External Cloud Folder<![CDATA[ ## Vulnerability Details **File Location**: `config/guide.md:18-24` **Vulnerability Type**: Privacy-sensitive automatic cloud storage **Risk Level**: Medium ### Vulnerable Instructions ```markdown ### 检测到简历文件/图片时 自动执行: 1. 提取内容(OCR / 文本解析) 2. 拆解为模块化素材库(教育 / 工作经历 / 项目 / 技能) 3. 调用 `scripts/create-material-doc.js` 自动创建飞书文档作为素材库 4. 输出给用户:「素材库已建立,共提取了 X 段工作经历、Y 个项目。你看一下有没有遗漏?」 ``` The destination and sensitive fields are further defined in `scripts/create-material-doc.sh:9-18,38-42`: ```bash # agent 内部处理:提取简历 → 调用 feishu_create_doc 创建素材库文档 # → 写入求职 2026 文件夹 # # 素材库文档模板结构(由 Agent 填充内容): # # 【素材库】 # 创建时间:YYYY-MM-DD # # == 基础信息 == # - 姓名: # - 手机: # - 邮箱: # - 城市: ``` ```bash echo "⚠️ 此脚本为接口声明,实际执行由 Agent 通过 feishu_create_doc 完成" echo "Agent 需要:" echo " 1. 提取简历内容" echo " 2. 调用 feishu_create_doc 创建素材库文档" echo " 3. 调用 feishu_drive_file move 将文档移入求职 2026 文件夹 (AYCEfx1x0lCjBYdlz8MctUw1nyh)" ``` ### Technical Analysis The hidden Agent guide instructs the Agent to create an external Feishu cloud document automatically when a resume is detected. The workflow performs storage before asking the user to review the result. The associated template includes direct identifiers such as name, phone number, email address, and city. It also stores education, employment, and project history. The document is moved to a hardcoded folder identifier: ```text AYCEfx1x0lCjBYdlz8MctUw1nyh ``` The workflow does not require the Agent to: - Obtain explicit consent before external upload. - Verify that the destination belongs to the current user. - Display the destination tenant, account, folder, or sharing permissions. - Minimize which personal fields are stored. - Define retention or deletion behavior. - Confirm whether the user wants persistent cloud storage. The public Skill description mentions permanent storage, but it does not adequately establish informed consent for automatic storage in a specific third-party cloud destination or for the inclusion of contact det ...[truncated 1259 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit, informed opt-in before creating any external cloud document. 2. Show the user: - The external service name. - The authenticated account or tenant. - The target folder. - The fields that will be uploaded. - The intended retention period and sharing permissions. 3. Verify that the fixed folder belongs to the current user; preferably eliminate hardcoded destination identifiers and require user selection. 4. Exclude phone number, email address, and other direct identifiers by default. 5. Provide a local-only storage option. 6. Create the cloud document only after the user confirms the parsed content and destination. 7. Apply least-privilege document permissions and disable public-link sharing by default. 8. Provide clear export, correction, and deletion controls. 9. Record consent and the selected destination without storing unnecessary personal data. 10. Update the Agent guide so review occurs before persistence rather than after document creation. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (40)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description focuses on resume processing: turning an old resume into a permanent materials library, generating customized resumes and PDFs for job descriptions, and mock interview support. The supplied code chunk does not implement resume generation, PDF creation, or interview simulation. Instead, it declares a JD-analysis workflow centered on extracting JD text, performing external company research, evaluating fit against a materials library, and creating/storing a岗位分析手册 document in Feishu. While JD matching is adjacent to the stated resume workflow, the code introduces undeclared capabilities and a materially different immediate purpose: job/company analysis and document creation rather than resume tailoring. Therefore this is a description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
声明描述的是一个覆盖简历解析、素材库管理、岗位匹配、定制生成、PDF 导出和模拟面试的完整助手;而实际代码只完成其中很小的一部分——将现有 HTML 简历页面导出为 PDF。虽然“生成干净 PDF”与声明中的一项功能一致,但该代码没有体现任何简历解析、JD 匹配、内容生成、素材库管理或面试模拟能力。因此代码的实际主要用途与声明的整体能力范围存在明显不一致,属于描述与行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared description focuses on resume generation from a permanent materials library, JD-based tailoring, clean PDF output, and mock interviews. The supplied code does not implement or declare behavior for resume parsing, materials library management, JD matching, resume generation, or PDF creation. Instead, it defines an interface for interview recap logging and application tracking: collecting company/role/interview result details, appending an interview record section to documentation, and updating application status. While mock interviews are loosely adjacent to interviewing, this code is specifically for post-interview recordkeeping and delivery tracking, which is a materially different purpose and an undeclared capability.

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding
The declared description presents an end-user resume-processing and job-application assistant. The supplied code does not implement resume parsing, materials library creation, JD matching, resume generation, PDF export, or mock interview functionality. Instead, it performs environment setup by checking for external binaries and installing an npm dependency. While setup logic can support a larger application, this chunk’s actual behavior is materially different from the declared primary purpose and includes system-level dependency detection/installation capabilities not reflected in the description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
声明描述的是一个内容智能处理型简历助手,重点在素材库构建、JD 匹配、定制简历生成、PDF 产出和面试模拟。而这段代码仅实现了一个简历交付 SOP 的命令行步骤管理器:维护会话状态、显示进度、重置/完成步骤,以及调用外部脚本做 PDF 生成。除“可生成 PDF”这一点部分相关外,绝大多数核心宣称能力都没有在代码中体现。代码的主要用途与描述的主要用途存在明显偏差,因此应判定为不匹配。

Unvalidated Output Injection

High
Category
Output Handling
Content
* Examples:
 *   node scripts/generate-pdf.js ./resume.html ./resume.pdf
 *   node scripts/generate-pdf.js /path/to/resume.html
 *   node scripts/generate-pdf.js ./resume.html  (output defaults to ./resume.pdf)
 */

const http = require('http');
Confidence
80% confidence
Finding
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The manifest description and the entire user-facing instructions are written in Chinese, and the metadata/topics emphasize Chinese usage, but there is no statement that users may choose another language or that the tool is intentionally limited to a Chinese-only region/compliance context. This can constitute a language/locale policy issue under the stated rule.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill advertises persistent storage of resumes, interview history, and job-search records in a 'permanent' materials library without any clear disclosure of retention, access scope, deletion controls, or privacy implications. This is dangerous because these records contain highly sensitive personal and career data that could be exposed, over-retained, or reused beyond user expectations.

Ssd 3

Medium
Confidence
96% confidence
Finding
The document explicitly describes indefinite retention and reuse of resume and interview data in a permanent library/archive, which creates unnecessary long-term exposure of sensitive personal information. In the career-assistant context, this includes employment history, education, interview performance, and application strategy, all of which may be damaging if later accessed, correlated, or breached.

Ssd 3

Medium
Confidence
94% confidence
Finding
Automatic archival of interview records and application history increases the volume and persistence of sensitive career data without showing any user approval, retention boundary, or confidentiality safeguard. This is risky because even seemingly routine logs can reveal job-search intent, negotiation posture, weaknesses identified in mock interviews, and other sensitive personal signals.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The guide instructs the agent to automatically parse uploaded resume files or images and create a Feishu document, but the user is not warned in advance that their personal data will be extracted, structured, and transmitted to an external document platform. Because resumes commonly contain sensitive personal and employment information, silent automation materially increases privacy and data-handling risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The guide directs the agent to fetch JD content from links and combine it with online company-information lookups without clearly notifying the user. This can trigger network access and third-party data retrieval based on user-supplied content, which may surprise users, expose browsing targets, or process unintended URLs beyond their expectations.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrase set for resume generation is overly broad, including generic terms like '生成', '出 PDF', and '做一份'. In a chat context, these phrases can easily appear in ordinary conversation and cause the agent to generate resume artifacts or invoke downstream scripts without clear, current user intent, creating unintended data processing and external side effects.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The methodology expands the skill from resume/JD matching into external company intelligence gathering and persistent tracking-document creation, which increases data collection and handling beyond the user-visible purpose. This creates scope creep and privacy risk, especially because JD text, company research, and later interview notes may contain sensitive personal or employment-related information without explicit user consent or data-minimization guidance.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The file explicitly instructs creating a persistent Feishu document, which causes user/job-application data to be written to an external system without any stated necessity, consent gate, retention limit, or access-control warning. In a resume assistant context, this is risky because users may not expect their JD contents, application strategy, and related notes to be permanently stored outside the current session.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The instructions say to create and append to a Feishu document containing JD text, analysis, and interview records, but provide no warning that this is persistent storage of potentially sensitive employment data. This omission undermines informed consent and can expose personal career plans, interview performance, and employer-specific information to unnecessary retention or broader access within the external platform.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This markdown file is natural-language guidance, and its instructions are presented exclusively in Chinese. Under the policy rule for language or locale constraints, forcing a specific language without user opt-in can be a policy violation when no alternative or justification is provided.

Natural-Language Policy Violations

Medium
Confidence
81% confidence
Finding
The file is written as a prescriptive methodology titled and described entirely in Chinese, including an absolute statement that this is the 'only reliable way,' but provides no indication that language choice is optional or that the locale restriction is intentional for a region-specific use case. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The document advises killing residual Chrome processes as a troubleshooting step without any guardrails, scope limitation, or warning that this may terminate unrelated user/browser sessions and cause data loss. In an agent skill context, operational instructions can be automated or followed literally, making unsafe process-termination guidance more dangerous than a casual human-only note.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The title and opening instruction are written entirely in Chinese and present the methodology as a mandatory document to follow before every resume edit. There is no indication that users may choose another language or locale, which can violate language-choice policy when applied as a general skill reference.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This skill instructs the agent to extract, structure, and persist highly sensitive resume data including name, phone number, email, city, education, employment history, and projects, but it does not require any privacy notice, consent step, minimization rule, retention limit, or secure-handling guidance. Because the workflow explicitly creates a long-lived '素材库' and allows incremental version storage, it increases the risk of unnecessary collection and prolonged retention of personal data beyond what the user may reasonably expect.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly describes storing job application history and interview notes in session context and potentially in persistent documents, but it does not require clear user consent, retention limits, or any privacy notice. These records can contain sensitive career data, interviewer impressions, compensation discussion, and self-assessment notes that could be exposed, retained longer than expected, or reused in ways the user did not anticipate.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script defines an agent workflow that automatically creates a Feishu document and moves it into a specific folder whenever a JD is detected, but it does not require explicit user confirmation before modifying user data or files. Even though this file is framed as an interface declaration rather than executable logic, it still instructs the agent to perform write-side actions automatically, which can lead to unexpected document creation, unwanted organization changes, or persistence of sensitive job-search data.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script explicitly describes automatic extraction of resume content and creation of a Feishu document containing highly sensitive personal data such as name, phone, email, city, education, and work history. Even though this file is only an interface declaration, it documents a workflow that processes and stores personal data without any mention of user consent, privacy notice, data minimization, retention limits, or access controls, which creates a real privacy and compliance risk.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This shell script includes comments, usage instructions, and console output only in Chinese, which imposes a specific language on users. The policy allows locale constraints only when users are given a choice or the constraint is clearly documented and justified, neither of which appears here.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/generate-pdf.js:59

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/workflow.js:146