Back to skill

Security audit

deep-website-scraper-agent-built-api-skill

Security checks for vulnerabilities and agentic risk

Overview

This scraper appears to do what it says, but it should be reviewed because it asks for an API key through chat and can send arbitrary URLs and potentially personal data to BrowserAct without clear guardrails.

Install only if you are comfortable with target URLs and scraped results being processed by BrowserAct. Configure BROWSERACT_API_KEY locally and do not paste the key into chat. Avoid internal, private, signed, credential-bearing, or regulated URLs, and treat returned contact fields or other personal data according to your privacy and retention obligations.

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

Warning
Location
SKILL.md:27
Finding
Unsafe API Credential Disclosure Guidance<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:27-30`; related implementation in `scripts/deep_website_scraper_api.py:92-98` **Vulnerability Type**: Sensitive credential exposure through insecure onboarding instructions **Risk Level**: Medium ### Complete Code Snippets `SKILL.md:27-30`: ```markdown ## API Key Guide Before running, check the `BROWSERACT_API_KEY` environment variable. If it is not set, do not take other measures; ask and wait for the user to provide it. Agent must tell the user: ``` `scripts/deep_website_scraper_api.py:92-98`: ```python api_key = os.getenv("BROWSERACT_API_KEY") if not api_key: print("\n[!] ERROR: BrowserAct API Key is missing.", flush=True) print("Please follow these steps:", flush=True) print(f"1. Go to: {API_KEY_URL}", flush=True) print("2. Copy your API Key.", flush=True) print("3. Provide it to me or set it as an environment variable (BROWSERACT_API_KEY).", flush=True) sys.exit(1) ``` ### Technical Analysis The Skill documentation instructs the Agent to ask the user for the BrowserAct API key, while the script tells the user to “Provide it to me.” This encourages disclosure of a bearer credential through the Agent conversation rather than limiting credential handling to a local environment variable. Conversation messages may be retained in transcripts, observability systems, debugging logs, or other infrastructure outside the execution environment. Requesting the secret through chat is unnecessary because the script already supports reading it securely from `BROWSERACT_API_KEY`. The script does not print the value after reading it, and its use as a bearer token for the declared BrowserAct API is functionally necessary. The vulnerability is specifically the insecure onboarding and disclosure guidance, not the environment-variable lookup itself. ### Attack Path 1. The user attempts to run the Skill without setting `BROWSERACT_API_KEY`. 2. The documentation or script directs th ...[truncated 781 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all instructions asking the user to provide the API key to the Agent. 2. Change the script message to require local configuration only, for example: ```python print( "Set BROWSERACT_API_KEY securely in the local execution environment. " "Do not paste the key into chat.", flush=True, ) ``` 3. Update `SKILL.md` to explicitly prohibit requesting, displaying, echoing, logging, or storing the key. 4. Continue reading the credential from `BROWSERACT_API_KEY`, but validate only that it is present; do not include its value in exceptions or diagnostic output. 5. Recommend secret-manager or scoped runtime injection where available. 6. Advise users to rotate any API key previously disclosed through a conversation or log. 7. Use a minimally scoped BrowserAct credential where the provider supports scope or quota restrictions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/deep_website_scraper_api.py:17
Finding
Unrestricted User-Supplied URL Forwarded to a Third-Party Scraping Service<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deep_website_scraper_api.py:17-34` and `scripts/deep_website_scraper_api.py:100-101` **Vulnerability Type**: Missing validation of externally transmitted URL input **Risk Level**: Medium ### Complete Code Snippets `scripts/deep_website_scraper_api.py:17-34`: ```python def run_task(api_key, website_url='https://example.com'): headers = {"Authorization": f"Bearer {api_key}"} payload = { "input": { "website_url": website_url, } } print("Start Task", flush=True) try: response = requests.post( f"{API_BASE_URL}/templates/{TEMPLATE_ID}/runs", json=payload, headers=headers, timeout=30, ).json() ``` `scripts/deep_website_scraper_api.py:100-101`: ```python website_url = sys.argv[1] if len(sys.argv) > 1 else 'https://example.com' output = run_task(api_key, website_url) ``` ### Technical Analysis The script accepts an arbitrary command-line string as `website_url` and forwards it unchanged to BrowserAct. It does not validate the scheme, hostname, embedded user information, IP address class, or presence of sensitive query parameters. This exceeds the Skill’s declared scope of processing public webpages because the input can identify private or local resources, contain credentials in URL user information, include signed query tokens, or use an unintended URI scheme. The entire URL is disclosed to BrowserAct and may consequently enter third-party request logs, task records, dashboards, or processing infrastructure. Because BrowserAct performs the actual browser operation remotely, this repository alone does not prove that internal resources are reachable or that BrowserAct is vulnerable to server-side request forgery. However, the Skill fails to enforce its own stated public-web boundary and unnecessarily permits sensitive URL data to be transmitted to a third party. ### Attack Path 1. An atta ...[truncated 1320 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the input with a standards-compliant URL parser such as `urllib.parse.urlsplit`. 2. Allow only the `https` and, if operationally necessary, `http` schemes. 3. Reject URLs containing embedded usernames or passwords. 4. Require a valid hostname and reject localhost names, private-use domains, and IP literals belonging to loopback, private, link-local, multicast, reserved, or unspecified ranges. 5. Resolve hostnames and reject resolutions to non-public addresses. Revalidate after redirects where the downstream platform supports redirect policies, because initial hostname validation alone does not prevent DNS rebinding or redirects to private destinations. 6. Reject non-web schemes such as `file:`, `ftp:`, `data:`, and `javascript:`. 7. Warn users when query strings or fragments are present, and require confirmation before transmitting URLs likely to contain secrets. 8. Document clearly that the URL is sent to BrowserAct for third-party processing. 9. Where feasible, configure the BrowserAct template itself to enforce public-network-only navigation and redirect validation. 10. Avoid logging full sensitive URLs; redact user information and security-related query parameters in diagnostics. ]]>
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 (5)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill clearly relies on environment access (`BROWSERACT_API_KEY`) and outbound network/API calls, but it does not declare corresponding permissions. That mismatch can bypass expected platform trust and review controls, making it harder for users or orchestrators to understand that the skill can exfiltrate inputs to an external service. In this context, the skill is specifically designed to send user-provided URLs and retrieved page content to BrowserAct, which increases the importance of transparent permission declaration.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The description is broad enough to trigger on generic requests like collecting public data, exporting records, enriching datasets, or monitoring web data, even when a narrower or safer tool would be more appropriate. That over-broad routing can cause unintended invocation of a networked scraping skill and transmission of user targets/data to a third-party API without sufficiently specific user intent. Because this skill performs deep scraping and automated extraction, accidental activation is more dangerous than for a purely local helper.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill advertises extraction of fields such as email, phone, and address but does not warn that the output may contain personal data. That omission can lead users or downstream agents to collect, store, or redistribute personal information without adequate notice, minimization, or compliance checks. The context makes this more sensitive because scraping at scale and exporting structured records materially increases privacy and misuse risk.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script transmits a user-supplied website URL to BrowserAct's third-party API to initiate scraping, but it provides no explicit disclosure, consent flow, or data-handling warning before sending that input off-host. In a skill context, users may assume the agent is acting locally; silently forwarding targets and associated task metadata to an external service creates privacy, compliance, and data-governance risk, especially if users provide internal, sensitive, or regulated URLs.

External Transmission

Medium
Category
Data Exfiltration
Content
print("Start Task", flush=True)
    try:
        response = requests.post(
            f"{API_BASE_URL}/templates/{TEMPLATE_ID}/runs",
            json=payload,
            headers=headers,
Confidence
89% confidence
Finding
This POST request sends user-controlled input and authorization credentials to an external API, which is expected for the integration but still constitutes a real security/privacy boundary crossing. In an agent skill, this is more dangerous because the tool can be invoked on arbitrary user-provided targets, potentially causing unreviewed disclosure of sensitive URLs or misuse of the API for scraping destinations the operator did not intend to share with a third party.

Static analysis

No suspicious patterns detected.