Back to skill

Security audit

Sitemap Content Scraper

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-built for public sitemap scraping, but its network safeguards and resource limits are weak enough to warrant review before installation.

Install only if you are comfortable giving the skill outbound web access and permission to write a scraped corpus locally. Use it with trusted public sites, set an explicit small --limit and narrow include filters, choose an output folder inside the workspace, and avoid running it where internal services or cloud metadata endpoints are reachable until the DNS rebinding and resource-limit issues are fixed.

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

Error
Location
scripts/scrape_sitemap.py:53
Finding

DNS Rebinding Can Bypass Public-Only URL Validation

Content
View full analysis
tuple[bool, str | None]: normalized = hostname.strip().strip(".").lower() if not normalized: return False, "empty hostname" if normalized in {"localhost"}: return False, "localhost is not allowed" if normalized.endswith((".local", ".localhost", ".internal", ".home.arpa")): return False, "internal-only hostname suffix is not allowed" try: ip = ipaddress.ip_address(normalized) except ValueError: pass else: if not ip.is_global: return False, f"non-public IP {ip} is not allowed" return True, None try: addrinfo = socket.getaddrinfo(normalized, None, proto=socket.IPPROTO_TCP) except socket.gaierror as exc: return False, f"hostname resolution failed: {exc}" resolved_ips: set[ipaddress.IPv4Address | ipaddress.IPv6Address] = set() for info in addrinfo: addr = info[4][0] try: resolved_ips.add(ipaddress.ip_address(addr)) except ValueError: continue if not resolved_ips: return False, "hostname did not resolve to usable IP addresses" for ip in resolved_ips: if not ip.is_global: return False, f"hostname resolves to non-public address {ip}" return True, None ``` The scraper subsequently opens the URL without pinning the previously validated IP address: ```python def fetch_text(url: str, timeout: float, user_agent: str) -> tuple[str | Non ...[truncated 5131 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scrape_sitemap.py:125
Finding

Unbounded Remote Responses and Recursive Sitemap Processing Can Exhaust Resources

Content
View full analysis
list[str]: sitemap_url = normalize_http_url(sitemap_url, field_name="sitemap-url") seen_sitemaps = seen_sitemaps or set() if sitemap_url in seen_sitemaps: return [] seen_sitemaps.add(sitemap_url) xml_text, error = fetch_text(sitemap_url, timeout=timeout, user_agent=user_agent) if xml_text is None: raise RuntimeError(f"could not fetch sitemap {sitemap_url}: {error}") tag, locs = parse_sitemap_urls(xml_text) if tag == "sitemapindex": urls: list[str] = [] for child_url in locs: resolved_child_url = urllib.parse.urljoin(sitemap_url, child_url) urls.extend( gather_urls_from_sitemap( resolved_child_url, timeout=timeout, user_agent=user_agent, seen_sitemaps=seen_sitemaps, ) ) return urls if tag == "urlset": return [urllib.parse.urljoin( ...[truncated 3265 chars]
Remediation
View remediation
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code accurately implements the scraping/output portion of the description: it fetches a supplied sitemap, follows sitemap indexes, filters URLs, scrapes public pages, writes Markdown files, and emits a manifest. However, the declared purpose also claims sitemap discovery from robots.txt and common locations and selection of the right sitemap or content family. None of those discovery/selection behaviors are present in this code chunk. Instead, it only operates after a sitemap has already been chosen and passed via --sitemap-url. So this chunk is materially narrower than the declared end-to-end description, making the description inaccurate for the supplied code chunk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill performs network access and writes scraped content to local storage, but it does not declare any explicit tool scope such as permissions or allowed-tools. That weakens policy enforcement and reviewability, making it easier for an agent runtime to execute broader actions than intended or for future edits to expand behavior without clear constraints.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.