Back to skill

Security audit

Skill Auditor

Security checks for vulnerabilities and agentic risk

Overview

This is a local skill-auditing tool, but its implementation can persist unintended sensitive files and can miss or suppress important security findings.

Review before installing. Run this only in a contained workspace or after fixing symlink rejection and containment checks, and do not rely on its risk score alone until SKILL.md scanning and metadata-based finding suppression are corrected. Keep notification targets local or trusted because diffs and snapshots can contain sensitive content.

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

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/skills_audit.py:108
Finding

External Symlinks Can Expose Host Files Through Audit Snapshots

Content
View full analysis
list[Path]: files: list[Path] = [] for p in dir_path.rglob("*"): if p.is_file(): if "/.git/" in str(p) or "/__pycache__/" in str(p): continue if p.suffix == ".pyc": continue files.append(p) files.sort(key=lambda x: str(x)) return files ``` ```python repo = ensure_snapshots_repo() dest = repo / "skills" # rsync: mirror skills_dir to snapshots/skills, excluding .git and __pycache__ if dest.exists(): shutil.rmtree(dest) shutil.copytree( skills_dir, dest, ignore=shutil.ignore_patterns(".git", "__pycache__", "*.pyc"), ) ``` ### Technical Analysis The auditor recursively processes files without rejecting symbolic links or verifying that each resolved path remains beneath the audited Skill directory. `Path.is_file()` follows a symbolic link when its target is a regular file. Subsequent calls that hash or read that path also follow the link. In addition, `shutil.copytree()` uses `symlinks=False` by default, which copies the contents of a file referenced by a symbolic link rather than preserving the link itself. Consequently, a Skill controlled by an untrusted author can contain a link to any file readable by the account running the auditor. The linked target may then be: 1. Read while calculating hashes or conducting static analysis. 2. Copied into `~/.openclaw/skills-audit/snapshots/skills/`. 3. Committed to the local Git snapshot history. 4. Exposed later through diff inspection or another process that reads the snapshot. The behavior crosses the intended boundary of `workspace/skills` and is not necessary for static auditing. ### Attack Path 1. An attacker publishes a Skill containin ...[truncated 1316 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/skills_audit.py:241
Finding

Skill Instruction Files Are Excluded from Security Scanning

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/skills_audit.py:176
Finding

Attacker-Controlled Descriptions Can Suppress Security Findings

Content
View full analysis
list[str]: """Match a skill's description against context profiles. Return matched profile names.""" if not description: return [] desc_lower = description.lower() matched = [] for name, profile in profiles.items(): keywords = profile.get("keywords", []) for kw in keywords: if kw.lower() in desc_lower: matched.append(name) break return matched ``` ```python for pname in matched_profiles: profile = profiles.get(pname, {}) for rule_id in profile.get("ignore_rules", []): ignore_rules.add(rule_id) for rule_id, new_sev in profile.get("downgrade_rules", {}).items(): # Keep the lowest severity if multiple profiles downgrade if rule_id not in downgrade_map: downgrade_map[rule_id] = new_sev adjusted = [] for f in findings: rid = f["rule_id"] if rid in ignore_rules: continue # Skip this finding entirely if rid in downgrade_map: f = dict(f) # shallow copy f["severity"] = downgrade_map[rid] f["context_downgraded"] = True adjusted.append(f) ``` ```python # Also try to extract description from SKILL.md frontmatter if not provided if not matched_profiles and not skill_description: skill_md = skill_dir / "SKILL.md" if skill_md.exists(): text = safe_read_text(skill_md, max_bytes=2000) # Simple frontmatter extraction if text.startswith("---"): end = text.find("---", 3) if end > 0: fm = text[3:end] for line in fm.splitlines(): if line.strip().start ...[truncated 2971 chars]
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (62)

YARA rule 'reverse_shell': Reverse shell patterns in scripts or source code [malware]

Critical
Category
YARA Match
Confidence
85% confidence
Finding

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

Content

Scanner excerpt · config/risk-rules.json (reported line 355)May include surrounding context.

