Back to skill

Security audit

vettr

Security checks for vulnerabilities and agentic risk

Overview

This is a real security-scanning skill, but its ignore-file and remote-download behavior can make results misleading or reach unintended network targets.

Review before installing. Use the local scanner only as one input, not as a sole safety gate, because a target skill can include .vettrignore rules that hide files from analysis. Run remote URL vetting only in a disposable or network-restricted environment, especially for untrusted URLs, and be aware that npm dependencies and external binaries are part of the trust boundary.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
src/vettr-engine.ts:71
Finding

Target-Controlled .vettrignore Rules Can Bypass Security Scanning

Content
View full analysis
0 && isExcluded(relativePath, ignorePatterns)) { continue; } ``` ```ts // src/utils/vettrignore.ts:14-24 export function parseVettrignore(content: string): VettrignoreResult { const patterns: string[] = []; const warnings: string[] = []; for (const raw of content.split('\n')) { const line = raw.trim(); if (line === '' || line.startsWith('#')) continue; patterns.push(line); } return { patterns, warnings }; } ``` ```ts // src/utils/vettrignore.ts:99-108 export function isExcluded(filePath: string, patterns: string[]): boolean { // Normalise to forward slashes for consistent matching const normalized = filePath.replace(/\\/g, '/'); for (const pattern of patterns) { const regex = patternToRegex(pattern); if (regex.test(normalized)) return true; } return false; } ``` ### Technical Analysis The scanner automatically trusts `.vettrignore` from the Skill being audited. Because that Skill is potentially attacker-controlled, its author can directly determine which files the security engine inspects. There are no restrictions preventing broad patterns such as `**`, `src/`, `*.js`, or `package.json`. Matching files are silently omitted before source analysis, dependency analysis, network-call extraction, lifecycle-script detection ...[truncated 1882 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/utils/sanitise.ts:22
Finding

Remote Skill Retrieval Permits Blind SSRF Through DNS Resolution and Redirects

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The code does match part of the description: it is a static analyzer for JS/TS source and detects eval/spawn-related and other security-relevant patterns. However, the declared description materially overstates its coverage. In this chunk, there is no logic for analyzing package/dependency metadata, no typosquatting checks, and no prompt-injection pattern detection. Separately, the code includes a capability to extract literal fetch() URLs from source, which is not mentioned in the description. Because several named headline capabilities in the description are absent from the actual behavior, the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description presents a broad static analysis security scanner for third-party skills, including detection of eval/spawn risks, malicious dependencies, typosquatting, and prompt injection patterns. The supplied code chunk does not implement those broader capabilities. It only analyzes package.json-style dependency metadata and lifecycle scripts. It does partially align with the malicious dependency aspect, and the suspicious-prefix check is loosely related to typosquatting/suspicious naming, but it is not a full typosquatting detector. There are no undeclared dangerous capabilities in this snippet; the mismatch is that the declared functionality is substantially broader than the actual behavior shown.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared purpose describes a broad static security scanner focused on code-level and content-level threats such as eval/spawn usage, malicious dependencies, and prompt injection. The supplied code chunk only analyzes manifest metadata. It does include typosquatting detection, which matches part of the description, and permission-risk checks, which are plausibly related to security vetting. However, the primary behavior of this chunk is narrower and materially different from the declared scanner scope because it does not implement the key advertised detections (eval/spawn, dependency analysis, prompt injection). It also adds metadata-specific checks like missing/blocked authors and version formatting that are not described. This is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents the skill as a broader static analysis scanner that detects eval/spawn risks, malicious dependencies, typosquatting, and prompt injection. The supplied code chunk only covers a subset: prompt injection regexes, code obfuscation via escaped 'eval', credential-path string references, and homoglyph-based dangerous-name detection. The file comment explicitly says structural patterns like eval/exec/spawn are handled by a different analyzer and are not duplicated here, so this chunk itself does not perform that declared function. There is also no dependency analysis or typosquatting logic present. While this code is consistent with part of a security scanner, it materially underimplements the declared set of capabilities for this chunk, so the description does not accurately represent what this code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Yes, this is a mismatch. The declared description claims a concrete security scanning skill with pre-installation vetting capabilities. However, the provided code is only a declaration file for an SDK: it specifies available interfaces and methods but contains no executable logic that scans skills, inspects dependencies, analyzes source code, or blocks installation. The actual code’s primary purpose is API/type definition, which is materially different from the claimed security scanner functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description says the skill is a static analysis security scanner for vetting third-party skills. However, this code chunk does not implement scanning, detection of malicious dependencies, typosquatting, prompt injection analysis, or other static-analysis logic. Instead, it provides a subprocess execution helper with command allowlisting and argument sanitization. While such a helper could support a scanner, the code itself materially enables command execution and possible network/resource access through git/curl, which are undeclared capabilities in the description. This is a meaningful description-behavior mismatch, not merely a supporting implementation detail, because the chunk’s primary behavior is safe execution of external commands rather than analysis.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose describes a full security scanner with multiple detection capabilities. The supplied code does not perform scanning, parsing, dependency analysis, or prompt-injection detection. It is a standalone Levenshtein distance helper. While such a utility could support typosquatting detection as one small component, this chunk by itself materially differs from the declared primary purpose and lacks the advertised security-analysis behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared purpose describes a security scanner that analyzes third-party skills for malicious behavior and suspicious patterns. The supplied code does not implement any scanning or analysis of skill contents, dependencies, prompts, or code execution primitives. Instead, it is a utility module for sanitizing user/file inputs and generating random identifiers. While these helpers may support a larger vetting tool, this chunk’s actual behavior is materially different from the declared primary purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The supplied code chunk is a narrow filesystem-pattern utility: it parses .vettrignore contents, serializes patterns, converts glob-like patterns to regular expressions, and checks whether paths should be excluded. It does not scan third-party skills, inspect source code, analyze dependencies, detect malicious packages, or identify prompt injection patterns. This is therefore a clear description-behavior mismatch: the declared primary purpose is a security scanner, while the actual code implements ignore-file handling support logic.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/analyzers/metadata-analyzer.ts (reported line 14)May include surrounding context.

