Back to skill

Security audit

Ad-Ready Pro

Security checks for vulnerabilities and agentic risk

Overview

This ad-generation skill is coherent, but it needs review because it can fetch arbitrary product or image URLs and upload retrieved assets to ComfyDeploy without clear network-scope safeguards.

Review before installing or running this skill on sensitive products, internal URLs, private staging sites, unreleased brand assets, or confidential reference images. Use manually selected public assets where possible, avoid auto-fetch for untrusted URLs, and prefer running it in an environment with restricted outbound network access and a locked dependency set.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate.py:148
Finding
Unrestricted Product and Image URL Fetching Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate.py:148-198` **Vulnerability Type**: Server-Side Request Forgery (SSRF) through unrestricted URL fetching **Risk Level**: High ### Vulnerable Code ```python def fetch_product_image(client: httpx.Client, product_url: str, dest: Path) -> bool: """Try to find and download the main product image from a product page.""" try: from bs4 import BeautifulSoup except ImportError: print(" ⚠ beautifulsoup4 not available for product image extraction", flush=True) return False print(" Fetching product page for main image...", flush=True) try: headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Accept": "text/html,*/*", } response = client.get(product_url, headers=headers, follow_redirects=True, timeout=20.0) if response.status_code != 200: print(f" ✗ Could not fetch product page ({response.status_code})", flush=True) return False soup = BeautifulSoup(response.text, "html.parser") # Strategy 1: og:image meta tag (most reliable) og_img = soup.find("meta", property="og:image") if og_img and og_img.get("content"): img_url = urljoin(product_url, og_img["content"]) print(f" Found og:image: {img_url[:80]}...", flush=True) if download_to_file(client, img_url, dest): return True # Strategy 2: Large images in the page images = soup.find_all("img") candidates = [] for img in images: src = img.get("src") or img.get("data-src") or img.get("data-lazy-src") if not src: continue src = urljoin(product_url, src) # Skip tiny images, icons, tracking pixels width = img.get("width", "0") height = img.get("height", "0") try: w = in ...[truncated 3826 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Allow only `https` URLs unless plain HTTP is explicitly required and justified. 2. Reject URLs containing embedded credentials, malformed hostnames, unexpected ports, or non-HTTP schemes. 3. Resolve the hostname before connecting and reject all loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges. 4. Explicitly block common cloud metadata destinations, including link-local metadata addresses. 5. Disable automatic redirects or validate the scheme, hostname, port, and resolved address of every redirect target before following it. 6. Protect against DNS rebinding by ensuring that the address actually used for the connection is an approved public address. 7. Apply the same validation to `product_url`, `og:image`, every `img` source, and any user-provided remote image URL. 8. Use an outbound proxy or network sandbox that permits access only to public Internet destinations and the documented ComfyDeploy API. 9. Enforce a strict maximum response size while streaming rather than loading an unbounded response into memory. 10. Verify image content using file signatures and an image decoder instead of trusting the `Content-Type` header or response length. 11. Require explicit user confirmation before uploading automatically fetched content to ComfyDeploy. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/generate.py:3
Finding
Unpinned Runtime Dependencies Permit Unreviewed Supply-Chain Changes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate.py:3-7` **Vulnerability Type**: Incompletely pinned third-party runtime dependencies **Risk Level**: Medium ### Vulnerable Code ```python # /// script # requires-python = ">=3.10" # dependencies = [ # "httpx>=0.25.0", # "beautifulsoup4>=4.12.0", # ] # /// ``` ### Technical Analysis The inline dependency declarations specify only minimum versions. They allow `uv run` to resolve and execute future compatible releases of `httpx`, `beautifulsoup4`, and their transitive dependencies. The audited project contains no lockfile or integrity hashes. Consequently, two executions of the same reviewed Skill can install different dependency code without any corresponding change to the Skill package. This weakens reproducibility and allows dependency updates to bypass the Skill's code-review boundary. The declarations do not demonstrate that the current packages are malicious. The risk arises because a future compromised package release, compromised transitive dependency, or otherwise unsafe update could be selected automatically and execute within the Skill process. ### Attack Path 1. A direct or transitive dependency publishes a compromised or malicious release that satisfies the declared minimum-version constraint. 2. The Skill is executed in an environment that does not already have a locked dependency set. 3. `uv run` resolves the newer, unreviewed release. 4. Package installation, import initialization, or invoked library functionality executes attacker-controlled code in the Skill process. 5. That code inherits access to the process environment, network connectivity, user-selected files, and the ComfyDeploy API key available to the process. ### Impact Assessment A compromised dependency would execute with the same operating-system privileges as the Skill. Depending on the execution environment, it could potentially: - Read environment variables, including `COMFY_DEPLOY_API_KEY`. ...[truncated 370 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact reviewed version rather than using minimum-version constraints. 2. Generate and commit a `uv.lock` file covering direct and transitive dependencies. 3. Run the Skill in locked or frozen mode so execution fails rather than silently changing the dependency graph. 4. Require package hashes or equivalent integrity verification where supported. 5. Review dependency updates before modifying the lockfile. 6. Use automated vulnerability and provenance scanning for both direct and transitive packages. 7. Install dependencies from a trusted, explicitly configured package index. 8. Run the Skill in a restricted environment with minimal filesystem access, sanitized environment variables, and constrained outbound network access to reduce the impact of a supply-chain compromise. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill clearly instructs the agent to use network access, environment variables, and file writes, but it does not declare any tool scope or permission boundaries. That omission increases the chance of over-privileged execution and makes it harder to enforce least privilege or audit what the skill is allowed to do.

Vague Triggers

Medium
Confidence
91% confidence
Finding
This invocation guidance is broad enough to match many ordinary requests involving product URLs and ad creation, but it does not define boundaries for when this skill should or should not be used versus alternatives. The file also does not provide negative examples or a narrowly scoped trigger context to reduce unintended activation.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill describes automatically downloading images from third-party sites and uploading them to ComfyDeploy, but it does not clearly require user consent or warn about external data transfer. This can expose proprietary product assets, internal URLs, or user-supplied images to external services without informed approval.

External Transmission

Medium
Category
Data Exfiltration
Content
## API Details

**Endpoint:** `https://api.comfydeploy.com/api/run/deployment/queue`
**Deployment ID:** `e37318e6-ef21-4aab-bc90-8fb29624cd15`

## ComfyDeploy Input Variables
Confidence
88% confidence
Finding
Transmission to an external API is expected for this skill, but it is still a real security concern because the skill sends user-derived content and downloaded assets to a third-party endpoint. In context this is less suspicious than covert exfiltration, yet it remains dangerous if users are not informed, if sensitive inputs are accepted, or if endpoint access is broader than necessary.

External Transmission

Medium
Category
Data Exfiltration
Content
sys.stderr.reconfigure(line_buffering=True)

DEPLOYMENT_ID = "e37318e6-ef21-4aab-bc90-8fb29624cd15"
API_BASE = "https://api.comfydeploy.com/api"

# Dynamic brand profiles from catalog
BRANDS_DIR = Path.home() / "clawd" / "ad-ready" / "configs" / "Brands"
Confidence
85% confidence
Finding
The script transmits user-supplied product URLs and optional image assets to external services, including ComfyDeploy and logo/image sources. In this skill context that behavior is expected, but it still creates a real data-exfiltration boundary: sensitive or internal URLs, local files, and brand assets may be uploaded or fetched over the network without restriction, and auto-fetch can be abused to probe internal resources if untrusted URLs are accepted.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The script uses Spanish variable names and API input keys such as "producto", "referencia", and "marca", which surface in the skill’s behavior and can encode a fixed locale convention. There is no indication that users can choose language or that this locale constraint is documented as intentional or region-specific.

Static analysis

No suspicious patterns detected.