Back to skill

Security audit

URL to Markdown - Web Page Extract API

Security checks for vulnerabilities and agentic risk

Overview

This skill is a clearly disclosed URL extraction helper that sends requested public web pages to Scavio, with no hidden persistence or local execution.

Install this only if you are comfortable sending target URLs and extracted page content to Scavio. Avoid using it for private documents, signed URLs, internal systems, confidential knowledge bases, or pages whose URL alone is sensitive.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (5)

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This example sends a user-supplied URL and the caller's API bearer token to an external third-party service. Even though this is the documented purpose of the skill, it creates a real data-transfer boundary: any sensitive, internal, or user-private URL provided through the skill is disclosed to Scavio and fetched server-side, which can expose confidential targets or content metadata.

Content

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

md
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1. The common case: a page as clean Markdown, 1 credit
page = requests.post(f"{BASE}/api/v1/extract", headers=HEADERS,
    json={"url": "https://example.com/pricing"}).json()

print(page["data"]["content"][:500], page["data"]["content_length"])

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This call transmits a requested URL to an external API for conversion into plain text, which is a genuine exfiltration path for user-provided targets and any resulting extracted content. In an agent setting, this becomes more sensitive because the tool may be invoked on links containing private documents, signed URLs, or internal knowledge-base locations without sufficient review.

Content

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

md
print(page["data"]["content"][:500], page["data"]["content_length"])

# 2. Plain text for an embedding pipeline, still 1 credit
plain = requests.post(f"{BASE}/api/v1/extract", headers=HEADERS,
    json={"url": "https://example.com/blog/post", "format": "text"}).json()

# 3. A client-rendered page: advanced renders JavaScript and STILL costs 1 credit

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The advanced mode example sends the target URL to an external service that may render JavaScript remotely, increasing the amount of third-party interaction with the destination page. While not overtly malicious, this broadens exposure because the agent can cause remote rendering of arbitrary user-requested pages and disclose browsing targets plus authentication-free page content to the provider.

Content

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

md
json={"url": "https://example.com/blog/post", "format": "text"}).json()

# 3. A client-rendered page: advanced renders JavaScript and STILL costs 1 credit
spa = requests.post(f"{BASE}/api/v1/extract", headers=HEADERS,
    json={"url": "https://example.com/app/docs", "mode": "advanced"}).json()

# 4. Raw HTML to parse yourself

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

Requesting raw HTML from an external extraction API can transmit and retrieve more data than cleaned text, including embedded tokens in markup, hidden fields, or sensitive page structure. In skill context this is more dangerous than markdown extraction because it encourages shipping entire pages to a third-party service for downstream parsing.

Content

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

json={"url": "https://example.com/app/docs", "mode": "advanced"}).json()

4. Raw HTML to parse yourself

raw = requests.post(f"{BASE}/api/v1/extract", headers=HEADERS, json={"url": "https://example.com", "format": "html"}).json()

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The retry/escalation helper operationalizes repeated outbound transmission of arbitrary URLs to a third-party API, potentially across multiple rendering tiers. Although the skill notes some server-side protections, the pattern still creates a real confidentiality and governance risk because agents may automatically forward sensitive user-specified URLs and content off-platform with little friction.

Content

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

md
def read(url, format="markdown"):
    """normal (1cr) -> advanced (1cr) -> ultra (2cr). Only the successful call is billed."""
    for mode in ("normal", "advanced", "ultra"):
        r = requests.post(f"{BASE}/api/v1/extract", headers=HEADERS,
                          json={"url": url, "format": format, "mode": mode})
        if r.status_code == 200:
            data = r.json()["data"]