T09 · Insecure Skill Coding Practices
- Location
SKILL.md:692- Finding
Bright Data API Key Disclosed Through Terminal Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent Bright Data scraper-building guide, but it broadly steers agents to send arbitrary sites, APIs, and scraped content through a third-party service without enough scoping or safety checks.
Install only if you intend to use Bright Data for authorized scraping and are comfortable sending target URLs, request metadata, and fetched page content to that provider. Use scoped API keys, do not print secrets, avoid private/internal/authenticated or regulated pages unless approved, and review generated scrapers before letting them run bulk jobs.
SKILL.md:692Bright Data API Key Disclosed Through Terminal Output
references/pagination-patterns.md:279JavaScript Injection Through Unescaped CSS Selector Interpolation
The skill’s trigger phrases are unusually broad and can activate on common requests like 'get data from [website]' or 'pull data from', causing the skill to engage in many contexts beyond explicit scraper-building. That increases the chance of unintended delegation to a scraping workflow that encourages third-party data extraction and external requests without clear user intent or scope validation.
The instruction to query the live Dataset List API causes authenticated outbound communication to a third-party service and can reveal usage intent and environment configuration. While less severe than content scraping, it still expands the skill’s external dependency surface and normalizes automatic third-party lookups without a consent checkpoint.
curl -H "Authorization: Bearer $BRIGHTDATA_API_KEY" \
https://api.brightdata.com/datasets/list
This returns every available scraper with its dataset_id and name. Search the results for the target domain. You can also browse the full documentation index at https://docs.brightdata.com/llms.txt to discover scraper-specific docs and supported parameters.
The embedded request includes bearer-authenticated transmission to an external scraping provider, which creates a clear trust-boundary crossing. Even though the API key itself is only used as an auth header, the surrounding pattern still enables external processing of arbitrary user-specified targets and returned content.
API_KEY = os.environ["BRIGHTDATA_API_KEY"]
ZONE = os.environ["BRIGHTDATA_UNLOCKER_ZONE"]
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
The embedded request includes bearer-authenticated transmission to an external scraping provider, which creates a clear trust-boundary crossing. Even though the API key itself is only used as an auth header, the surrounding pattern still enables external processing of arbitrary user-specified targets and returned content.
API_KEY = os.environ["BRIGHTDATA_API_KEY"]
ZONE = os.environ["BRIGHTDATA_UNLOCKER_ZONE"]
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
This request transmits the target URL and zone information to Bright Data, creating a third-party data path for every scrape target. In a tool advertised for 'any website,' the lack of destination restrictions or consent language makes the external transmission more risky.
ZONE = os.environ["BRIGHTDATA_UNLOCKER_ZONE"]
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"zone": ZONE,
This helper demonstrates a standard external fetch pattern but lacks any visible controls over what destinations may be sent to the third-party service. In context, the skill’s broad mandate to scrape 'any website' makes that omission more dangerous than it would be in a tightly scoped integration.
def fetch_page(url: str) -> str:
"""Fetch a page through Bright Data Web Unlocker."""
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"}
This helper demonstrates a standard external fetch pattern but lacks any visible controls over what destinations may be sent to the third-party service. In context, the skill’s broad mandate to scrape 'any website' makes that omission more dangerous than it would be in a tightly scoped integration.
def fetch_page(url: str) -> str:
"""Fetch a page through Bright Data Web Unlocker."""
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"}
The code sample shows a reusable mechanism for sending arbitrary user-selected URLs to an external provider for retrieval. That is inherently sensitive because the user may supply confidential, internal, or regulated resources, and the skill does not include trust-boundary enforcement.
def fetch_page(url: str) -> str:
"""Fetch a page through Bright Data Web Unlocker."""
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"}
)
Direct external fetching of API URLs is a meaningful security concern because it lowers the barrier to harvesting structured data from internal or semi-public endpoints. Combined with the skill’s advice to probe for 'hidden APIs,' the pattern can support unauthorized or excessive data extraction beyond ordinary page scraping.
def fetch_api(api_url: str) -> dict:
"""Fetch a JSON API endpoint through Web Unlocker."""
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": api_url, "format": "raw"}
Direct external fetching of API URLs is a meaningful security concern because it lowers the barrier to harvesting structured data from internal or semi-public endpoints. Combined with the skill’s advice to probe for 'hidden APIs,' the pattern can support unauthorized or excessive data extraction beyond ordinary page scraping.
def fetch_api(api_url: str) -> dict:
"""Fetch a JSON API endpoint through Web Unlocker."""
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": api_url, "format": "raw"}
Forwarding API endpoint URLs externally is especially dangerous because APIs often expose complete structured records, making extraction more scalable and impactful than HTML scraping. The surrounding guidance to seek out hidden APIs increases the likelihood of aggressive or unauthorized collection behaviors.
def fetch_api(api_url: str) -> dict:
"""Fetch a JSON API endpoint through Web Unlocker."""
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": api_url, "format": "raw"}
)
This concurrent bulk scraping example operationalizes high-volume external transmission, allowing many arbitrary URLs to be fetched in parallel through Bright Data. The concurrency guidance materially increases the scale and speed of collection, amplifying abuse potential and the impact of scraping sensitive or unauthorized targets.
async def fetch_one(session, url):
async with sem:
async with session.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"},
timeout=aiohttp.ClientTimeout(total=60),
As part of the production template, this code normalizes repeated external transmission behavior into copy-paste-ready scraper logic. That makes accidental misuse more likely, especially by users who may not appreciate that all targets and responses are being routed through a third-party provider.
def fetch_page(url: str, retries: int = 3) -> str:
for attempt in range(retries):
try:
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"},
As part of the production template, this code normalizes repeated external transmission behavior into copy-paste-ready scraper logic. That makes accidental misuse more likely, especially by users who may not appreciate that all targets and responses are being routed through a third-party provider.
def fetch_page(url: str, retries: int = 3) -> str:
for attempt in range(retries):
try:
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"},
The template’s outbound request code embeds the core third-party transmission behavior into a production-ready script, making it easy to deploy without considering destination sensitivity. This increases operational risk because users may adopt it as-is and scrape arbitrary sites through an external processor.
for attempt in range(retries):
try:
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"},
timeout=60,
The documentation repeatedly instructs users to send target URLs, page content, and scraping inputs to Bright Data services, but it does not clearly warn that this shares potentially sensitive browsing targets and retrieved content with a third party. In a scraper-building skill, this matters because users may apply the examples to internal, authenticated, regulated, or otherwise sensitive pages without understanding the data-sharing implications.
This duplicate finding reflects the same external transmission behavior in the fetch_page example: target URLs are sent off-platform to Bright Data for retrieval. The risk is not code execution but undisclosed third-party data sharing that may surprise users and violate internal data-handling expectations.
ZONE = os.environ["BRIGHTDATA_UNLOCKER_ZONE"]
def fetch_page(url: str) -> str:
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"},
This duplicate finding reflects the same external transmission behavior in the fetch_page example: target URLs are sent off-platform to Bright Data for retrieval. The risk is not code execution but undisclosed third-party data sharing that may surprise users and violate internal data-handling expectations.
ZONE = os.environ["BRIGHTDATA_UNLOCKER_ZONE"]
def fetch_page(url: str) -> str:
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": url, "format": "raw"},
This duplicate finding points to the same bulk API trigger call that transmits user-provided URL inventories to a third party. In a production scraper guide, that becomes more dangerous because users may operationalize it at scale without reviewing privacy, contractual, or compliance consequences.
def bulk_scrape_with_trigger(urls: list[str], dataset_id: str) -> list:
"""Submit all URLs to Web Scraper API at once."""
# Trigger
response = requests.post(
"https://api.brightdata.com/datasets/v3/trigger",
params={"dataset_id": dataset_id, "format": "json"},
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
This duplicate finding points to the same bulk API trigger call that transmits user-provided URL inventories to a third party. In a production scraper guide, that becomes more dangerous because users may operationalize it at scale without reviewing privacy, contractual, or compliance consequences.
def bulk_scrape_with_trigger(urls: list[str], dataset_id: str) -> list:
"""Submit all URLs to Web Scraper API at once."""
# Trigger
response = requests.post(
"https://api.brightdata.com/datasets/v3/trigger",
params={"dataset_id": dataset_id, "format": "json"},
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
Downloading the completed snapshot from Bright Data means scraped content is being stored and later retrieved from a third-party service, which increases confidentiality and retention concerns beyond simple transit. In this skill context, users may unknowingly cause externally hosted copies of scraped data to exist, including potentially sensitive content.
# Download
data = requests.get(
f"https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}",
params={"format": "json"},
headers={"Authorization": f"Bearer {API_KEY}"}
).json()
The guide instructs users to send arbitrary target URLs and returned page content through Bright Data's external service using environment-based credentials, but it does not clearly warn that this transmits browsing targets and scraped content to a third party. In a scraper-building skill, that omission is security-relevant because users may unknowingly process sensitive URLs, session-bound pages, or regulated data through external infrastructure.
This code performs an outbound request to Bright Data and includes a user-supplied target URL in the JSON payload, causing external transmission of the browsing target and resulting fetched content path through a third-party service. In context, this is expected product behavior for a scraping skill, but it is still a real data-exposure concern if users apply it to confidential endpoints or authenticated pages without understanding the trust boundary.
ZONE = os.environ["BRIGHTDATA_UNLOCKER_ZONE"]
# Fetch raw HTML
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": TARGET_URL, "format": "raw"}
This code performs an outbound request to Bright Data and includes a user-supplied target URL in the JSON payload, causing external transmission of the browsing target and resulting fetched content path through a third-party service. In context, this is expected product behavior for a scraping skill, but it is still a real data-exposure concern if users apply it to confidential endpoints or authenticated pages without understanding the trust boundary.
ZONE = os.environ["BRIGHTDATA_UNLOCKER_ZONE"]
# Fetch raw HTML
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": TARGET_URL, "format": "raw"}
This example sends the same target URL to the external Bright Data endpoint and additionally requests markdown-formatted output, which still involves third-party handling of fetched page content. The extra formatting step may encourage users to send full page material off-platform without considering confidentiality or terms-of-service implications.
html = response.text
# Also fetch as markdown for a quick readable overview
md_response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"zone": ZONE, "url": TARGET_URL, "format": "raw", "data_format": "markdown"}
No suspicious patterns detected.