Back to skill

Security audit

Skill Gatekeeper

Security checks for vulnerabilities and agentic risk

Overview

This skill is a security gatekeeper with purpose-aligned scanning features, but it overstates its sandbox protections and contains unsafe install and filesystem operations that could affect files outside the intended skill area.

Install only if you are comfortable reviewing and fixing the implementation first. Avoid using the install command with untrusted slugs, do not rely on its sandbox claim as real isolation, and treat quarantine/audit-all as capable of moving or deleting local skill directories until path validation and confirmation controls are added.

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

T09 · Insecure Skill Coding Practices

Error
Location
gatekeeper.ts:258
Finding

OS Command Injection Through an Unvalidated Installation Slug

Content
View full analysis
{ console.log(`\n📦 安裝技能: ${slug}`) console.log(` 🔒 自動進入安全審核...`) // 使用 clawhub 安裝 const { execSync } = await import("child_process") try { execSync(`node "C:/Users/ReaMasTer/AppData/Roaming/npm/node_modules/clawhub/bin/clawdhub.js" install ${slug} --dir "${SKILL_DIR}"`, { encoding: "utf-8" }) ``` The untrusted value originates from the command-line arguments: ```ts if (command === "install" && args[1]) { const success = await installWithAudit(args[1]) ``` ### Technical Analysis The `slug` value is accepted directly from `process.argv` and interpolated into a command string passed to `execSync`. By default, `execSync` executes its string through a system shell. Consequently, shell metacharacters contained in `slug` are interpreted as command syntax rather than as part of a single installation argument. No validation, escaping, or strict identifier allowlist is applied before the value reaches the shell. Quoting only `SKILL_DIR` does not protect the separately interpolated `slug`. This vulnerability is particularly serious because the injected command executes before the newly installed Skill is audited. The security scanner therefore cannot prevent exploitation of the Gatekeeper itself. ### Attack Path 1. An attacker supplies or recommends a crafted Skill slug containing shell control syntax. 2. A user or automation invokes `skill-gatekeeper install` with that slug. 3. `main()` forwards the untrusted argument to `installWithAudit()`. 4. `installWithAudit()` inserts the value into the command string without validation. 5. The operating-system shell parses the injected syntax. 6. Attacker-controlled commands execute with the same permissions and environment as the Gatekeeper process. 7. Ex ...[truncated 735 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
gatekeeper.ts:192
Finding

Path Traversal Enables Out-of-Scope Copying and Recursive Deletion

Content
View full analysis
{ try { const sandboxPath = join(SANDBOX_DIR, skillName) mkdirSync(SANDBOX_DIR, { recursive: true }) cpSync(skillPath, sandboxPath, { recursive: true }) return sandboxPath ``` ```ts async function auditSkill(skillName: string): Promise { const skillPath = join(SKILL_DIR, skillName) const config = loadConfig() ``` ```ts rmSync(sandboxPath, { recursive: true, force: true }) ``` The command-line audit path is accepted without validation: ```ts if (command === "audit" && args[1]) { const result = await auditSkill(args[1]) ``` ### Technical Analysis The user-controlled `skillName` is passed to `path.join()` for both the source Skill path and the sandbox destination. `path.join()` normalizes traversal components but does not enforce containment beneath a trusted root. A value containing parent-directory components can therefore cause the resolved source or destination to escape `SKILL_DIR` or `SANDBOX_DIR`. The escaped source is recursively copied, and the escaped destination is later passed to a recursive, forced deletion operation. The code does not: - Canonicalize and verify that paths remain below their intended roots. - Reject absolute paths or parent-directory components. - Detect symlink-based escapes. - Confirm that the cleanup target is the temporary directory originally created for the audit. The copy operation is not an isolation boundary. It runs with the Gatekeeper's ordinary filesystem privileges and can access any path available to that account. ### Attack Path 1. An attacker causes `skill-gatekeeper audit` to be invoked with a Skill name containing traversal components. ...[truncated 1287 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
gatekeeper.ts:43
Finding

Stateful Global Regular Expressions Permit Nondeterministic Scanner Bypass

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
gatekeeper.ts:153
Finding

Incomplete File Coverage Allows Malicious Skill Content to Bypass Auditing

Content
View full analysis
{ const issues: Issue[] = [] const scanableExtensions = [".ts", ".tsx", ".js", ".jsx", ".sh", ".bash"] async function scanDir(dirPath: string) { try { const entries = await readdirAsync(dirPath, { withFileTypes: true }) for (const entry of entries) { const fullPath = join(dirPath, entry.name) if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") { await scanDir(fullPath) } else if (entry.isFile()) { const ext = extname(entry.name).toLowerCase() if (scanableExtensions.includes(ext)) { try { const content = await readFileAsync(fullPath, "utf-8") for (const { pattern, type } of HIGH_RISK_PATTERNS) { if (pattern.test(content)) { issues.push({ severity: "high", type, description: `發現危險模式: ${type}` }) } } for (const { pattern, type } of MEDIUM_RISK_PATTERNS) { if (pattern.test(content)) { issues.push({ severity: "medium", type, description: `發現潛在風險: ${type}` }) } } ``` ### Technical Analysis The local scanner examines only six filename extensions: - `.ts` - `.tsx` - `.js` - `.jsx` - `.sh` - `.bash` It does not inspect `SKILL.md`, despite that file containing the instructions that define how an Agent uses a Skill. It also omits common executable or instruction-bearing formats such as Python, PowerShell, batch scripts, extensionless executables, configuration files, and files selected through shebangs. Hidden directories and `node_modules` are skipped entirely. Content placed in the ...[truncated 2230 chars]
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented behavior claims secure sandbox testing and automatic safe release, but the described implementation also installs skills, moves/removes directories, stores a VirusTotal API key, and appears to equate static scanning plus file copy with sandboxing. This can mislead users into trusting a security control that does not provide the isolation it claims, creating a false sense of safety around potentially malicious skills. Because this skill is itself a security-review gate, inaccurate claims materially increase risk.

Content

No source excerpt is available for this finding.

YARA rule 'keylogger_indicators': Keylogger functionality in scripts or source code [malware]

High
Category
YARA Match
Confidence
70% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · gatekeeper.ts (reported line 51)May include surrounding context.

ts
ern: /new\s+Function\s*\(/g, type: "動態函數創建" },
  { pattern: /child_process\.exec\s*\(/g, type: "系統命令執行" },
  { pattern: /child_process\.spawn\s*\(/g, type: "子進程創建" },
  { pattern: /process\.exit\s*\(/g, type: "強制進程終止" },
  { pattern: /decodeURIComponent.*password|decodeURIComponent.*token/g, type: "密碼竊取模式" },
  { pattern: /SetClipboardData|GetAsyncKeyState|keylogger/i, type: "鍵盤側錄模式" },
]

const MEDIUM_RISK_PATTERNS = [
  { pattern: /writeFile.*sync|writeFileSync/g, type: "檔案寫入操作" },
  { pattern: /curl.*\|.*sh/g, type: "管道下載執行" },
  { pattern: /wget.*\|.*sh/g, type: "Wget 管道執行" },
  { pattern: /powershell.*-enc|base64.*decode/gi, type: "Base64 PowerShell" },
]

function loadConfig(): Config {
  try {
    const content = readFileSync(join(CONFIG_FILE), "utf-8")
    return JSON.parse(content)
  } catch {
    return { autoApprove: false, requireVT: true, whitelist: [] }
  }
}

function sa

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill invokes an external installer through execSync using string interpolation with untrusted user input (slug). That creates command-execution risk and also expands the tool's capability from auditing into installing arbitrary external content, which is especially dangerous in a security gatekeeping component that users may trust to be defensive.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises and appears to require shell and network-capable behavior, but it does not declare any explicit tool scope such as permissions or allowed-tools. That makes the trust boundary unclear and can result in over-broad execution capability for a skill that installs software, contacts VirusTotal, and quarantines files. In this context, undeclared shell/network access is more dangerous because the skill is positioned as a security gatekeeper and may be granted elevated trust by users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file contains user-facing descriptions and usage instructions exclusively in Chinese, with no indication that users can choose another language. That can violate language/locale policy where skills must not force a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 17)May include surrounding context.

ts
interface Config {
  virusTotalApiKey?: string
  autoApprove?: boolean
  requireVT?: boolean
  whitelist?: string[]
}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 66)May include surrounding context.

ts
interface Config {
  virusTotalApiKey?: string
  autoApprove?: boolean
  requireVT?: boolean
  whitelist?: string[]
}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 312)May include surrounding context.

ts
interface Config {
  virusTotalApiKey?: string
  autoApprove?: boolean
  requireVT?: boolean
  whitelist?: string[]
}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 314)May include surrounding context.

ts
interface Config {
  virusTotalApiKey?: string
  autoApprove?: boolean
  requireVT?: boolean
  whitelist?: string[]
}

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 324)May include surrounding context.

ts
interface Config {
  virusTotalApiKey?: string
  autoApprove?: boolean
  requireVT?: boolean
  whitelist?: string[]
}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The tool modifies configuration on disk and quarantine logic later deletes skill directories without an explicit confirmation flow. In a gatekeeping tool, silent destructive actions can be abused or triggered unexpectedly, causing data loss or unauthorized state changes on the user's system.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code presents a 'sandbox isolation environment' but only copies files to another directory and performs static scans. This can mislead users into believing dynamic containment exists, causing unsafe trust decisions around untrusted skills that were never actually executed in a restricted environment.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 310)May include surrounding context.

ts
config.virusTotalApiKey = args[2]
      saveConfig(config)
      console.log("✅ VirusTotal API Key 已設定")
    } else if (args[1] === "--auto-approve") {
      const config = loadConfig()
      config.autoApprove = args[2] !== "false"
      saveConfig(config)

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 328)May include surrounding context.

ts
config.virusTotalApiKey = args[2]
      saveConfig(config)
      console.log("✅ VirusTotal API Key 已設定")
    } else if (args[1] === "--auto-approve") {
      const config = loadConfig()
      config.autoApprove = args[2] !== "false"
      saveConfig(config)

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
65% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 310)May include surrounding context.

ts
config.virusTotalApiKey = args[2]
      saveConfig(config)
      console.log("✅ VirusTotal API Key 已設定")
    } else if (args[1] === "--auto-approve") {
      const config = loadConfig()
      config.autoApprove = args[2] !== "false"
      saveConfig(config)

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
65% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · gatekeeper.ts (reported line 328)May include surrounding context.

ts
config.virusTotalApiKey = args[2]
      saveConfig(config)
      console.log("✅ VirusTotal API Key 已設定")
    } else if (args[1] === "--auto-approve") {
      const config = loadConfig()
      config.autoApprove = args[2] !== "false"
      saveConfig(config)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

In the audit command, the output claims dangerous skills were moved to quarantine, but no quarantine action occurs in that code path. This false security signal can leave known-dangerous skills in place while users believe they have been contained.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file's natural-language strings, including risk descriptions, audit messages, and CLI help text, are consistently hard-coded in Traditional Chinese. This imposes a specific language on all users without offering a locale option or documenting that the tool is intended only for a Chinese-speaking environment.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
gatekeeper.ts:269