T09 · Insecure Skill Coding Practices
- Location
index.js:116- Finding
Allowlist Substring Matching Bypasses All Subsequent Security Checks
- Content
View full analysis
Vulnerability Details
File Location:
index.js:116-123andindex.js:143-151
Vulnerability Type: Allowlist policy bypass
Risk Level: HighVulnerable Code
javascript // Check allowlist if (this.isWhitelisted(toolCall)) { return { allowed: true, reason: 'Whitelisted operation', type: 'whitelist' }; }javascript isWhitelisted(toolCall) { return this.whitelist.some(item => { // Simple allowlist matching logic return ( (item.pattern && item.pattern.test(toolCall)) || (item.command && toolCall.includes(item.command)) ); }); }The relevant packaged allowlist includes entries such as:
json { "command": "cat /etc/passwd", "reason": "Admin monitoring", "description": "Allow reading password file for admin monitoring" }Technical Analysis
Allowlist entries are matched using
String.prototype.includes(). Consequently, an allowlist entry does not need to equal the submitted command; it only needs to appear anywhere within it.Allowlist processing also occurs before blocklist and strict intent validation. Once
isWhitelisted()returnstrue,checkToolCall()immediately returns an allowed decision. The remaining security controls are never evaluated.This creates a policy bypass for compound shell commands. For example:
text cat /etc/passwd; rm -rf /var/logThe complete string contains the allowlisted substring
cat /etc/passwd. It is therefore approved even though its second command matches a destructive blocklist rule.The library does not execute commands itself, so exploitation depends on an integrating application executing commands after receiving an allowed result. This is precisely the usage pattern promoted by the project documentation.
Attack Path
- Identify a packaged or administrator-added allowlist command, such as
cat /etc/passwdor ...[truncated 1126 chars]
- Identify a packaged or administrator-added allowlist command, such as
- Remediation
View remediation
Remediation Suggestions
- Replace substring matching with exact matching of a normalized command representation.
- Parse commands using a shell-aware parser and validate the executable and each argument separately.
- Reject shell control operators, including command separators, pipelines, redirections, substitutions, and background execution, unless explicitly required and independently validated.
- Apply mandatory deny rules before allowlist exceptions.
- Split compound expressions and validate every command independently; one allowlisted component must not authorize the entire expression.
- Bind allowlist entries to an exact executable, approved arguments, permitted paths, and expected operation type.
- Remove sensitive generic entries such as
cat /etc/passwdunless they are essential and constrained to an exact read-only operation. - Add regression tests covering appended commands, prefixed commands, pipelines, command substitutions, newlines, and shell separators.
