Back to skill

Security audit

proxy-web-fetch

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward web-page fetch helper that uses a configured OpenClaw Manager proxy, with normal proxy privacy considerations but no hidden or destructive behavior found.

Install only if you trust the configured OpenClaw Manager Web Fetch Proxy. Do not use it for secret-bearing, internal, regulated, or credential-token URLs unless that proxy is approved for that data. Treat the included shell wrapper as a convenience tool with weak input validation, and prefer normal, trusted inputs for timeout and format options.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/proxy_fetch.sh:24
Finding

Unsafe JSON Construction from Unvalidated Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/proxy_fetch.sh:24-26, 63-84
Vulnerability Type: JSON injection and insufficient input validation
Risk Level: Medium

Vulnerable Code

bash
while [[ "$#" -gt 0 ]]; do
    case $1 in
        -u|--url) URL="$2"; shift ;;
        -t|--timeout) TIMEOUT="$2"; shift ;;
        -f|--format) RETURN_FORMAT="$2"; shift ;;
        --no-cache) NO_CACHE="true" ;;
        --no-images) RETAIN_IMAGES="false" ;;
        --no-gfm) NO_GFM="true" ;;
        --keep-img-data-url) KEEP_IMG_DATA_URL="true" ;;
        --images-summary) WITH_IMAGES_SUMMARY="true" ;;
        --links-summary) WITH_LINKS_SUMMARY="true" ;;
bash
# Escape special characters in URL for safe JSON encoding
SAFE_URL="${URL//\\/\\\\}"
SAFE_URL="${SAFE_URL//\"/\\\"}"

# Build JSON payload
PAYLOAD=$(cat <<EOF
{
  "url": "$SAFE_URL",
  "timeout": $TIMEOUT,
  "no_cache": $NO_CACHE,
  "return_format": "$RETURN_FORMAT",
  "retain_images": $RETAIN_IMAGES,
  "no_gfm": $NO_GFM,
  "keep_img_data_url": $KEEP_IMG_DATA_URL,
  "with_images_summary": $WITH_IMAGES_SUMMARY,
  "with_links_summary": $WITH_LINKS_SUMMARY
}
EOF
)

Technical Analysis

The script creates a JSON request through direct shell-string interpolation rather than using a JSON serializer. The TIMEOUT argument is inserted as an unquoted JSON value, and RETURN_FORMAT is inserted into a quoted JSON string without JSON escaping. Consequently, a caller that controls these command-line arguments can introduce JSON delimiters, quotes, or additional properties into the payload.

The URL escaping is also incomplete for general JSON encoding. It handles backslashes and quotation marks but does not correctly encode control characters such as newlines and carriage returns. Such input can produce invalid JSON.

Options that require values access $2 without first verifying that a value exists. This can ...[truncated 2006 chars]

Remediation
View remediation

Remediation Suggestions

  1. Construct the payload with a real JSON encoder such as jq instead of a heredoc:

    bash
    PAYLOAD=$(jq -n \
      --arg url "$URL" \
      --argjson timeout "$TIMEOUT" \
      --arg return_format "$RETURN_FORMAT" \
      --argjson no_cache "$NO_CACHE" \
      --argjson retain_images "$RETAIN_IMAGES" \
      --argjson no_gfm "$NO_GFM" \
      --argjson keep_img_data_url "$KEEP_IMG_DATA_URL" \
      --argjson with_images_summary "$WITH_IMAGES_SUMMARY" \
      --argjson with_links_summary "$WITH_LINKS_SUMMARY" \
      '{
        url: $url,
        timeout: $timeout,
        no_cache: $no_cache,
        return_format: $return_format,
        retain_images: $retain_images,
        no_gfm: $no_gfm,
        keep_img_data_url: $keep_img_data_url,
        with_images_summary: $with_images_summary,
        with_links_summary: $with_links_summary
      }')
    
  2. Validate timeout as a bounded positive integer before JSON construction:

    bash
    if ! [[ "$TIMEOUT" =~ ^[0-9]+$ ]] || (( TIMEOUT < 1 || TIMEOUT > 300 )); then
        echo "Error: timeout must be an integer between 1 and 300" >&2
        exit 1
    fi
    
  3. Restrict the output format to its documented allowlist:

    bash
    case "$RETURN_FORMAT" in
        markdown|text) ;;
        *)
            echo "Error: format must be markdown or text" >&2
            exit 1
            ;;
    esac
    
  4. Before reading $2, verify that each value-taking option has a following argument and that it is not another option.

  5. Validate the final payload with the chosen JSON encoder before sending it. Consider making curl fail explicitly on HTTP errors by using --fail-with-body, while retaining appropriate error reporting.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exposes shell-based execution examples and depends on curl, but it does not declare an explicit tool scope such as permissions or allowed-tools. That creates an authorization gap where the runtime may permit broader shell usage than users or platform policy expect, increasing the chance of unintended command execution paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill description says requests are routed through a manager proxy, but it does not clearly warn users that requested URLs and fetched page contents are transmitted to an external service. This can cause inadvertent disclosure of sensitive URLs, tokens embedded in URLs, or confidential page contents when users believe the fetch is local or first-party.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The skill explicitly sends user-supplied URLs to ${WEB_FETCH_PROXY_URL} and returns fetched page content through that service, which is a real external data transmission path. In this context the transmission is the intended function, but it still carries security and privacy risk because the proxy can observe requested targets and response data, and may be able to reach internal resources depending on proxy configuration.

Content

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

Quick Start

Basic cURL Usage

bash
curl --request POST \

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/proxy_fetch.sh (reported line 87)May include surrounding context.

sh
EOF
)

# Execute cURL request to Web Fetch Proxy (no auth needed)
curl -s --request POST \
  --url "${PROXY_URL}/" \
  --header "Content-Type: application/json" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code performs an HTTP POST to an externally configured proxy, transmitting the requested URL and associated options in the JSON payload. Although the script name and comments indicate proxy fetching, there is no runtime disclosure, prompt, or explicit warning that user-provided input will be sent over the network to the proxy endpoint.

Content

No source excerpt is available for this finding.