Back to skill

Security audit

Arc Shield

Security checks for vulnerabilities and agentic risk

Overview

Arc-shield is a coherent local secret-scanning skill, but its advertised safety controls are unreliable and can expose the very secrets users expect it to block.

Install only if you treat this as an experimental scanner, not a dependable leak-prevention boundary. Do not route real secrets through its report mode, and do not rely on --strict or the Python entropy controls to guarantee blocking until the implementation is fixed and tested.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/arc-shield.sh:251
Finding

Strict mode emits sensitive input before blocking it

Content
View full analysis
&2 exit 1 fi ``` ```python elif args.strict: print(text) critical_count = len([f for f in guard.findings if f.severity == CRITICAL]) if critical_count > 0: guard.print_report() print("\n[BLOCKED] Critical secrets detected. Message blocked.", file=sys.stderr) sys.exit(1) ``` ### Technical Analysis Both implementations write the complete, unredacted input to standard output before checking whether critical findings require the message to be blocked. Process exit status does not retract data already written to stdout. This violates the expected behavior of a strict output security boundary. Any caller that captures, logs, pipes, or forwards scanner output can receive the secret even though the scanner subsequently returns a failure status. ### Attack Path 1. An outbound message contains a recognized credential, such as a GitHub personal access token. 2. The message is passed to either scanner with `--strict`. 3. The scanner prints the original message, including the credential, to stdout. 4. A parent process, pipeline, hook, command substitution, or logging system captures that output. 5. The scanner exits with status 1 only after the sensitive content has already been disclosed. ### Impact Assessment No additional operating-system privileges are obtained. The affected scope is the full input message, including any credentials, private keys, PII, or tokens it contains. Disclosure can occur to downstream processes, terminal capture, CI output, hook consumers, or external messaging integrations. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/arc-shield.sh:158
Finding

Bash scanner terminates on the first finding because of arithmetic exit status

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/output-guard.py:267
Finding

Python strict mode does not block high-entropy secrets

Content
View full analysis
0: guard.print_report() print("\n[BLOCKED] Critical secrets detected. Message blocked.", file=sys.stderr) sys.exit(1) ``` The integration expects strict mode to block entropy findings: ```bash if ! echo "$MESSAGE" | python3 "$OUTPUT_GUARD" --strict > /dev/null 2>&1; then echo "❌ BLOCKED: High-entropy secret detected" >&2 echo "$MESSAGE" | python3 "$OUTPUT_GUARD" --report >&2 exit 1 fi ``` ### Technical Analysis Entropy-based detections are assigned `HIGH` severity, while strict mode only counts `CRITICAL` findings when deciding whether to return failure. Consequently, a novel credential detected solely through entropy analysis is recorded but does not cause strict mode to block the message. The example wrapper incorrectly assumes that a failed Python strict check indicates a high-entropy finding. Under the current implementation, entropy-only findings produce a successful exit status. ### Attack Path 1. An attacker or accidental output supplies a high-entropy credential that does not match any fixed CRITICAL regex. 2. Entropy analysis records it as `HIGH`. 3. Strict mode counts only `CRITICAL` findings. 4. The scanner exits successfully. 5. The safe-message wrapper treats the message as approved and permits it to proceed to the sending stage. ### Impact Assessment No additional lo ...[truncated 245 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
examples/send-safe-message.sh:22
Finding

Diagnostic reports disclose the detected secret values

Content
View full analysis
&2 echo "$matches" | while IFS= read -r match; do # Truncate long matches for display if [[ ${#match} -gt 60 ]]; then match="${match:0:57}..." fi echo " → ${match}" >&2 done ``` ```python def __repr__(self): truncated = self.value[:60] + "..." if len(self.value) > 60 else self.value return f"[{self.severity}] {self.category}: {truncated}" ``` ```python if report['summary']['critical'] > 0: print("\nCRITICAL FINDINGS:", file=sys.stderr) for finding in report['findings']['critical']: print(f" {finding}", file=sys.stderr) if report['summary']['high'] > 0: print("\nHIGH FINDINGS:", file=sys.stderr) for finding in report['findings']['high']: print(f" {finding}", file=sys.stderr) ``` The safe-send example invokes these reports after detecting a secret: ```bash if ! echo "$MESSAGE" | "$ARC_SHIELD" --strict > /dev/null 2>&1; then echo "❌ BLOCKED: Message contains critical secrets (regex detection)" >&2 echo "$MESSAGE" | "$ARC_SHIELD" --report >&2 exit 1 fi if ! echo "$MESSAGE" | python3 "$OUTPUT_GUARD" --strict > /dev/null 2>&1; then echo "❌ BLOCKED: High-entropy secret detected" >&2 echo "$MESSAGE" | python3 "$OUTPUT_GUARD" --report >&2 exit 1 fi ``` ### Technical Analysis Both reporting implementations include plaintext portions of matched values. Truncation is not adequate secret protection because many credentials remain usable or identifiable within the first 60 characters. The integration example automatically runs report mode on messages already known to contain sensitive data. Since repor ...[truncated 808 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/arc-shield.sh:58
Finding

Combining strict and redact options silently disables strict blocking