ts
'system:admin',
  'system:root',
  'credentials:read',
  'keychain:access',
]);

export class MetadataAnalyzer {

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/analyzers/pattern-analyzer.ts (reported line 92)May include surrounding context.

ts
'system:admin',
  'system:root',
  'credentials:read',
  'keychain:access',
]);

export class MetadataAnalyzer {

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · .github/workflows/ai-review.yml (reported line 84)May include surrounding context.

yaml
}).encode()

req = urllib.request.Request(
    "https://api.z.ai/api/coding/paas/v4/chat/completions",
    data=payload,
    headers={
        "Authorization": f"Bearer {api_key}",

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Content

Scanner excerpt · skill.md (reported line 39)May include surrounding context.

md
This installs all Node.js dependencies, including tree-sitter `.wasm` grammar files required at runtime for AST-based analysis. The `.wasm` files are located in `node_modules` and must be present for the skill to function.

> ⚠️ **Install safety:** `npm install` runs dependency lifecycle scripts, which can execute arbitrary code. For stronger isolation, run `npm ci --ignore-scripts` — but note that tree-sitter native/WASM artifacts may not build, breaking AST analysis. Prefer installing inside a container or VM when possible.

## External Binaries

Known Vulnerable Dependency: yaml==2.8.2 — 1 advisory(ies): CVE-2026-33532 (yaml is vulnerable to Stack Overflow via deeply nested YAML collections)

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The lockfile pins yaml to version 2.8.2, and the reported advisory describes a denial-of-service condition where deeply nested YAML input can trigger stack overflow during parsing. In the context of a security-vetting skill that likely ingests untrusted skill metadata/config files, YAML parsing may be reachable on attacker-controlled input, making this a credible but low-severity availability risk rather than a false positive.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 12)May include surrounding context.

json
"test": "node --test dist/__tests__/**/*.test.js"
  },
  "dependencies": {
    "tree-sitter-javascript": "^0.25.0",
    "tree-sitter-typescript": "^0.23.2",
    "web-tree-sitter": "^0.26.0",
    "yaml": "^2.4.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 13)May include surrounding context.

json
},
  "dependencies": {
    "tree-sitter-javascript": "^0.25.0",
    "tree-sitter-typescript": "^0.23.2",
    "web-tree-sitter": "^0.26.0",
    "yaml": "^2.4.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 14)May include surrounding context.

json
"dependencies": {
    "tree-sitter-javascript": "^0.25.0",
    "tree-sitter-typescript": "^0.23.2",
    "web-tree-sitter": "^0.26.0",
    "yaml": "^2.4.0"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 15)May include surrounding context.

json
"tree-sitter-javascript": "^0.25.0",
    "tree-sitter-typescript": "^0.23.2",
    "web-tree-sitter": "^0.26.0",
    "yaml": "^2.4.0"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",

Known Vulnerable Dependency: yaml==2.8.2 — 1 advisory(ies): CVE-2026-33532 (yaml is vulnerable to Stack Overflow via deeply nested YAML collections)

Low
Category
Supply Chain
Confidence
89% confidence
Finding

The resolved yaml dependency is reported as vulnerable to stack overflow from deeply nested YAML collections, which can enable denial of service if the skill parses attacker-controlled YAML. This skill is a scanner for third-party skills and explicitly depends on YAML parsing, so hostile input is plausible and the context makes parser robustness more important.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 18)May include surrounding context.

json
"yaml": "^2.4.0"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",
    "fast-check": "^4.5.3",
    "typescript": "^5.3.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 19)May include surrounding context.

json
},
  "devDependencies": {
    "@types/node": "^20.0.0",
    "fast-check": "^4.5.3",
    "typescript": "^5.3.0"
  },
  "engines": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 20)May include surrounding context.

json
"devDependencies": {
    "@types/node": "^20.0.0",
    "fast-check": "^4.5.3",
    "typescript": "^5.3.0"
  },
  "engines": {
    "node": ">=20.0.0"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code executes external commands via execFileAsync, which is a safety-relevant operation under the missing-user-warnings rule for code files. The file contains internal validation and comments, but no user-facing confirmation prompt, disclosure message, or warning that commands like git, curl, tar, or clawhub will be run.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The environment passed to subprocesses sets LANG to process.env['LANG'] ?? 'en_US.UTF-8', which imposes an English-US locale when none is already configured. This is a natural-language/locale policy concern because the skill defaults to a specific language/locale without offering user choice or documenting a justified regional constraint.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.dynamic_code_execution, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/analyzers/ast-analyzer.ts:225

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
src/analyzers/ast-analyzer.ts:185

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/analyzers/ast-analyzer.ts:330