Back to skill

Security audit

issuu_downloader

Security checks for vulnerabilities and agentic risk

Overview

This Issuu downloader appears purpose-built, but it needs review because it automatically probes local proxies and can fetch arbitrary URLs from the agent's network.

Install only if you are comfortable with the skill making outbound web requests, testing local proxy ports, and saving a PDF locally. Prefer running it in a network-restricted environment, provide only legitimate Issuu URLs, avoid relying on automatic proxy detection, and review or pin dependencies before production use.

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
main.py:40
Finding

Unrestricted User-Controlled URL Fetch Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: main.py, lines 40-45
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: Medium

python
def get_document_info(self, url: str) -> Optional[Dict]:
    try:
        # Adding a small sleep to look more "human"
        time.sleep(1)
        response = self.session.get(url, timeout=30)
        response.raise_for_status()
        html = response.text

Technical Analysis

The skill describes url as an Issuu document URL, but the implementation passes the caller-controlled value directly to requests.Session.get() without validating its scheme, hostname, resolved IP address, or destination network.

The requests library follows redirects by default. Consequently, an attacker may provide either a direct URL to an internal service or a public URL that redirects to a loopback, private, or link-local destination. The request is made from the environment running the skill and therefore inherits that environment's network reachability.

The response body is not returned directly to the caller. The implementation instead searches it for an Issuu document identifier and returns a generic error when no identifier is found. This limits direct data disclosure, but does not eliminate SSRF: requests can still reach internal services, activate state-changing GET endpoints, and expose limited status or timing information through execution behavior and printed exceptions.

Attack Path

  1. An attacker invokes the skill with a URL targeting an otherwise inaccessible service, such as a loopback or private-network HTTP endpoint. Alternatively, the attacker supplies a public URL that redirects to such an endpoint.
  2. run_skill() passes the URL to IssuuDownloader.download(), which passes it to get_document_info().
  3. get_document_info() calls self.session.get(url, timeout=30) without destination validation.
  4. The Agent host sends the request using its own network privileges and routing conte ...[truncated 1166 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse the supplied URL with urllib.parse.urlsplit() and reject malformed values, embedded credentials, unexpected ports, and non-HTTPS schemes.
  2. Enforce an explicit hostname allowlist containing only the Issuu domains required by the workflow, such as issuu.com and specifically approved subdomains. Use exact hostname or properly bounded suffix comparisons rather than substring matching.
  3. Resolve the hostname before connecting and reject every resolved IPv4 and IPv6 address that is loopback, private, link-local, multicast, reserved, unspecified, or otherwise non-global.
  4. Disable automatic redirects with allow_redirects=False, or validate the scheme, hostname, port, and resolved addresses of every redirect target before following it.
  5. Protect against DNS rebinding by ensuring the validated address is the address used for the connection, or enforce destination restrictions through a controlled outbound proxy or firewall.
  6. Apply egress filtering that prevents the skill from reaching loopback, private, link-local, metadata, and internal management networks.
  7. Return a clear validation error when the input is not an approved Issuu URL rather than attempting the request.
  8. Add automated tests covering direct private addresses, IPv6 loopback, alternative numeric IP representations, user-info URL tricks, attacker-controlled redirects, and DNS rebinding scenarios.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (10)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly promotes anti-blocking behavior, VPN/proxy use, and automatic probing/detection of local proxies without clearly warning users that their traffic may be rerouted through third-party infrastructure or that local proxy discovery can expose privacy-sensitive network configuration. In this context, the combination of download automation, evasion language, and proxy guidance increases the chance of user privacy harm, policy circumvention, and unsafe network behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code does more than passive local proxy detection: it actively sends outbound requests to https://www.google.com through candidate localhost proxy ports without explicit user consent. This creates undisclosed network activity, can leak that the tool is being used, and may route traffic through a locally running proxy service the user did not intend this skill to use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill automatically probes common localhost proxy ports and performs external connectivity tests without clear disclosure or user approval. In this context, that is more dangerous because the skill is a downloader that may silently alter network routing, interact with local security/privacy tools, and generate unexpected outbound traffic.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The comment characterizes the delay as making the client appear human, while the surrounding logic is fully automated retrieval and probing of remote content. This is an intent-level mismatch in the documentation because it presents deception-oriented behavior as benign pacing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This code creates an output directory and writes a downloaded PDF to a fixed path, but there is no docstring or comment disclosing the file-write behavior to the user. The operation is user-impacting because it persists data on disk, and the function does not provide any warning beyond returning the path afterward.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with a lower bound only (requests>=2.31.0), which allows future unreviewed versions to be installed and makes builds non-reproducible. This increases supply-chain risk and complicates determining whether a vulnerable or breaking release may be pulled in during installation.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0
img2pdf>=0.5.1
urllib3>=2.0.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

requests has known advisories, and because the manifest does not pin an exact version, it is impossible to verify from this file alone whether the installed release is affected. This uncertainty is dangerous because vulnerable versions may be resolved in some environments, especially when builds are not reproducible.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

img2pdf>=0.5.1 is unpinned, so installs may resolve to different versions over time without review. That creates a supply-chain and reproducibility weakness because a newly published vulnerable or malicious version could be consumed automatically.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
requests>=2.31.0
img2pdf>=0.5.1
urllib3>=2.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

urllib3>=2.0.0 permits any later version, preventing deterministic builds and allowing unnoticed adoption of vulnerable or incompatible releases. In network-facing libraries like urllib3, that uncertainty is especially undesirable because security fixes and regressions frequently matter to transport behavior.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
requests>=2.31.0
img2pdf>=0.5.1
urllib3>=2.0.0

Unverifiable Dependency: urllib3 has 16 known advisory(ies) (CVE-2025-66471 (urllib3 streaming API improperly handles highly compressed data); CVE-2024-37891 (urllib3's Proxy-Authorization request header isn't stripped during cross-origin ); CVE-2026-21441 (Decompression-bomb safeguards bypassed when following HTTP redirects (streaming ) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

urllib3 also has known advisories, but the unpinned requirement prevents verification of whether deployments receive a safe release. For a core HTTP client library, unresolved version ambiguity can expose consumers to request-handling, redirect, proxy, or decompression-related flaws if an affected version is installed.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.