Back to skill

Security audit

Humanize Text

Security checks for vulnerabilities and agentic risk

Overview

This text-humanizing skill is purpose-aligned, but it needs review because it uploads submitted text or file contents to an external API and has incomplete safeguards around sensitive files and exposed request data.

Install only if you are comfortable sending the text you process, including selected file contents, to Evolink. Avoid using it on secrets, credentials, regulated data, or private documents; keep HUMANIZE_SAFE_DIR narrow, and be aware that the API key and submitted text may be visible to local process-monitoring tools while curl runs.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/humanize.sh:35
Finding
Sensitive file protections can be bypassed through incomplete path validation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/humanize.sh:35-50` **Vulnerability Type**: Incomplete sensitive-file path validation **Risk Level**: Medium ### Vulnerable Code ```bash SAFE_DIR="${HUMANIZE_SAFE_DIR:-$HOME/.openclaw/workspace}" # Normalize: ensure SAFE_DIR ends with / SAFE_DIR="${SAFE_DIR%/}/" if [[ "$resolved" != "$SAFE_DIR"* ]]; then echo "Error: Access restricted to $SAFE_DIR" >&2 exit 1 fi # 4. Filename blacklist local basename basename=$(basename "$resolved") case "$basename" in .env*|*.key|id_rsa*|authorized_keys|.bash_history|config.json|.ssh|*.pem|*.p12|*.pfx|shadow|passwd) echo "Error: Access to sensitive files is blocked." >&2 exit 1 ;; esac ``` ### Technical Analysis The script intends to prevent sensitive files from being uploaded to the Evolink API, but its protection is based only on the final basename of the resolved input path. Sensitive directory components are not inspected. For example, blacklisting the basename `.ssh` does not block files located inside a `.ssh` directory. A path ending in `.ssh/id_ed25519` has the basename `id_ed25519`, which does not match `.ssh` or `id_rsa*`. Other private-key names not covered by the patterns may similarly pass validation. The configurable `HUMANIZE_SAFE_DIR` is normalized only by appending a slash; it is not canonicalized or constrained against excessively broad values. Setting it to `/` makes the prefix check accept any resolved absolute path. The resulting exposure remains limited to files readable by the account running the Skill, but it exceeds the minimum file-access scope needed for text rewriting. The scanner warning about SSH-key writes is a false positive: these strings form a read denylist, and the script does not write to SSH key files. The actual issue is that the denylist does not reliably prevent sensitive-file reads and subsequent network transmission. ### Attack Path 1. An attacker or unsafe configuration sets ` ...[truncated 1043 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Canonicalize the permitted root using `realpath -e` before performing containment checks. 2. Reject unsafe roots such as `/`, the user's home directory, and other broad system locations. 3. Compare the canonical target against the canonical safe directory with a boundary-safe check. 4. Inspect every path component, not only the final basename, and reject sensitive directories such as `.ssh`, `.gnupg`, and cloud credential directories. 5. Add common credential filenames such as `id_ed25519`, `id_ecdsa`, and `credentials` where appropriate. 6. Prefer an explicit allowlisted upload directory over a filename denylist. 7. Require clear user confirmation before sending file contents to a third-party service. 8. Add tests covering nested sensitive directories, alternative private-key names, symlinks, broad safe-directory settings, and prefix-confusion paths. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/humanize.sh:145
Finding
API credential and submitted document are exposed through process arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/humanize.sh:145-155` **Vulnerability Type**: Sensitive data exposure through command-line arguments **Risk Level**: Medium ### Vulnerable Code ```bash RESPONSE=$(curl -s "$API_URL" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_KEY" \ -d "{ \"model\": \"$MODEL\", \"max_tokens\": 4096, \"system\": $ESCAPED_SYSTEM, \"messages\": [{\"role\": \"user\", \"content\": $ESCAPED_USER}] }") ``` ### Technical Analysis The bearer token is passed directly to `curl` through the `-H` command-line argument. The complete JSON request, including the submitted document, is likewise passed through the `-d` argument. Command-line arguments can be exposed through process-inspection facilities while `curl` is running. The exact visibility depends on the operating system and process-isolation configuration, but local users, monitoring agents, diagnostic tools, or processes with sufficient access may be able to inspect the argument vector. This creates two distinct disclosure risks: - The `EVOLINK_API_KEY` can be captured from the authorization header. - The text being humanized can be captured from the request-body argument. Although transmission to Evolink is declared functionality, exposing the same data to local process inspection is unnecessary and violates least-exposure principles. ### Attack Path 1. A victim invokes `scripts/humanize.sh` with private document content. 2. The script starts `curl` with the API token and complete document embedded in its argument vector. 3. A local observer repeatedly monitors process arguments using available process-inspection interfaces. 4. While the request is active, the observer captures the authorization header or JSON request body. 5. The observer reuses the API key or reads the victim's submitted content. ### Impact Assessment Exploitation can disclose the Evolink API credential and the full t ...[truncated 458 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Stream the JSON request body to `curl` over standard input instead of supplying it as a `-d` argument. 2. Avoid placing authorization secrets directly in the process argument vector. 3. Pass sensitive headers through a protected file descriptor, temporary configuration with restrictive permissions, or another mechanism that does not expose them in process listings. 4. If a temporary file is unavoidable, create it with mode `0600`, use a secure temporary-file API, and delete it reliably with a shell trap. 5. Minimize the lifetime of the API key in child-process-visible state. 6. Document the local confidentiality assumptions and test the implementation on supported operating systems to verify that credentials and document content are absent from observable command-line arguments. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

External Script Fetching

High
Category
Supply Chain
Content
ESCAPED_USER=$(json_escape "$USER_MSG")

# --- Call Evolink API ---
RESPONSE=$(curl -s "$API_URL" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d "{
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The invocation phrases are very broad and overlap with common editing requests, making accidental or implicit triggering more likely in normal conversation. In an agent environment, this can cause user text to be processed by the skill unexpectedly and potentially sent to an external service without sufficiently explicit user intent.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The README mentions an API key and external API documentation but does not clearly and prominently warn that user-provided text is transmitted to a third-party service for processing. This creates a meaningful data-handling and privacy risk because users may submit confidential drafts, emails, or reports believing processing is local or self-contained.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The README makes detailed security and implementation claims about path pinning, sensitive-file blacklists, MIME validation, and local scanning/rewriting components, but those controls are not substantiated in the provided file. Unverified security assurances can mislead users and reviewers into trusting the skill with sensitive content or local files under false assumptions, which is a security-relevant documentation integrity issue.

Session Persistence

Medium
Category
Rogue Agent
Content
- The declared requirements are minimal (`EVOLINK_API_KEY` only) — no unrelated binaries or system dependencies

### Instruction Scope
- SKILL.md instructs the agent to scan and rewrite user-provided text for 24 defined patterns
- It does not instruct reading unrelated files, modifying system config, or exfiltrating data
- All processing is scoped to user-provided text content only
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.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The description says to use the skill for "humanize text" requests and then broadens that to "or similar requests," which creates an open-ended invocation scope. In an agent environment, this can cause the skill to intercept generic editing or rewriting tasks and send user content to an external API without clear user intent or informed consent.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The example trigger "Make this sound more natural" is broad and overlaps with routine editing, proofreading, tone adjustment, and plain rewriting requests. That increases the chance of accidental activation, causing unnecessary data disclosure to the remote provider and unexpected behavior from the agent.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
Automatic language detection without user choice means all submitted text is analyzed by the remote service even when the user has not consented to that processing path or selected a language. In privacy-sensitive contexts, this can expose metadata about the text and remove user control over how content is handled.

External Transmission

Medium
Category
Data Exfiltration
Content
API_KEY="${EVOLINK_API_KEY:?Set EVOLINK_API_KEY first. Get one at https://evolink.ai/signup}"
MODEL="${EVOLINK_MODEL:-claude-opus-4-6}"
API_URL="https://api.evolink.ai/v1/messages"

# --- Security: Path validation for local files ---
validate_file() {
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
ESCAPED_USER=$(json_escape "$USER_MSG")

# --- Call Evolink API ---
RESPONSE=$(curl -s "$API_URL" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d "{
Confidence
97% confidence
Finding
This curl call transmits user-provided content, potentially including local file contents, to an external API. Even though the destination is hardcoded and HTTPS is used, the security issue is data exfiltration/privacy leakage rather than command injection, and the file-reading behavior makes the impact materially relevant.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script sends the full supplied content to a third-party API, but it does not present a clear user-facing warning or confirmation that local file contents will leave the system. In this context, the risk is real because the tool explicitly accepts file paths and reads file contents, so users may inadvertently transmit sensitive workspace data to an external service.

Static analysis

No suspicious patterns detected.