Back to skill

Security audit

Security Sentinel

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real workspace security scanner, but it needs review because its recursive file scan can follow links outside the project and it includes unnecessary deprecated dependencies.

Review before installing. Run it only in workspaces you trust and under a low-privilege account, because crafted symlinks in a project can cause it to read outside the project. Be aware npm audit may contact the npm registry with dependency metadata. The publisher should reject symlinks or enforce root containment, remove unused dependencies, and align scan.js with the documented scanner behavior.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
index.js:119
Finding

Recursive workspace scanning follows symbolic links outside the authorized scan root

Content
View full analysis
filePath.includes(ignored))) continue; if (fs.existsSync(filePath)) { const stat = fs.statSync(filePath); if (stat.isDirectory()) { getAllFiles(filePath, fileList); ``` `scan.js:45-65`: ```javascript function recursiveScan(dir) { let results = []; const files = fs.readdirSync(dir); for (const file of files) { const fullPath = path.join(dir, file); // Skip ignored directories if (['node_modules', '.git', 'media', 'dist', 'coverage', '.openclaw', 'memory', 'cache', 'ai-game-engine', 'repo'].includes(file)) continue; // Skip self, env files, and lock files if (file === 'index.js' || file === 'scan.js' || file.endsWith('.env')) continue; if (['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock'].includes(file)) continue; if (file.endsWith('.tmLanguage.json')) continue; try { const stats = fs.statSync(fullPath); if (stats.isDirectory()) { results = results.concat(recursiveScan(fullPath)); } else if (stats.isFile() && stats.size < 500 * 1024) { ``` ### Technical Analysis Both recursive scanners use `fs.statSync()`, which follows symbolic links. Neither implementation first uses `fs.lstatSync()` to reject links, resolves the canonical path with `fs.realpathSync()`, nor verifies that the resolved target remains under the canonical workspace root. Consequently, a symbolic link placed inside the workspace ...[truncated 2107 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
package.json:9
Finding

Unused deprecated glob dependency introduces avoidable supply-chain exposure

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented purpose and the reported implementation behavior diverge significantly: the skill claims general security scanning but reportedly performs repository-specific policy enforcement and may fail to execute some advertised checks. This mismatch is dangerous because users may rely on the skill for security assurance it does not actually provide, leading to missed vulnerabilities and incorrect trust decisions.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · index.js (reported line 95)May include surrounding context.

js
// 3. Permission Scan
  console.log('[Sentinel] Checking permissions...');
  const CRITICAL_FILES = ['package.json', '.env', 'openclaw.json'];
  for (const crit of CRITICAL_FILES) {
    if (fs.existsSync(crit)) {
      const stats = fs.statSync(crit);

Known Vulnerable Dependency: brace-expansion==2.0.2 — 4 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro) +1 more

High
Category
Supply Chain
Confidence
96% confidence
Finding

The lockfile pins brace-expansion 2.0.2, and the supplied advisory set indicates multiple denial-of-service conditions involving pathological brace patterns that can trigger exponential processing, hangs, or memory exhaustion. In a security-scanning skill that is likely to process attacker-controlled filenames, paths, or glob-like patterns across a workspace, such dependency-level parsing flaws are more dangerous because they can be triggered during normal scan operations and cause the agent to stall or crash.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: minimatch==5.1.6 — 3 advisory(ies): CVE-2026-27904 (minimatch ReDoS: nested *() extglobs generate catastrophically backtracking regu); CVE-2026-26996 (minimatch has a ReDoS via repeated wildcards with non-matching literal in patter); CVE-2026-27903 (minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja)

High
Category
Supply Chain
Confidence
98% confidence
Finding

The lockfile includes minimatch 5.1.6, and the listed advisories describe regular-expression/backtracking denial-of-service issues where crafted glob patterns can consume excessive CPU. This skill’s purpose is to scan workspaces for vulnerabilities and misconfigurations, so it is especially likely to evaluate many file patterns; if any pattern source is attacker-influenced, the vulnerable matcher could be used to degrade availability or block scans.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The scanner explicitly skips files ending in .env, which commonly contain API keys, database passwords, and other secrets. In a security-scanning skill, omitting .env files creates a blind spot that can hide credential exposure and materially weakens the tool's stated purpose.

Content

Scanner excerpt · scan.js (reported line 54)May include surrounding context.

js
if (['node_modules', '.git', 'media', 'dist', 'coverage', '.openclaw', 'memory', 'cache', 'ai-game-engine', 'repo'].includes(file)) continue;
        
        // Skip self, env files, and lock files
        if (file === 'index.js' || file === 'scan.js' || file.endsWith('.env')) continue;
        if (['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock'].includes(file)) continue;
        if (file.endsWith('.tmLanguage.json')) continue;

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

Although .env is listed as an allowed extension, the earlier skip condition prevents such files from ever being scanned. This inconsistency reinforces that the tool fails to inspect one of the highest-risk file types for credential leakage, making the scanner unreliable for secret detection.

Content

Scanner excerpt · scan.js (reported line 64)May include surrounding context.

js
results = results.concat(recursiveScan(fullPath));
            } else if (stats.isFile() && stats.size < 500 * 1024) { // Limit to 500KB files
                // Check extension
                if (!['.md', '.js', '.json', '.yml', '.yaml', '.sh', '.env', '.txt'].includes(path.extname(file))) continue;
                
                const content = fs.readFileSync(fullPath, 'utf8');
                secretPatterns.forEach(pat => {

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scan.js (reported line 93)May include surrounding context.

js
if (pkg.scripts) {
                        for (const [name, cmd] of Object.entries(pkg.scripts)) {
                            if (cmd.includes('curl') && cmd.includes('| bash')) {
                                results.push(`🚨 Dangerous script detected in ${fullPath} script '${name}': curl | bash`);
                            }
                            if (cmd.includes('rm -rf /')) {
                                results.push(`🚨 Critical Risk: 'rm -rf /' detected in ${fullPath} script '${name}'`);

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scan.js (reported line 95)May include surrounding context.

js
if (cmd.includes('curl') && cmd.includes('| bash')) {
                                results.push(`🚨 Dangerous script detected in ${fullPath} script '${name}': curl | bash`);
                            }
                            if (cmd.includes('rm -rf /')) {
                                results.push(`🚨 Critical Risk: 'rm -rf /' detected in ${fullPath} script '${name}'`);
                            }
                        }

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scan.js (reported line 96)May include surrounding context.

js
if (cmd.includes('curl') && cmd.includes('| bash')) {
                                results.push(`🚨 Dangerous script detected in ${fullPath} script '${name}': curl | bash`);
                            }
                            if (cmd.includes('rm -rf /')) {
                                results.push(`🚨 Critical Risk: 'rm -rf /' detected in ${fullPath} script '${name}'`);
                            }
                        }

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scan.js (reported line 95)May include surrounding context.

js
if (cmd.includes('curl') && cmd.includes('| bash')) {
                                results.push(`🚨 Dangerous script detected in ${fullPath} script '${name}': curl | bash`);
                            }
                            if (cmd.includes('rm -rf /')) {
                                results.push(`🚨 Critical Risk: 'rm -rf /' detected in ${fullPath} script '${name}'`);
                            }
                        }

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scan.js (reported line 96)May include surrounding context.

js
results.push(`🚨 Dangerous script detected in ${fullPath} script '${name}': curl | bash`);
                            }
                            if (cmd.includes('rm -rf /')) {
                                results.push(`🚨 Critical Risk: 'rm -rf /' detected in ${fullPath} script '${name}'`);
                            }
                        }
                    }

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises and invokes shell-capable behavior (node skills/security-sentinel/index.js, npm audit) but does not declare an explicit tool scope such as permissions or allowed-tools. In an agent environment, undeclared shell capability weakens least-privilege controls and can let a seemingly simple scanning skill execute broader commands than reviewers or policy expect.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · SKILL.md (reported line 44)May include surrounding context.

md
* Checks for:
 * 1. Dependency vulnerabilities (npm audit)
 * 2. Exposed secrets (API keys, Tokens)
 * 3. File permission risks (world-writable)
 */

const SECRET_PATTERNS = [

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · index.js (reported line 10)May include surrounding context.

js
* Checks for:
 * 1. Dependency vulnerabilities (npm audit)
 * 2. Exposed secrets (API keys, Tokens)
 * 3. File permission risks (world-writable)
 */

const SECRET_PATTERNS = [

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency is specified with a caret range, which permits installation of newer minor and patch releases than the version originally tested. This creates supply-chain risk because future upstream releases could introduce malicious code, regressions, or breaking security behavior without any change to this repository.

Content

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

json
"test": "node index.js"
  },
  "dependencies": {
    "fs-extra": "^11.1.0",
    "glob": "^8.1.0"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency is specified with a caret range, which allows npm to resolve to newer minor and patch versions over time. In a security-scanning skill, unexpected dependency drift is especially undesirable because the tool may be trusted to inspect sensitive workspace contents, so a compromised or flawed upstream update could affect a high-trust component.

Content

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

json
},
  "dependencies": {
    "fs-extra": "^11.1.0",
    "glob": "^8.1.0"
  }
}