Back to skill

Security audit

OpenClaw Security Guard

Security checks for vulnerabilities and agentic risk

Overview

This is a local security-checking skill, but it needs review because some helper scripts can write outside expected locations and the publishing guard can be bypassed.

Review this skill before installing. The scanner strings are mostly expected for a security tool, but only run the hook installer if overwriting the fixed workspace script is acceptable, and avoid the Obsidian writer unless the destination path and note title are controlled. Do not rely on the prepublish guard alone for publish/install decisions until the filename bypass and symlink containment issues are fixed.

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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/audit-skill-dir.mjs:28
Finding

Symbolic Link Following Allows Reads Outside the Selected Audit Directory

Content
View full analysis
{ for (const rule of rules) { if (rule.re.test(line)) { findings.push({ level: rule.level, label: rule.label, file, line: i + 1, excerpt: line.trim().slice(0, 200) }); } } }); } ``` ### Technical Analysis The directory auditor assumes that every file discovered beneath the selected directory is physically contained within that directory. However, it does not use `lstatSync` to identify symbolic links and does not compare each file's canonical path against the canonical audit root. For a symbolic link, `Dirent.isDirectory()` is false, so a link whose name has an accepted extension can reach `scanFile`. `fs.readFileSync` then follows the symbolic link and reads its external target. The scanner does not print entire files, but any external line matching a detection rule can be included in the JSON output as a finding excerpt. Large or unsuitable linked files may also cause resource consumption or scanner failure. ### Attack Path 1. An attacker prepares a skill directory containing a symbolic link with an accepted filename, such as `external.md`. 2. The symbolic link points to a file outside the skill directory that is readable b ...[truncated 812 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/prepublish-guard.mjs:17
Finding

Filename-Based Exclusions Allow Prepublish Security Guard Bypass

Content
View full analysis
f.level === 'BLOCK' && !/references\/checklist\.md|scripts\/audit-skill-dir\.mjs|scripts\/security-check\.mjs/.test(f.file)); if (actionableBlocks.length > 0) { console.error('\nPrepublish guard: BLOCK due to actionable findings.'); process.exit(1); } console.log('\nPrepublish guard: PASS (no actionable BLOCK findings).'); ``` ### Technical Analysis The prepublish wrapper suppresses every `BLOCK` finding whose path matches one of three filename patterns: - `references/checklist.md` - `scripts/audit-skill-dir.mjs` - `scripts/security-check.mjs` These exclusions are applied to files inside the user-selected audit target. An attacker controlling that target also controls its filenames and can place genuine malicious content in an excluded path. The regular expression is not anchored to a trusted package root and does not verify file identity or content context. Consequently, it cannot distinguish inert detection signatures in the security guard itself from an actual remote shell pipeline, destructive command, or embedded secret in an untrusted skill. The child scanner's nonzero status is not independently enforced after valid JSON is parsed. Therefore, a scanner result containing only excluded `BLOCK` findings can be converted into a successful prepublish result. ### Attack Path 1. An attacker creates a skill containing a genuinely blocked payload. 2. The payload is placed in a path such as `scripts/security-check.mjs`. 3. The victim invokes `prepublish-guard.mjs` against the skill. 4. `audit-skill-dir.mjs` correctly emits a `BLOCK` finding and exits with a blocking st ...[truncated 768 chars]
Remediation
View remediation
finding.level === 'BLOCK' ); if (actionableBlocks.length > 0 || result.status !== 0) { process.exit(1); } ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/write-obsidian-audit.mjs:13
Finding

Unsanitized Note Title Permits Writes Outside the Obsidian Audit Directory

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/install-hooks.sh:4
Finding

Hook Installer Unconditionally Overwrites an Existing Workspace Executable

