Back to skill

Security audit

AI员工协作技能包

Security checks for vulnerabilities and agentic risk

Overview

This AI team-management skill is mostly coherent with its stated purpose, but its local file handling is under-scoped and can escape intended directories through unvalidated inputs.

Install only if you are comfortable with a local prototype that writes persistent config and memory files. Use it in a dedicated workspace with non-sensitive data, avoid untrusted employee role/template inputs, and review or patch path validation and deletion/retention controls before using it with business or private information.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/employee-manager.js:53
Finding
Path Traversal Through Attacker-Controlled Employee Role and Identifier<![CDATA[ ## Vulnerability Details **File Location**: `scripts/employee-manager.js`, lines 53–82 **Vulnerability Type**: Path traversal leading to unauthorized directory creation and file writes **Risk Level**: High ### Vulnerable Code ```javascript hire(config) { const { name, role, skills = [], model = 'gpt-4', template } = config; if (!name || !role) { throw new Error('员工名称和角色不能为空'); } const id = `${role.toLowerCase().replace(/\s+/g, '-')}-${Date.now()}`; const employee = { id, name, role, skills, model, status: 'idle', createdAt: new Date().toISOString(), currentTask: null, completedTasks: 0, memoryPath: `./memory/${id}` }; // 创建记忆目录 const memDir = path.join(MEMORY_DIR, id); if (!fs.existsSync(memDir)) { fs.mkdirSync(memDir, { recursive: true }); // 创建初始记忆文件 fs.writeFileSync( path.join(memDir, 'memory.md'), `# ${name} - 记忆存储\n\n创建时间: ${new Date().toISOString()}\n\n## 工作记录\n\n`, 'utf8' ); } ``` The unsafe identifier is also reused by other filesystem operations: ```javascript const memDir = path.join(MEMORY_DIR, id); fs.renameSync(memDir, path.join(archiveDir, id)); ``` ```javascript const memFile = path.join(MEMORY_DIR, id, 'memory.md'); fs.appendFileSync(memFile, entry, 'utf8'); ``` ### Technical Analysis The employee identifier is derived directly from the caller-controlled `role` value. The only normalization replaces whitespace with hyphens; it does not reject `..` components, forward slashes, backslashes, or other path syntax. The resulting identifier is passed to `path.join(MEMORY_DIR, id)` and subsequently used by directory creation, file creation, memory append, and archive operations. A role containing traversal components can therefore cause the normalized path to escape the intended `memory/` directory. Appending the current timestamp to the identifier does not prevent traversal. It only changes the final path component after the attacke ...[truncated 1655 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate employee identifiers independently of user-controlled fields, preferably with `crypto.randomUUID()`: ```javascript const { randomUUID } = require('crypto'); const id = randomUUID(); ``` 2. Store the human-readable role only as metadata and never use it as a directory or filename. 3. Introduce a centralized containment check for every filesystem operation: ```javascript function safeChildPath(baseDir, childName) { const base = path.resolve(baseDir); const target = path.resolve(base, childName); if (target !== base && !target.startsWith(base + path.sep)) { throw new Error('Path escapes the permitted directory'); } return target; } ``` 4. If legacy identifiers must be supported, validate them against a strict allowlist such as `/^[a-zA-Z0-9_-]+$/` and reject path separators, `..`, null bytes, and absolute paths. 5. Apply validation not only during hiring, but also before `fire()`, `writeMemory()`, `readMemory()`, and all archive operations. Persisted configuration must be treated as untrusted input. 6. Run the process under a dedicated, least-privileged operating-system account and restrict filesystem permissions to the project’s required data directories. 7. Add tests covering traversal inputs such as `../`, `../../target`, mixed separators, encoded separators, and malicious identifiers loaded from `employees.json`. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/employee-manager.js:85
Finding
Arbitrary Local File Read Through Template Path Traversal<![CDATA[ ## Vulnerability Details **File Location**: `scripts/employee-manager.js`, lines 85–94 **Vulnerability Type**: Template path traversal and unauthorized local file read **Risk Level**: High ### Vulnerable Code ```javascript // 如果提供了模板,复制模板内容 if (template) { const templatePath = path.join(TEMPLATES_DIR, template); if (fs.existsSync(templatePath)) { const templateContent = fs.readFileSync(templatePath, 'utf8'); fs.writeFileSync( path.join(memDir, 'workflow.md'), templateContent, 'utf8' ); } } ``` ### Technical Analysis The programmatic `hire(config)` interface accepts a caller-controlled `template` value and joins it directly to `TEMPLATES_DIR`. There is no allowlist, filename validation, canonicalization, or verification that the resolved path remains inside the templates directory. A template value containing `../` components can escape `TEMPLATES_DIR`. If the resulting path exists and is readable, `fs.readFileSync()` reads it as UTF-8. Its contents are then copied to the employee’s `workflow.md` file. This creates an arbitrary local file-read and file-copy primitive within the permissions of the Node.js process. The CLI shown in this artifact does not expose the template parameter, so exploitation through the reviewed code requires another caller to invoke `hire(config)` programmatically with attacker-controlled configuration. ### Attack Path 1. An attacker gains control over the `template` property supplied to `EmployeeManager.hire()`. 2. The attacker provides a traversal path such as `../../config/sensitive.json`. 3. `path.join(TEMPLATES_DIR, template)` resolves to a file outside the permitted templates directory. 4. `fs.existsSync()` confirms that the external target exists. 5. `fs.readFileSync()` reads the target using the privileges of the Node.js process. 6. The complete contents are copied to `memory/<employee-id>/workflow.md`. 7. Any party or subsequent component able to access that workflow file can ...[truncated 726 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not accept arbitrary template paths. Expose logical template identifiers and map them to explicitly approved files: ```javascript const allowedTemplates = Object.freeze({ boss: 'boss-ai.md', product: 'product-ai.md', tech: 'tech-ai.md' }); const filename = allowedTemplates[template]; if (!filename) { throw new Error('Unknown template'); } const templatePath = path.join(TEMPLATES_DIR, filename); ``` 2. Resolve and verify the final path before reading it: ```javascript const base = path.resolve(TEMPLATES_DIR); const target = path.resolve(base, filename); if (!target.startsWith(base + path.sep)) { throw new Error('Template path escapes the templates directory'); } ``` 3. Reject absolute paths, path separators, `.` and `..` components, null bytes, and unexpected file extensions. 4. Use `fs.realpathSync()` where symbolic links may exist, then verify that the real target remains under the real templates directory. This prevents an approved-looking symlink from pointing outside the directory. 5. Restrict templates to regular files of an expected maximum size and expected extension before reading them. 6. Ensure generated workflow files are not exposed to untrusted users and are created with restrictive permissions. 7. Add security tests for traversal paths, absolute paths, mixed Windows and POSIX separators, symbolic-link escapes, oversized files, and invalid template identifiers. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The skill documentation promises collaboration features like automatic task assignment, progress monitoring, and reporting, but the analyzed behavior reportedly includes undeclared local filesystem read/write and archival operations plus CLI employee-management actions. This mismatch is security-relevant because users may grant trust and permissions based on the stated purpose while the skill performs broader actions that can affect local data and system state.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README states that work records are automatically saved to the memory/ directory and reloaded on startup, but it does not warn users about retention, possible sensitive data accumulation, or how to review and delete stored data. In a multi-agent collaboration skill, stored task history may contain business plans, credentials, customer information, or internal discussions, so silent persistence creates meaningful privacy and security risk.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Advertising persistent memory and real-time status monitoring without disclosing retention, access, deletion, or privacy boundaries can lead users to expose sensitive operational or personal data without informed consent. In a team-automation context, monitored status and long-term memory may contain project details, employee activity, or business secrets, increasing privacy and compliance risk.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The natural-language comments, error messages, logs, and CLI usage are presented only in Chinese throughout the file, which imposes a specific language on users. The file does not offer a language option or explain that the skill is intentionally limited to a Chinese-speaking or region-specific context.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The CLI directly executes the 'fire' command from user input, which removes the employee from the active roster and moves that employee's memory directory to an archive. Although there is a status check and a post-action log message, there is no pre-action confirmation or user-facing warning before this potentially disruptive state-changing operation runs.

Natural-Language Policy Violations

Low
Confidence
85% confidence
Finding
A language policy issue exists when a skill effectively forces a specific language without user opt-in or documented justification. This README presents all instructions, commands context, and operational guidance only in Chinese, with no alternative language option or note that the skill is intended solely for a Chinese-speaking audience.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The natural-language instructions, descriptions, commands, and role explanations are all written in Chinese, which effectively forces a specific language experience. The file does not indicate that this is a China-specific or Chinese-only skill, nor does it offer users an alternative language or explicit opt-in.

Static analysis

No suspicious patterns detected.