Back to skill

Security audit

AI Agent 自省调试框架

Security checks for vulnerabilities and agentic risk

Overview

This debugging skill has a legitimate purpose, but it can automatically change files, permissions, dependencies, and send diagnostic data with weak scoping and control.

Review before installing. Only use this skill in a disposable or tightly sandboxed workspace unless it is changed to ask before writing files, changing permissions, installing packages, or sending reports. Do not configure a webhook with sensitive projects unless reports are redacted and the destination is trusted.

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

T09 · Insecure Skill Coding Practices

Error
Location
introspection-debugger.js:167
Finding

Shell Command Injection Through Automatic Dependency Installation

Content
View full analysis
{ const moduleName = this.extractModuleName(error.message); if (moduleName) { try { await this.execAsync(`npm install ${moduleName}`, { cwd: this.workspace }); return { action: 'installed_dependency', module: moduleName }; } catch (e) { return { action: 'install_failed', module: moduleName, reason: e.message }; } } return null; }, ``` The constructed command is passed to a shell: ```javascript execAsync(cmd, options = {}) { return new Promise((resolve, reject) => { exec(cmd, options, (error, stdout, stderr) => { if (error) reject(error); else resolve(stdout); }); }); } ``` ### Technical Analysis The module name is extracted from an error message and interpolated directly into a shell command. The extraction logic does not enforce valid npm package syntax and does not reject shell metacharacters. Because `child_process.exec()` invokes a shell, control operators, command substitutions, redirections, or other shell syntax embedded in the extracted value can alter the intended command. The automatic error-capture design makes this particularly dangerous because a crafted error can trigger command execution without a separate authorization step. ### Attack Path 1. An attacker causes the application to capture an error whose message matches `MODULE_NOT_FOUND` or `Cannot find module`. 2. The crafted message contains shell syntax in the text parsed by `extractModuleName()`. 3. Root-cause analysis selects the `installDependency` repair method. 4. The extracted value is interpolated into `npm install ${moduleName}`. 5. `exec()` passes the resulting string to the operating-system shell. 6. The injected command executes with the p ...[truncated 418 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
introspection-debugger.js:167
Finding

Automatic Installation of Untrusted and Unpinned Packages

Content
View full analysis
{ const moduleName = this.extractModuleName(error.message); if (moduleName) { try { await this.execAsync(`npm install ${moduleName}`, { cwd: this.workspace }); return { action: 'installed_dependency', module: moduleName }; } catch (e) { return { action: 'install_failed', module: moduleName, reason: e.message }; } } return null; }, ``` ### Technical Analysis A package name inferred from untrusted runtime text is installed automatically. There is no dependency allowlist, version pin, lockfile constraint, integrity verification, registry restriction, or human approval. Installing an npm package can execute lifecycle scripts such as `preinstall`, `install`, and `postinstall`. Consequently, even without exploiting shell metacharacters, an attacker who controls or predicts the extracted package name may cause attacker-controlled package code to execute. The implementation can also modify `package.json`, the lockfile, and `node_modules`, changing the workspace's persistent dependency state. ### Attack Path 1. The attacker publishes or identifies a package containing malicious lifecycle behavior. 2. The attacker causes an error message to match the module-missing rule and identify that package. 3. The debugger automatically invokes `npm install` for the inferred name. 4. npm retrieves the package from the configured registry. 5. Package lifecycle scripts execute with the application's operating-system privileges. 6. The malicious package remains in the workspace and may execute again when imported or during later installations. ### Impact Assessment The issue can lead to supply-chain code execution, theft of credentials available to installation scripts, mo ...[truncated 224 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
introspection-debugger.js:136
Finding

Arbitrary File Creation and Overwrite Outside the Workspace

