T09 · Insecure Skill Coding Practices
- Location
SKILL.md:42- Finding
Potential Disclosure of Sensitive URL Data to a Third-Party Extraction Service
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill coherently documents a Scavio URL-extraction workflow, but users should avoid sending private or token-bearing links to the service.
Install/use this skill only if you are comfortable sending target URLs and fetched page contents to Scavio. Do not use it on password-reset links, signed downloads, private document links, URLs with tokens or personal data in query parameters, or authenticated/internal pages unless you explicitly intend that disclosure. Prefer the direct HTTPS examples or an isolated environment if you do not need the SDKs.
SKILL.md:42Potential Disclosure of Sensitive URL Data to a Third-Party Extraction Service
SKILL.md:186Unverifiable Third-Party SDK Installation Instructions
The skill does not clearly warn users that submitted URLs are fetched server-side by an external provider, which can leak confidential links, signed URLs, document locations, or embedded secrets in query strings. In an agent setting, lack of disclosure increases the risk of silent third-party data transmission.
The trigger guidance is broad enough that an agent may invoke this skill whenever a user pastes a link or asks about page contents, without first confirming that sending the URL to a third-party service is intended. That can cause unintended disclosure of sensitive URLs, internal document links, or private query parameters to Scavio.
This code sends user-supplied URLs to an external API, which is a real data egress path. Even though external fetching is the core purpose of the skill, it becomes dangerous if agents pass along sensitive URLs or content without explicit user awareness and consent.
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"])
This example again demonstrates transmission of a target URL to Scavio, here for embedding/text extraction use cases that may encourage bulk ingestion of external content. The security issue is the same: unreviewed URLs may disclose sensitive resources or proprietary content to a third party.
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
The advanced mode still transmits the user-provided URL externally and may fetch more complex pages, which can include authenticated app frontends or sensitive documentation endpoints. In an agent workflow, that increases the chance of sending unintended targets to a third party if invocation is too automatic.
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
Requesting raw HTML from an external service can expose the full page source of the target URL to that service, including embedded metadata, scripts, and possibly sensitive in-page information. Compared with cleaned markdown/text extraction, raw HTML increases the volume and sensitivity of transmitted content.
json={"url": "https://example.com/app/docs", "mode": "advanced"}).json()
raw = requests.post(f"{BASE}/api/v1/extract", headers=HEADERS, json={"url": "https://example.com", "format": "html"}).json()
The retry/escalation function automates repeated external requests for the same user-supplied URL, increasing the likelihood of transmitting sensitive links without deliberate review. While failures are not billed, automatic escalation expands third-party exposure and may make overbroad invocation more harmful.
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"]
Detected: suspicious.exposed_secret_literal