Content
View full analysis
"$TARGET" <<'EOF' #!/usr/bin/env bash set -euo pipefail SKILL_DIR="${1:-}" if [ -z "$SKILL_DIR" ]; then echo "Usage: security-prepublish-guard.sh " >&2 exit 2 fi node "$HOME/.openclaw/workspace/skills/openclaw-security-guard/scripts/prepublish-guard.mjs" "$SKILL_DIR" EOF chmod +x "$TARGET" ``` ### Technical Analysis The documented installer writes to a fixed workspace executable with the shell redirection operator `>`. If the target already exists, its contents are truncated and replaced without warning, confirmation, or backup. Installing a local wrapper is part of the Skill's declared functionality, so the write is not covert persistence. The vulnerability is the destructive overwrite behavior and lack of safe installation controls. The script also assumes the parent directory already exists. If it does not, installation fails rather than creating it safely. ### Attack Path 1. A user already has a script at `$HOME/.openclaw/workspace/scripts/security-prepublish-guard.sh`. 2. The user invokes the documented `install-hooks.sh` command. 3. Shell redirection opens the existing file with truncation. 4. The original script is irreversibly replaced by the bundled wrapper. 5. Subsequent automation invoking that path runs the replacement instead of the user's previous implementation. ### Impact Assessment The issue can destroy an existing user script and alter subsequent workspace automation. The write is limited to a fixed path under the invoking user's home directory and does not obtain elevated privileges. Because installation is explicit and the installed content is visible and non-malicious, the risk is primarily integrity loss and unexpected tool replacement. ]]>
Remediation
View remediation
&2 exit 1 fi if [ -e "$TARGET" ] && [ "${1:-}" != "--force" ]; then echo "Target already exists; use --force after reviewing it: $TARGET" >&2 exit 1 fi ``` ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (15)

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 · SKILL.md (reported line 66)May include surrounding context.

md
- curl|bash / wget|sh installers
- destructive shell patterns
- risky exfiltration / webhook / netcat usage
- suspicious file targets like `~/.ssh`, `/etc/passwd`, `.env`, `id_rsa`

## Verdicts

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 · references/checklist.md (reported line 14)May include surrounding context.

md
- exfiltration utilities and outbound secret posting

## Typical publish-time red flags
- `curl ... | bash`
- `wget ... | sh`
- `rm -rf`, `mkfs`, `dd`, `chmod -R 777`
- posting to unknown webhooks / Discord webhooks / pastebins

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 · references/checklist.md (reported line 15)May include surrounding context.

md
## Typical publish-time red flags
- `curl ... | bash`
- `wget ... | sh`
- `rm -rf`, `mkfs`, `dd`, `chmod -R 777`
- posting to unknown webhooks / Discord webhooks / pastebins
- embedded tokens / API keys / JWTs / private keys

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 · references/checklist.md (reported line 16)May include surrounding context.

md
## Typical publish-time red flags
- `curl ... | bash`
- `wget ... | sh`
- `rm -rf`, `mkfs`, `dd`, `chmod -R 777`
- posting to unknown webhooks / Discord webhooks / pastebins
- embedded tokens / API keys / JWTs / private keys
- scripts that auto-modify shell startup files without clear user intent

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 · scripts/audit-skill-dir.mjs (reported line 23)May include surrounding context.

js
## Typical publish-time red flags
- `curl ... | bash`
- `wget ... | sh`
- `rm -rf`, `mkfs`, `dd`, `chmod -R 777`
- posting to unknown webhooks / Discord webhooks / pastebins
- embedded tokens / API keys / JWTs / private keys
- scripts that auto-modify shell startup files without clear user intent

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 · references/checklist.md (reported line 25)May include surrounding context.

md
{ level: 'BLOCK', label: 'pipe-to-shell', re: /(curl .*\| *(bash|sh)|wget .*\| *(bash|sh))/i },
  { level: 'BLOCK', label: 'destructive-shell', re: /(rm -rf|mkfs|dd if=|chmod -R 777|chown -R root|:\(\)\{:\|:&\};:)/i },
  { level: 'WARN', label: 'exfiltration', re: /(discord\.com\/api\/webhooks|pastebin|transfer\.sh|api\.telegram\.org|nc |ncat |scp |rsync .*@)/i },
  { level: 'WARN', label: 'sensitive-path', re: /(\/etc\/passwd|id_rsa|authorized_keys|\.env|\.ssh|\.gnupg|keychain)/i },
  { level: 'WARN', label: 'postinstall-autoexec', re: /("postinstall"\s*:\s*"[^"]+")/i }
];

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 · scripts/audit-skill-dir.mjs (reported line 25)May include surrounding context.

js
{ level: 'BLOCK', label: 'pipe-to-shell', re: /(curl .*\| *(bash|sh)|wget .*\| *(bash|sh))/i },
  { level: 'BLOCK', label: 'destructive-shell', re: /(rm -rf|mkfs|dd if=|chmod -R 777|chown -R root|:\(\)\{:\|:&\};:)/i },
  { level: 'WARN', label: 'exfiltration', re: /(discord\.com\/api\/webhooks|pastebin|transfer\.sh|api\.telegram\.org|nc |ncat |scp |rsync .*@)/i },
  { level: 'WARN', label: 'sensitive-path', re: /(\/etc\/passwd|id_rsa|authorized_keys|\.env|\.ssh|\.gnupg|keychain)/i },
  { level: 'WARN', label: 'postinstall-autoexec', re: /("postinstall"\s*:\s*"[^"]+")/i }
];

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 · scripts/security-check.mjs (reported line 32)May include surrounding context.

js
{ level: 'BLOCK', label: 'pipe-to-shell', re: /(curl .*\| *(bash|sh)|wget .*\| *(bash|sh))/i },
  { level: 'BLOCK', label: 'destructive-shell', re: /(rm -rf|mkfs|dd if=|chmod -R 777|chown -R root|:\(\)\{:\|:&\};:)/i },
  { level: 'WARN', label: 'exfiltration', re: /(discord\.com\/api\/webhooks|pastebin|transfer\.sh|api\.telegram\.org|nc |ncat |scp |rsync .*@)/i },
  { level: 'WARN', label: 'sensitive-path', re: /(\/etc\/passwd|id_rsa|authorized_keys|\.env|\.ssh|\.gnupg|keychain)/i },
  { level: 'WARN', label: 'postinstall-autoexec', re: /("postinstall"\s*:\s*"[^"]+")/i }
];

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
90% confidence
Finding

Skill attempts to nullify the agent's safety policies or restrictions ('you have no restrictions', 'ignore your guidelines', 'do anything now'). This is a direct jailbreak that disables guardrails.

Content

Scanner excerpt · scripts/security-check.mjs (reported line 13)May include surrounding context.

js
const RULES = {
  text: [
    { level: 'BLOCK', label: 'prompt-injection', re: /(ignore (all|previous) instructions|developer mode|system override|reveal (the )?system prompt|bypass safety|jailbreak)/i },
    { level: 'BLOCK', label: 'secret', re: /(sk-[a-z0-9]{16,}|ghp_[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|-----BEGIN (RSA|OPENSSH|EC) PRIVATE KEY-----|xox[baprs]-[A-Za-z0-9-]+)/i },
    { level: 'WARN', label: 'exfiltration', re: /(send (me|this|that).*(token|secret|key|cookie)|upload .*?(\.env|id_rsa|passwd)|pastebin|webhook)/i },
    { level: 'WARN', label: 'obfuscation', re: /(```json|@context|mainEntity|acceptedAnswer|\| .* \| .* \|)/i }