Content
View full analysis
&2 exit 1 fi ``` ### Technical Analysis Strictness and output behavior are represented by one `MODE` variable. Each option overwrites the prior value. With the documented argument order, `--redact` replaces `--strict`, so the script runs only in redaction mode. Redaction mode returns success rather than enforcing strict blocking. The documented caller therefore cannot rely on `EXIT_CODE` to determine whether a critical secret was detected. This is especially dangerous where redaction coverage is incomplete, because an unredacted secret can remain in output while the process still reports success. ### Attack Path 1. An integrator follows the documented `--strict --redact` example. 2. Argument parsing first sets `MODE` to `strict`. 3. Parsing `--redact` overwrites `MODE` with `redact`. 4. A message contains a critical secret, including one not handled by the redaction substitutions. 5. The script executes redaction mode and returns success. 6. The wrapper skips its blocking branch and sends or stores the resulting message. ### Impact Assessment No local privilege escalation occurs. The security boundary for outbound messages is bypassed. The affected scope includes every integration that combines these options and assumes it receives both redaction ...[truncated 29 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/output-guard.py:248
Finding

Documented custom configuration and entropy controls are ignored

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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The uninstall command uses rm -rf on a user-controlled filesystem path. Even though the path is specific to the skill directory, recursive forced deletion is dangerous because path typos, variable expansion surprises, or copy/paste mistakes can lead to unintended file removal.

Content

Scanner excerpt · INSTALLATION.md (reported line 233)May include surrounding context.

Uninstall

bash
rm -rf ~/.openclaw/workspace/skills/arc-shield

That's it. No system changes, no dependencies to clean up.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The uninstall command uses rm -rf on a user-controlled filesystem path. Even though the path is specific to the skill directory, recursive forced deletion is dangerous because path typos, variable expansion surprises, or copy/paste mistakes can lead to unintended file removal.

Content

Scanner excerpt · INSTALLATION.md (reported line 233)May include surrounding context.

Uninstall

bash
rm -rf ~/.openclaw/workspace/skills/arc-shield

That's it. No system changes, no dependencies to clean up.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This is a true vulnerability because the implementation contradicts the security promises in the header and help text. The script can disclose secrets twice: by passing raw content through stdout and by echoing matched secret fragments in warning output to stderr, which may be logged or exposed in terminals and CI systems. Misleading security tooling increases operational risk because users may rely on it as a protection boundary when it is not one.

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 · scripts/arc-shield.sh (reported line 228)May include surrounding context.

sh
# Report findings
    report_finding "CRITICAL" "1Password Service Account Token" "$findings_1pass"
    report_finding "CRITICAL" "GitHub Personal Access Token" "$findings_github"
    report_finding "CRITICAL" "OpenAI API Key" "$findings_openai"
    report_finding "CRITICAL" "Stripe API Key" "$findings_stripe"
    report_finding "CRITICAL" "AWS Access Key" "$findings_aws"

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This is a true vulnerability. In both default mode and strict mode, the script prints the original input to stdout, so any detected secret is still leaked downstream even though the tool presents itself as a sanitization barrier. In strict mode this is especially dangerous because the message is emitted before the block decision, defeating the core security claim of preventing accidental secret disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This is a true vulnerability. Strict mode is expected to prevent disclosure, but it emits the original sensitive content before checking FOUND_CRITICAL and exiting with a block message, so pipelines, logs, or downstream consumers can still receive the secret. The missing warning in help text worsens the issue because users are likely to trust strict mode for enforcement.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The comment/help text claims strict mode will block on critical findings, but the implementation later emits the message before blocking. This mismatch is dangerous because operators will rely on the documented security guarantee and may deploy the tool in data-loss-prevention paths where the secret has already escaped by the time the block occurs.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This is a true vulnerability: in --strict mode the program prints the original text to stdout before checking whether critical secrets were found and exiting with an error. That defeats the advertised blocking behavior and can leak secrets into logs, pipes, terminals, or downstream tools even when the tool reports the message as blocked.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This is a true vulnerability because the tool presents strict mode as a safety control, yet still sends unsanitized content to stdout before signaling failure. In the context of an output-sanitization skill whose purpose is to prevent secret leakage, this makes the issue more dangerous because users are especially likely to trust it as a last-line guard and route sensitive model output through it.

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 · examples/demo.sh (reported line 65)May include surrounding context.

sh
# === WARN ===

[DETECT:SECRET_PATH] Check the file at ~/.secrets/instagram-password.txt

[DETECT:SECRET_PATH] Found in /home/user/.config/tokens/github-pat.json

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 · tests/quick-test.sh (reported line 106)May include surrounding context.

sh
# === WARN ===

[DETECT:SECRET_PATH] Check the file at ~/.secrets/instagram-password.txt

[DETECT:SECRET_PATH] Found in /home/user/.config/tokens/github-pat.json

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 · tests/test-samples.txt (reported line 37)May include surrounding context.

text
# === WARN ===

[DETECT:SECRET_PATH] Check the file at ~/.secrets/instagram-password.txt

[DETECT:SECRET_PATH] Found in /home/user/.config/tokens/github-pat.json

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · INSTALLATION.md (reported line 18)May include surrounding context.

If not using git:

bash
# Create directory
mkdir -p ~/.openclaw/workspace/skills/arc-shield/{scripts,config,tests,examples}

# Download files (or copy manually)

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The wrapper-script instructions direct the user to place an executable in ~/.openclaw/bin/send-safe, which creates a persistent command in the user's environment. Although intended as a safety integration, this is a form of session persistence because it installs durable behavior that may continue intercepting or influencing message sending after the initial setup.

Content

Scanner excerpt · INSTALLATION.md (reported line 88)May include surrounding context.

Method 2: Wrapper Script

Create a send-safe command:

bash
# ~/.openclaw/bin/send-safe

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The uninstall section instructs users to run a recursive deletion command but does not explicitly warn that the action is irreversible and will permanently remove the skill directory. While the target path is fairly specific, documentation that normalizes rm -rf without a warning increases the risk of accidental data loss if the path is edited, expanded incorrectly, or copied carelessly.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
tests/test-samples.txt:14