Back to skill

Security audit

Web Content Fetcher

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it can send full URLs and fetched page content to third-party fetch services without clear consent or safeguards.

Review before installing. Do not use this skill with private, authenticated, internal, signed, token-bearing, or otherwise sensitive URLs unless you are comfortable disclosing them and the fetched content to the named third-party services. Prefer explicit user confirmation and a single chosen provider rather than automatic fallback or all-provider mode.

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

T09 · Insecure Skill Coding Practices

Warning
Location
fetch.sh:6
Finding

Unvalidated URLs Are Disclosed to External Content Services in the Shell Implementation

Content
View full analysis
[method]" echo "Methods: jina (default), markdown, defuddle" exit 1 fi ENCODED_URL="$URL" echo "=== Attempting to fetch: $URL ===" >&2 echo "Method: $METHOD" >&2 case "$METHOD" in jina) echo "--- Using r.jina.ai ---" >&2 curl -s "https://r.jina.ai/$ENCODED_URL" ;; markdown) echo "--- Using markdown.new ---" >&2 curl -s "https://markdown.new/$ENCODED_URL" ;; defuddle) echo "--- Using defuddle.md ---" >&2 curl -s "https://defuddle.md/$ENCODED_URL" ;; all) echo "=== Trying all methods ===" >&2 echo "--- r.jina.ai ---" >&2 curl -s "https://r.jina.ai/$ENCODED_URL" echo -e "\n--- markdown.new ---" >&2 curl -s "https://markdown.new/$ENCODED_URL" echo -e "\n--- defuddle.md ---" >&2 curl -s "https://defuddle.md/$ENCODED_URL" ;; ``` ### Technical Analysis The script embeds the complete user-supplied URL into a request sent to `r.jina.ai`, `markdown.new`, or `defuddle.md`. It does not validate the URL scheme, reject embedded credentials, remove sensitive query parameters, or obtain explicit confirmation before disclosing the value. URLs commonly contain signed query strings, password-reset tokens, API credentials, session identifiers, private document identifiers, and internal hostnames. The selected external provider can observe and potentially log the complete target URL. The `all` method expands the disclosure to all three providers. The quoted shell variable prevents ordinary shell command injection through the URL. The confirmed issue is third-party data disclosure rather than arbitrary local command execution. ### Attack Path ...[truncated 825 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
fetch_content.py:15
Finding

Unvalidated URLs Are Disclosed to External Content Services in the Python Implementation

Content
View full analysis
Tuple[bool, str]: """Fetch webpage content using the selected service.""" if method not in SERVICES: return False, f"Unknown service: {method}" service_url = SERVICES[method]["url"].format(url=url) try: result = subprocess.run( ["curl", "-s", service_url], capture_output=True, text=True, timeout=30 ) ``` ### Technical Analysis The Python implementation interpolates the complete input URL into an external service URL. No validation, normalization, secret detection, query-string redaction, or consent check occurs before transmission. Although `subprocess.run` uses an argument list and therefore does not invoke a shell, this only prevents shell metacharacter injection. It does not prevent confidential URL components from being disclosed to the external provider. Selecting `all` causes the URL to be sent to each configured provider. ### Attack Path 1. An attacker provides a URL containing a signed query string, access token, private resource identifier, or internal hostname. 2. The URL is passed to `fetch_content.py`. 3. `fetch_with_service` interpolates the full value into `service_url`. 4. `curl` sends the resulting request to the selected third-party service. 5. The provider receives the complete ...[truncated 478 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
fetch_content.py:37
Finding

Unbounded Response Buffering Can Cause Memory Exhaustion

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill directs users to send target URLs to third-party services (r.jina.ai, markdown.new, defuddle.md) but does not warn that both the requested URL and the retrieved page contents may be disclosed to those external providers. This can expose sensitive URLs, internal resources, tokens in query strings, or confidential content, and the 'bypass cloudflare' context makes the privacy and compliance risk more acute.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs use of shell commands such as curl and references a local script, but it does not declare any tool scope or allowed-tools boundaries. This creates an authorization and review gap: an agent may invoke shell/network capabilities implicitly, making misuse or unexpected external requests harder to constrain and audit.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger phrases are very broad and include common requests like fetching webpage content, which increases the chance the skill activates in routine situations without the user understanding that third-party bypass/fetch services will be used. Because the skill is specifically positioned for filtered or Cloudflare-protected sites, overbroad triggering can route ordinary browsing requests through external intermediaries unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script forwards a user-supplied URL to external proxy-like services (r.jina.ai, markdown.new, defuddle.md) without any warning, consent prompt, or documentation that the target URL will be disclosed to third parties. This can leak sensitive internal URLs, private query strings, presigned links, or confidential browsing targets, and the skill context explicitly encourages bypassing normal access controls, which increases the chance of sensitive use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The tool forwards user-supplied URLs to third-party services (r.jina.ai, markdown.new, defuddle.md) specifically to bypass normal access filtering such as Cloudflare. That can leak sensitive URLs, query strings, tokens, internal endpoints, or browsing intent to external operators, and the skill description makes the behavior more concerning because it is explicitly designed to route around site protections rather than fetch directly.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · fetch_content.py (reported line 39)May include surrounding context.

python
service_url = SERVICES[method]["url"].format(url=url)
    
    try:
        result = subprocess.run(
            ["curl", "-s", service_url],
            capture_output=True,
            text=True,

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script's comments and runtime usage/output strings are written in Chinese, which imposes a specific language on users without any opt-in or documented locale constraint. This can violate language/locale policy when a skill does not provide a choice or justify the restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

SQP-3 applies to all file types and includes language or locale policy violations. The natural-language strings in the module description and CLI help are Chinese-only, which can impose a fixed language on users without opt-in or justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.