Back to skill

Security audit

crossref-works-search-scraper-api-skill

Security checks for vulnerabilities and agentic risk

Overview

This Crossref scraping skill uses a disclosed BrowserAct API workflow, but it asks users to hand an API key to the agent and allows browsing outside the stated Crossref scope.

Install only if you are comfortable using BrowserAct for this workflow. Set BROWSERACT_API_KEY through a local environment variable or secret manager, do not paste it into chat, and keep invocations limited to the Crossref works search URL.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/crossref_works_search_scraper_api.py:17
Finding
Unrestricted Browser Target Exceeds the Declared Crossref Scope<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crossref_works_search_scraper_api.py`, lines 17–36 and 102–105 **Vulnerability Type**: Unrestricted user-controlled remote browsing target **Risk Level**: Medium ### Vulnerable Code ```python def run_task(api_key, base_url='https://search.crossref.org/search/works', keyword='machine learning', count='1'): headers = {"Authorization": f"Bearer {api_key}"} payload = { "input": { "base_url": base_url, "keyword": keyword, "count": count, } } print("Start Task", flush=True) try: response = requests.post( f"{API_BASE_URL}/templates/{TEMPLATE_ID}/runs", json=payload, headers=headers, timeout=30, ).json() ``` The target is populated directly from a command-line argument: ```python base_url = sys.argv[1] if len(sys.argv) > 1 else 'https://search.crossref.org/search/works' keyword = sys.argv[2] if len(sys.argv) > 2 else 'machine learning' count = sys.argv[3] if len(sys.argv) > 3 else '1' output = run_task(api_key, base_url, keyword, count) ``` ### Technical Analysis The Skill declares that it searches public Crossref Works records, for which the expected target is `https://search.crossref.org/search/works`. However, the implementation accepts an arbitrary `base_url` and forwards it to a fixed BrowserAct browser-automation template without validating its scheme, hostname, port, embedded credentials, or resolved address. This allows an invocation to direct the remotely operated browser toward a destination unrelated to Crossref. Depending on the BrowserAct execution environment and template behavior, this could include attacker-controlled sites, internal service names, IP literals, private or link-local addresses, or credential-bearing URLs. Redirects may also allow an initially acceptable URL to lead outside the intended domain unless redirect destinations are independen ...[truncated 2004 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove arbitrary target selection if it is unnecessary. Use the fixed Crossref endpoint internally rather than accepting `base_url` from the command line: ```python CROSSREF_WORKS_URL = "https://search.crossref.org/search/works" ``` 2. If configurability is required, parse the URL with `urllib.parse.urlsplit` and enforce all of the following: - The scheme must be exactly `https`. - The normalized hostname must be exactly `search.crossref.org`. - User information in the URL must be rejected. - Unexpected ports, fragments, and malformed URLs must be rejected. - IP literals and private, loopback, link-local, multicast, reserved, and unspecified addresses must be rejected. - The permitted path should be restricted to `/search/works` unless additional Crossref paths are explicitly required. 3. Configure the BrowserAct template itself with the same destination allowlist. Local validation alone cannot prevent the remote template or a server-side redirect from navigating elsewhere. 4. Reject or stop redirects that leave the approved Crossref origin, validating every redirect destination. 5. Apply bounds and format checks to `count` to prevent unexpected resource consumption, and constrain keyword length to a reasonable maximum. 6. Do not encourage users to paste API keys into an agent conversation. Update `SKILL.md` and the script's onboarding message to instruct users to configure `BROWSERACT_API_KEY` directly through an environment variable or approved secret manager. ]]>
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 (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares runtime requirements for Python and an environment variable containing an API key, and it instructs execution of a script that will make outbound requests to BrowserAct, but it does not clearly declare equivalent permissions. This creates a capability/permission mismatch that can mislead users or policy systems about access to secrets and network use, reducing transparency and weakening review controls.

Vague Triggers

Medium
Confidence
79% confidence
Finding
The description is broad enough to match generic requests such as exporting public records, enriching datasets, or monitoring public web data, which could cause the skill to be invoked for loosely related tasks without sufficient user intent. Over-broad triggering increases the chance of unnecessary external calls, data collection, or disclosure of user queries to a third-party service.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The output section states that returned data may include personal contact fields such as name, email, phone, and address, but it provides no privacy warning, purpose limitation, or handling guidance. This can normalize collection and return of personal data from a public-source workflow without informing users about sensitivity, minimization, or downstream compliance risks.

Ssd 3

Medium
Confidence
98% confidence
Finding
The script explicitly tells the user to 'Provide it to me' when referring to the BrowserAct API key, creating a social-engineering path for credential disclosure to the agent instead of keeping the secret in a local environment variable or secret store. In an agent skill context, this is dangerous because users may paste live API credentials into chat or tool inputs, where they can be logged, retained, or exposed to other systems.

Static analysis

No suspicious patterns detected.