Content
View full analysis
{ const filePath = this.extractFilePath(error.message); if (filePath && !filePath.includes('node_modules')) { const dir = path.dirname(filePath); await this.ensureDir(dir); const ext = path.extname(filePath); const content = this.getTemplateForExt(ext); fs.writeFileSync(filePath, content); return { action: 'created_file', path: filePath, content: 'template' }; } return null; }, ``` The path is taken directly from quoted error-message content, and directories are recursively created: ```javascript extractFilePath(message) { const match = message.match(/['"`]([^'"`]+)['"`]/); return match ? match[1] : null; } ensureDir(dir) { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } } ``` ### Technical Analysis The destination path comes from an error message and is used without canonicalization or validation against `this.workspace`. Absolute paths and traversal paths can therefore refer to arbitrary locations accessible to the process. The `node_modules` substring check is not a security boundary. It neither confines writes to the workspace nor protects other sensitive locations. In addition, `fs.writeFileSync()` uses overwrite semantics by default, so an existing target is truncated and replaced rather than only creating a genuinely missing file. Recursive directory creation increases the reachable scope by allowing missing parent directories to be created automatically. ### Attack Path 1. An attacker causes the debugger to capture an error matching the `ENOENT` rule. 2. The error message contains a quoted absolute path or traversal path selected by the attacker. 3. `extractFilePath()` returns that path without chec ...[truncated 698 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
introspection-debugger.js:152
Finding

Command Injection and Unauthorized Permission Changes Through chmod

Content
View full analysis
{ const filePath = this.extractFilePath(error.message); if (filePath) { try { // 尝试添加执行权限 await this.execAsync(`chmod +x "${filePath}"`); return { action: 'fixed_permissions', path: filePath }; } catch (e) { return { action: 'permission_fix_failed', reason: e.message }; } } return null; }, ``` The path extraction accepts arbitrary content between quotes: ```javascript extractFilePath(message) { const match = message.match(/['"`]([^'"`]+)['"`]/); return match ? match[1] : null; } ``` ### Technical Analysis The implementation invokes a shell to modify permissions on a path extracted from untrusted error text. Wrapping the value in double quotes does not make it safe: shell constructs such as command substitution can still be evaluated inside double-quoted strings. Independently of command injection, no check ensures that the selected file is inside the workspace or is a file whose executable bit should legitimately be changed. Automatically applying `chmod +x` also assumes that an `EACCES` error is caused by a missing executable bit, although it may have a different cause. ### Attack Path 1. The attacker causes an error message to match the `EACCES` permission-denied rule. 2. The message includes a crafted quoted path containing shell substitution syntax or identifies an arbitrary accessible file. 3. The debugger selects `fixPermissions`. 4. The path is interpolated into a command executed by `child_process.exec()`. 5. The shell evaluates injected syntax, or `chmod` changes the permissions of the attacker-selected file. 6. The resulting command execution or permission change occurs with the Node.js process's privileges. ### Impact Assessment ...[truncated 357 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
introspection-debugger.js:329
Finding

Unredacted Error Reports Can Be Transmitted to an Arbitrary HTTPS Endpoint

Content
View full analysis
{ console.log('[Introspection] Notification sent, status:', res.statusCode); }); req.on('error', (e) => { console.error('[Introspection] Notification failed:', e.message); }); req.write(postData); req.end(); } } catch (e) { console.error('[Introspection] Notify error:', e.message); } } ``` ### Technical Analysis Error messages and stack traces frequently contain absolute paths, internal module names, request metadata, query values, resource identifiers, and occasionally cr ...[truncated 1255 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
introspection-debugger.js:242
Finding

Global Exception Handler Can Recurse Through an Unhandled EventEmitter Error

Content
View full analysis
{ this.capture(error, { source: 'uncaughtException' }); }); // 捕获未处理的Promise拒绝 process.on('unhandledRejection', (reason, promise) => { const error = reason instanceof Error ? reason : new Error(String(reason)); this.capture(error, { source: 'unhandledRejection' }); }); } ``` The capture routine emits Node.js's special `error` event without checking for a listener: ```javascript // 发送通知 if (this.notificationHook && errorInfo.fixResult?.needHuman) { await this.notifyHuman(report); } // 触发事件 this.emit('error', errorInfo); this.emit('report', report); return report; ``` ### Technical Analysis In Node.js, emitting an `error` event on an `EventEmitter` with no registered `error` listener throws an exception. A newly created debugger instance does not install such a listener. If capture was entered from `uncaughtException`, emitting the unhandled `error` event can throw another exception, activating the same global handler again. Because `capture()` is asynchronous and its returned promise is ignored by the process handlers, failures may also become unhandled rejections and enter the second global handler. Every instance additionally registers new process-level listeners and provides no disposal method, potentially causing listener accumulation and duplicate processing. ### Attack Path 1. An application creates an `IntrospectionDebugger` instance without attaching an `error` listener. 2. An attacker or runtime condition triggers an uncaught exception or unhandled rejection. 3. The global han ...[truncated 606 chars]
Remediation
View remediation
{ void this.capture(error, { source: 'uncaughtException' }) .catch(captureError => { console.error('[Introspection] Capture failed:', captureError); }); }); ``` - Add a recursion guard so failures raised by the debugger are not processed repeatedly. - Register process handlers once rather than once per instance. - Provide a `dispose()` method that removes installed handlers. - Define and document whether the process should terminate safely after an uncaught exception instead of attempting to continue in an unknown state. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill performs host-level shell execution to change permissions and install packages as part of automatic remediation. Because the command inputs are derived from error text and the feature makes persistent system changes without approval, it creates a dangerous path to arbitrary command execution, environment tampering, and supply-chain exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Automatic dependency installation executes npm install for a module name parsed from an error string, with no approval or strict validation. This exposes the host to dependency confusion, malicious packages, and command injection or unsafe package-name parsing in an automated flow.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill may send reports containing message, stack, and context data to a webhook without prior warning. In debugging contexts these fields frequently contain secrets, filesystem layouts, environment details, and customer data, making silent exfiltration particularly risky.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises capabilities such as automatic file creation, permission repair, and dependency installation, which imply shell or system-modifying actions, but it does not declare any tool scope or permission boundary in the manifest. This creates a governance gap: an agent may invoke powerful operations without explicit user-visible constraints, increasing the risk of unintended or unsafe system changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation explicitly promotes automatic file creation, permission changes, and dependency installation, but provides no warning, consent flow, or safety guardrails around those actions. In an agent context, these behaviors can alter the host environment, weaken filesystem protections, or introduce untrusted packages, making accidental misuse or privilege abuse significantly more dangerous.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The natural-language documentation and user-facing messages in the file are in Chinese, but there is no indication that the user opted into that language or that the skill is intentionally limited to a Chinese-speaking context. This can violate language/locale policy when a skill forces a specific language without user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill automatically creates files based on parsed error messages with no confirmation step. In an agent context, attacker-influenced errors could cause unexpected file creation, overwrite development artifacts, or plant misleading stub files that alter later execution behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code changes permissions by constructing a shell command from a file path extracted from an error message. This combines silent host modification with shell injection risk if the path contains crafted characters, and may make unintended files executable.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The webhook notification feature can transmit full error reports, including stack traces and context, to an arbitrary URL. This can leak secrets, internal paths, tokens in error messages, and other sensitive operational data to external systems without strong validation or redaction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language description and headings are presented in Chinese, which effectively forces a specific language for users reading the skill documentation. The file does not provide an opt-in language choice or justify a region-specific constraint.

Content

No source excerpt is available for this finding.