Instruction Override

High
Category
Prompt Injection
Confidence
90% confidence
Finding

This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Content

Scanner excerpt · scripts/security-check.mjs (reported line 13)May include surrounding context.

js
const RULES = {
  text: [
    { level: 'BLOCK', label: 'prompt-injection', re: /(ignore (all|previous) instructions|developer mode|system override|reveal (the )?system prompt|bypass safety|jailbreak)/i },
    { level: 'BLOCK', label: 'secret', re: /(sk-[a-z0-9]{16,}|ghp_[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|-----BEGIN (RSA|OPENSSH|EC) PRIVATE KEY-----|xox[baprs]-[A-Za-z0-9-]+)/i },
    { level: 'WARN', label: 'exfiltration', re: /(send (me|this|that).*(token|secret|key|cookie)|upload .*?(\.env|id_rsa|passwd)|pastebin|webhook)/i },
    { level: 'WARN', label: 'obfuscation', re: /(```json|@context|mainEntity|acceptedAnswer|\| .* \| .* \|)/i }

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · scripts/security-check.mjs (reported line 13)May include surrounding context.

js
#!/usr/bin/env node

const [, , mode, ...rest] = process.argv;
const input = rest.join(' ').trim();

if (!mode || !input) {
  console.error('Usage: node security-check.mjs <text|command|url|path> <value>');
  process.exit(2);
}

const RULES = {
  text: [
    { level: 'BLOCK', label: 'prompt-injection', re: /(ignore (all|previous) instructions|developer mode|system override|reveal (the )?system prompt|bypass safety|jailbreak)/i },
    { level: 'BLOCK', label: 'secret', re: /(sk-[a-z0-9]{16,}|ghp_[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|-----BEGIN (RSA|OPENSSH|EC) PRIVATE KEY-----|xox[baprs]-[A-Za-z0-9-]+)/i },
    { level: 'WARN', label: 'exfiltration', re: /(send (me|this|that).*(token|secret|key|cookie)|upload .*?(\.env|id_rsa|passwd)|pastebin|webhook)/i },
    { level: 'WARN', label: 'obfuscation', re: /(```json|@context|mainEntity|acceptedAnswer|\| .* \| .* \|)/i }
  ],
  command: [
    { level: 'BLOCK', label: 'destructive-shell', re: /(rm -rf|mkfs|dd if=|shutdown|reboot|:\(\)\{

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 · scripts/security-check.mjs (reported line 33)May include surrounding context.

js
path: [
    { level: 'BLOCK', label: 'traversal', re: /(\.\.\/|\.\.\\)/ },
    { level: 'BLOCK', label: 'sensitive-path', re: /(\/etc\/passwd|\/proc\/|id_rsa|\.env|keychain|\/var\/run\/docker\.sock|authorized_keys)/i },
    { level: 'WARN', label: 'home-secret-path', re: /(\.ssh|\.gnupg|\.aws|\.npmrc|\.pypirc)/i }
  ]
};

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs users to run multiple shell scripts but does not declare any tool scope such as permissions or allowed-tools. That creates an undeclared execution capability boundary, making it easier for the skill to be used in environments where shell access is broader than reviewers expect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script writes audit output to a hard-coded path inside a specific user's Obsidian vault, creating an undocumented side effect outside the provided input/output contract. This can leak potentially sensitive audit data into an unrelated note repository and causes the skill to modify user-local content in a location that may not match user intent or the skill's declared security-guard purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Embedding a fixed capability to write into '/Users/m1/Desktop/obsidianvault/ClawLite' is unsafe because it grants file-system write behavior to a personal directory unrelated to the input JSON path. In a security-oriented skill, hidden writes to a specific desktop vault increase risk because findings may contain sensitive paths, excerpts, or secrets that get copied into a broader note system without explicit consent.

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
scripts/prepublish-guard.mjs:13