Back to skill

Security audit

shieldswarm-redteam-resilience

Security checks for vulnerabilities and agentic risk

Overview

The skill is openly defensive, but important safety gates can incorrectly approve unsafe commands or approval checks, so it needs review before operational use.

Install only if you need this defensive workflow and can keep it tightly scoped. Do not rely on its validator or approval_gate.sh as the sole authorization control for production changes, red-team exercises, or risky commands; require exact human approval, review commands manually, and protect or delete local approval and feedback logs.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/approval_gate.sh:66
Finding
Approval Verification Can Be Bypassed with Regular-Expression Input<![CDATA[ ## Vulnerability Details **File Location**: `scripts/approval_gate.sh`, lines 66–80 **Vulnerability Type**: Improper input handling in an authorization control **Risk Level**: High ### Vulnerable Code ```bash if [ -n "$ID" ]; then if grep -q "\"id\": *\"$ID\"" "$FILE" 2>/dev/null; then echo "approval_status=found id=$ID" exit 0 else echo "approval_status=missing id=$ID" exit 1 fi elif [ -n "$SCOPE" ]; then if grep -q "\"scope\": *\"$SCOPE\"" "$FILE" 2>/dev/null; then echo "approval_status=found scope=$SCOPE" exit 0 else echo "approval_status=missing scope=$SCOPE" exit 1 fi ``` ### Technical Analysis The script embeds the caller-controlled `ID` or `SCOPE` directly into a basic regular expression passed to `grep`. Regular-expression metacharacters are not escaped, and the JSONL file is not parsed as JSON. An input such as `.*` can therefore match the value of an unrelated approval record. The check also verifies only the requested ID or scope and does not bind the approval to other security-relevant properties such as risk, approver, operator, rollback owner, expiration, or the exact proposed action. This undermines the package's approval gate because a successful textual match is reported as a valid approval even when no exact approval exists for the requested operation. ### Attack Path 1. Obtain access to invoke `approval_gate.sh` and identify any approval JSONL file containing at least one record. 2. Supply a regular-expression value instead of a literal approval identifier, for example: ```bash bash scripts/approval_gate.sh --file approval.jsonl --check --id '.*' ``` 3. `grep` interprets `.*` as a wildcard and matches an unrelated record. 4. The script returns exit status zero and prints `approval_status=found`. 5. A downstream operator or automation process trusts this result and proceeds with an operation that was not actually approved. ### Impact Assessment An attacker able to control ...[truncated 492 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Parse each JSONL line with a real JSON parser instead of searching serialized JSON with `grep`. - Compare identifiers and scopes using exact string equality. - Reject malformed JSON records rather than silently treating them as searchable text. - Bind each approval to all relevant attributes, including the exact action or command digest, scope, risk, operator, approver, rollback owner, creation time, and expiration. - Reject duplicate approval IDs and define explicit revocation and expiry semantics. - If shell-only portability is mandatory, escape every regular-expression metacharacter and use fixed-string matching, although structured JSON parsing remains the preferred solution. - Add regression tests for values such as `.*`, `[a-z]`, `^`, `$`, backslashes, quotes, embedded newlines, duplicate IDs, expired approvals, and mismatched scopes. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/shieldswarm_validate.sh:38
Finding
Fail-Open Command Validator Can Approve Unsafe Commands<![CDATA[ ## Vulnerability Details **File Location**: `scripts/shieldswarm_validate.sh`, lines 38–151 **Vulnerability Type**: Incomplete dangerous-command detection and missing failure-state propagation **Risk Level**: High ### Vulnerable Code ```bash OFFENSIVE=" nmap masscan sqlmap hydra msfconsole metasploit slowloris hping3 nikto gobuster ffuf dirb wpscan acunetix evilginx " check_offensive() { local c="$1" p for p in $OFFENSIVE; do case " $c " in *" $p "*|*" $p "*) echo "check=offensive_pattern status=detected pattern=$p" FAIL=1 return 0 ;; esac done # stealth / evasion keywords (word-ish match) case " $c " in *fronting*|*"stealth tunnel"*|*"covert channel"*|*"vpn evasion"*|*obfuscat*) echo "check=offensive_pattern status=detected pattern=stealth_or_evasion" FAIL=1 return 0 ;; esac # load-generation / flood flags case "$c" in *wrk*|*siege*|*"ab -n"*|*"ab -c"*|*flood*) echo "check=offensive_pattern status=detected pattern=load_generation" FAIL=1 return 0 ;; esac echo "check=offensive_pattern status=clean" return 0 } ``` ```bash check_mode() { case "$MODE" in red_team) [ -n "$ROE" ] || { echo "check=mode_gate status=missing_roe"; FAIL=1; return 0; } [ -f "$ROE" ] || { echo "check=mode_gate status=roe_not_found file=$ROE"; FAIL=1; return 0; } # ROE validation omitted ;; *) echo "check=mode_gate status=not_required mode=$MODE" ;; esac return 0 } ``` ```bash check_length() { local n=${#CMD} if [ -n "$MAXLEN" ] && [ "$n" -gt "$MAXLEN" ]; then echo "check=command_length status=exceeds_limit length=$n limit=$MAXLEN" return 0 fi if [ -z "$MAXLEN" ] && [ "$n" -gt 4000 ]; then echo "check=command_length status=exceeds_limit length=$n limit=4000 default=4000" return 0 fi echo "check=command_length status=within_limit length=$n" return 0 } ``` ### Technical Analysis The validato ...[truncated 2219 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Reject every mode not included in an explicit allowlist. - Set `FAIL=1` for every failed check, including both command-length branches. - Prefer an allowlist of supported executable names, arguments, and command structures over a blacklist. - Parse commands into tokens without executing them and normalize executable paths before comparison. - Reject shell metacharacters, substitutions, redirections, control operators, encoded payloads, and interpreter wrappers unless a narrowly defined workflow explicitly requires them. - Do not treat static validation as authorization to execute a command. Require human review and execute through a constrained API or sandbox. - Add adversarial regression tests covering absolute and relative executable paths, punctuation boundaries, aliases, wrappers, mixed case, quoting, command substitution, pipelines, redirections, newline injection, unknown modes, and oversized commands. - Ensure every reported non-clean status necessarily produces a nonzero final exit status. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:29
Finding
Installation Guidance Executes an Unpinned Mutable npm Package<![CDATA[ ## Vulnerability Details **File Location**: `README.md`, lines 29–32 **Vulnerability Type**: Unpinned executable dependency **Risk Level**: Medium ### Vulnerable Code ```bash npx --yes clawhub@latest install @orionshaowswmw/shieldswarm-redteam-resilience ``` ### Technical Analysis The documented installation command asks `npx` to retrieve and execute the mutable `latest` release of `clawhub`. The `--yes` option suppresses the normal interactive confirmation. No exact version or package integrity value is supplied. As a result, the code executed by the installation command can change after this skill package has been reviewed. Compromise of the upstream npm account, registry package, publication pipeline, or mutable release tag could turn the installation command into a code-execution path. ### Attack Path 1. An attacker compromises the upstream `clawhub` npm package, its publisher account, or its release pipeline. 2. The attacker publishes a malicious release that becomes the package's `latest` version. 3. A user follows the README installation instructions. 4. `npx --yes` downloads and executes the malicious package without an interactive review prompt. 5. The payload runs with the privileges and environment of the user performing the installation. ### Impact Assessment A compromised dependency may execute arbitrary code with the installer's privileges. Potential impact includes reading or modifying files accessible to that user, accessing environment variables and credentials, altering installed packages, or making network requests. The audited repository does not itself contain the hypothetical upstream payload; the risk arises because its installation guidance delegates execution to mutable, unpinned third-party content. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `clawhub` to a specific audited version rather than using `@latest`. - Publish and verify an integrity digest or signed provenance statement for the installer package. - Avoid `--yes` where an interactive confirmation provides meaningful review. - Document the expected registry and protect against registry substitution. - Verify the package archive before executing installation logic. - Use a locked dependency manifest where supported. - Provide a review-first installation method that downloads the package without executing it, verifies its digest or signature, and only then invokes the installer. - Establish a process for promptly revoking or warning against compromised installer versions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
tools/self_improve.py:60
Finding
Feedback Memory File Is Written Without Explicit Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `tools/self_improve.py`, lines 60–63 **Vulnerability Type**: Insecure local storage permissions **Risk Level**: Medium ### Vulnerable Code ```python FEEDBACK.parent.mkdir(parents=True, exist_ok=True) with FEEDBACK.open("a", encoding="utf-8") as fh: fh.write(blob + "\n") ``` ### Technical Analysis The feedback mechanism stores durable operational context in `feedback.jsonl`, but the file is opened using the process's default creation mode and umask. Unlike `approval.jsonl`, the code does not explicitly enforce mode `0600`. On a system with a permissive umask, the resulting file may be readable by other local users. The content filter only searches for a limited collection of keywords and credential patterns; it is not a comprehensive detector for personal data, proprietary identifiers, internal hostnames, access tokens using unknown formats, or other sensitive operational information. The code also does not verify that the target is a regular file owned by the expected user before appending, leaving filesystem-link and pre-existing-file concerns unaddressed. ### Attack Path 1. Run the feedback logger in an environment with a permissive umask or with a pre-existing improperly protected `feedback.jsonl`. 2. Log operational context that is not detected by the limited keyword filter. 3. The context is appended to a file without explicit restrictive permissions. 4. Another local user with filesystem access reads the feedback file. 5. The reader obtains internal operational details or sensitive values that were not recognized by the filter. ### Impact Assessment The direct impact is local confidentiality loss. Exposed information is limited to data written to `feedback.jsonl`, but that data may include incident context, model-routing details, internal component names, or other operational metadata. This issue does not itself provide privilege escalation or remote access. The affected scope is the loca ...[truncated 60 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create `feedback.jsonl` atomically with mode `0600`, such as by using `os.open` with `O_CREAT`, `O_APPEND`, and an explicit permission mode. - Verify the ownership, type, and permissions of an existing feedback file before writing. - Reject symbolic links and non-regular files; where available, use no-follow semantics. - Correct permissions that are broader than intended or fail closed with a clear error. - Minimize stored context and apply structured field-level redaction rather than relying only on keyword matching. - Document retention and deletion requirements for feedback data. - Add tests under multiple umask settings and tests for symlink, hard-link, and pre-existing-file scenarios. ]]>
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill advertises and instructs use of shell commands, local file reads/writes, and references to model-selection policies, approvals, and feedback logs, but no explicit permissions declaration is present. That mismatch can undermine least-privilege enforcement and cause the host to grant broader capabilities implicitly than reviewers or operators expect, increasing the chance of unsafe execution in a security-sensitive skill.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
This is a real fail-open logic bug: check_length emits an exceeds_limit status, but it never sets FAIL=1, so oversized commands still receive verdict=PASS if the other checks succeed. In a defensive command validator, that undermines the stated paste-bomb/size guard and allows attackers or careless users to submit excessively large inputs that may bypass intended review constraints or stress downstream consumers.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/shieldswarm_validate.sh:77