json
"aws_secret_access",
        "GOOGLE_APPLICATION_CREDENTIALS",
        "BEGIN RSA PRIVATE KEY",
        "BEGIN OPENSSH PRIVATE KEY",
        "BEGIN EC PRIVATE KEY",
        "BEGIN PGP PRIVATE KEY"
      ]
    },
    {
      "id": "NETWORK_EXFILTRATION",
      "severity": "high",
      "description": "Data exfiltration, reverse shells, and covert network channels",
      "needles": [
        "bash -i >& /dev/tcp/",
        "bash -i >& /dev/udp/",
        "/dev/tcp/",
        "/dev/udp/",
        "nc -e",
        "nc -c",
        "ncat -e",
        "ncat -c",
        "netcat -e",
        "netcat -c",
        "socat exec:",
        "socat tcp:",
        "reverse_tcp",
        "reverse_https",
        "meterpreter",
        "webhook.site",
        "requestbin",
        "dns-exfil",
        "dnscat",
        "iodine"
      ]
    },
    {
      "id": "NETWORK_GENERAL",
      "severity": "medium",
      "description": "General network access and HTTP clients",
      "needles": [

YARA rule 'c2_framework_indicators': Command-and-control framework indicators (Cobalt Strike, Metasploit, Sliver, etc.) [malware]

Critical
Category
YARA Match
Confidence
85% confidence
Finding

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

Content

Scanner excerpt · config/risk-rules.json (reported line 369)May include surrounding context.

json
xfiltration, reverse shells, and covert network channels",
      "needles": [
        "bash -i >& /dev/tcp/",
        "bash -i >& /dev/udp/",
        "/dev/tcp/",
        "/dev/udp/",
        "nc -e",
        "nc -c",
        "ncat -e",
        "ncat -c",
        "netcat -e",
        "netcat -c",
        "socat exec:",
        "socat tcp:",
        "reverse_tcp",
        "reverse_https",
        "meterpreter",
        "webhook.site",
        "requestbin",
        "dns-exfil",
        "dnscat",
        "iodine"
      ]
    },
    {
      "id": "NETWORK_GENERAL",
      "severity": "medium",
      "description": "General network access and HTTP clients",
      "needles": [
        "http://",
        "https://",
        "curl ",
        "wget ",
        "requests.",
        "requests.get",
        "requests.post",
        "urllib.request",
        "urllib.urlopen",
        "aiohttp",
        "httpx.",
        "axios.",
        "node-fetch",
        "paramiko",
        "fabric",
        "te

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`skills_audit.py` performs static inspection of installed skill directories:

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`skills_audit.py` performs static inspection of installed skill directories:

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`skills_audit.py` performs static inspection of installed skill directories:

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

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

md
**Prohibited behaviors**:
- ❌ Running `git diff` and bypassing the structured `show` output path
- ❌ Defaulting to send raw full diff content to external channels without warning
- ❌ Automatically pushing large raw change content to external channels
- ✅ Prefer a safe summary based on `show`; provide full raw content only on explicit request

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

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

Content

Scanner excerpt · config/risk-rules.json (reported line 339)May include surrounding context.

json
"authorized_keys",
        "id_rsa",
        "id_ed25519",
        "/etc/shadow",
        "/etc/sudoers",
        "aws_access_key",
        "aws_secret_access",

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 · config/risk-rules.json (reported line 384)May include surrounding context.

json
"needles": [
        "http://",
        "https://",
        "curl ",
        "wget ",
        "requests.",
        "requests.get",

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 · config/risk-rules.json (reported line 385)May include surrounding context.

json
"http://",
        "https://",
        "curl ",
        "wget ",
        "requests.",
        "requests.get",
        "requests.post",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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 · config/risk-rules.json (reported line 405)May include surrounding context.

json
"severity": "high",
      "description": "Dangerous file system operations",
      "needles": [
        "rm -rf /",
        "rm -rf ~",
        "rm -rf /*",
        "mkfs",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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 · config/risk-rules.json (reported line 407)May include surrounding context.

json
"severity": "high",
      "description": "Dangerous file system operations",
      "needles": [
        "rm -rf /",
        "rm -rf ~",
        "rm -rf /*",
        "mkfs",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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 · config/risk-rules.json (reported line 405)May include surrounding context.

json
"severity": "high",
      "description": "Dangerous file system operations",
      "needles": [
        "rm -rf /",
        "rm -rf ~",
        "rm -rf /*",
        "mkfs",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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 · config/risk-rules.json (reported line 406)May include surrounding context.

json
"description": "Dangerous file system operations",
      "needles": [
        "rm -rf /",
        "rm -rf ~",
        "rm -rf /*",
        "mkfs",
        "dd if=",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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 · config/risk-rules.json (reported line 407)May include surrounding context.

json
"needles": [
        "rm -rf /",
        "rm -rf ~",
        "rm -rf /*",
        "mkfs",
        "dd if=",
        "wipefs",

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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 · config/risk-rules.json (reported line 407)May include surrounding context.

json
"needles": [
        "rm -rf /",
        "rm -rf ~",
        "rm -rf /*",
        "mkfs",
        "dd if=",
        "wipefs",

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 · config/risk-rules.json (reported line 414)May include surrounding context.

json
"shred ",
        "> /dev/sda",
        "> /dev/nvme",
        "chmod 777",
        "chmod -R 777",
        "Format-Volume",
        "Clear-Disk"

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · config/risk-rules.json (reported line 448)May include surrounding context.

json
"needles": [
        "docker.sock",
        "/var/run/docker",
        "docker run --privileged",
        "--pid=host",
        "--net=host",
        "--ipc=host",

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · config/risk-rules.json (reported line 449)May include surrounding context.

json
"docker.sock",
        "/var/run/docker",
        "docker run --privileged",
        "--pid=host",
        "--net=host",
        "--ipc=host",
        "nsenter",

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · config/risk-rules.json (reported line 450)May include surrounding context.

json
"/var/run/docker",
        "docker run --privileged",
        "--pid=host",
        "--net=host",
        "--ipc=host",
        "nsenter",
        "unshare -m",

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · config/risk-rules.json (reported line 451)May include surrounding context.

json
"docker run --privileged",
        "--pid=host",
        "--net=host",
        "--ipc=host",
        "nsenter",
        "unshare -m",
        "/proc/self/exe",

Privileged Container / Container Escape

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Potential security issue detected. Manual review is recommended.

Content

Scanner excerpt · config/risk-rules.json (reported line 452)May include surrounding context.

json
"--pid=host",
        "--net=host",
        "--ipc=host",
        "nsenter",
        "unshare -m",
        "/proc/self/exe",
        "/proc/1/root",

YARA rule 'crypto_stratum_protocol': Stratum mining protocol usage (stratum+tcp/ssl, mining.subscribe/authorize) [cryptominers]

High
Category
YARA Match
Confidence
90% confidence
Finding

YARA rule matched cryptocurrency mining indicators (stratum protocol, mining pools, miner binaries, or cryptojacking scripts).

Content

Scanner excerpt · config/risk-rules.json (reported line 466)May include surrounding context.

json
id=host",
        "--net=host",
        "--ipc=host",
        "nsenter",
        "unshare -m",
        "/proc/self/exe",
        "/proc/1/root",
        "cgroup escape",
        "release_agent",
        "/var/run/secrets/kubernetes.io"
      ]
    },
    {
      "id": "CRYPTO_MINING",
      "severity": "extreme",
      "description": "Cryptocurrency mining indicators",
      "needles": [
        "stratum+tcp://",
        "stratum+ssl://",
        "xmrig",
        "cpuminer",
        "cgminer",
        "bfgminer",
        "minerd",
        "minergate",
        "coinhive",
        "cryptonight",
        "randomx",
        "pool.minexmr",
        "pool.supportxmr"
      ]
    },
    {
      "id": "CODE_INJECTION",
      "severity": "high",
      "description": "Code injection and template injection patterns",
      "needles": [
        "curl | sh",
        "curl | bash",
        "wget | sh",
        "wget | bash",
        "eval \"$(curl",
        "eval \"$(wget",
        "xargs sh -c",

YARA rule 'crypto_miner_software': References to known cryptocurrency mining software [cryptominers]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched cryptocurrency mining indicators (stratum protocol, mining pools, miner binaries, or cryptojacking scripts).

Content

Scanner excerpt · config/risk-rules.json (reported line 468)May include surrounding context.

json
,
        "nsenter",
        "unshare -m",
        "/proc/self/exe",
        "/proc/1/root",
        "cgroup escape",
        "release_agent",
        "/var/run/secrets/kubernetes.io"
      ]
    },
    {
      "id": "CRYPTO_MINING",
      "severity": "extreme",
      "description": "Cryptocurrency mining indicators",
      "needles": [
        "stratum+tcp://",
        "stratum+ssl://",
        "xmrig",
        "cpuminer",
        "cgminer",
        "bfgminer",
        "minerd",
        "minergate",
        "coinhive",
        "cryptonight",
        "randomx",
        "pool.minexmr",
        "pool.supportxmr"
      ]
    },
    {
      "id": "CODE_INJECTION",
      "severity": "high",
      "description": "Code injection and template injection patterns",
      "needles": [
        "curl | sh",
        "curl | bash",
        "wget | sh",
        "wget | bash",
        "eval \"$(curl",
        "eval \"$(wget",
        "xargs sh -c",
        "SSTI",
        "Server-Side Template"
      ]

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 · config/risk-rules.json (reported line 487)May include surrounding context.

json
"description": "Code injection and template injection patterns",
      "needles": [
        "curl | sh",
        "curl | bash",
        "wget | sh",
        "wget | bash",
        "eval \"$(curl",

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 · config/risk-rules.json (reported line 488)May include surrounding context.

json
"needles": [
        "curl | sh",
        "curl | bash",
        "wget | sh",
        "wget | bash",
        "eval \"$(curl",
        "eval \"$(wget",

Static analysis

No suspicious patterns detected.