Back to skill

Security audit

Gumtree UK — bb-browser

Security checks for vulnerabilities and agentic risk

Overview

This Gumtree search skill is mostly coherent, but its listing adapter can fetch arbitrary URLs instead of being limited to Gumtree.

Review this skill before installing. It appears intended for read-only Gumtree UK searches, but only pass trusted Gumtree listing paths or URLs to gumtree/listing, and consider pinning bb-browser plus removing ~/.bb-browser/sites/gumtree if you no longer want the adapter override active.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
bb-sites/gumtree/listing.js:68
Finding
Server-Side Request Forgery Through an Unrestricted Listing URL## Vulnerability Details **File Location**: `bb-sites/gumtree/listing.js`, lines 68-79 **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```js if (!args.url) return { error: 'Missing argument: url', hint: 'e.g. bb-browser site gumtree/listing "https://www.gumtree.com/p/.../ID"' }; let path = String(args.url).trim(); if (!path.startsWith('http')) { if (!path.startsWith('/')) path = '/' + path; path = 'https://www.gumtree.com' + path; } const resp = await fetch(path, { ``` ### Technical Analysis The adapter accepts an absolute URL from `args.url` and passes it directly to `fetch()` whenever its string begins with `http`. It does not parse the URL, restrict the protocol, validate the hostname, resolve and inspect the destination IP address, or enforce the declared `www.gumtree.com` domain. As a result, an attacker who can control the listing URL can cause the Agent environment to send requests to arbitrary Internet hosts, localhost services, private network addresses, link-local endpoints, or potentially cloud instance metadata services. The default redirect behavior can also permit a nominally allowed URL to redirect to an unauthorized destination. The fetched response is processed for JSON-LD and Open Graph metadata. Parseable title, description, image, pricing, or location data can therefore be returned to the caller. Even when response contents are not extractable, HTTP status codes and the final redirect URL may provide an internal-service discovery oracle. ### Attack Path 1. An attacker supplies an absolute URL such as `http://127.0.0.1:PORT/path`, a private network endpoint, or a link-local metadata endpoint as `args.url`. 2. The value begins with `http`, so the code accepts it without adding or enforcing the Gumtree hostname. 3. `fetch(path)` sends the request from the Agent's network environment. 4. The target response is read and parsed as HTML. 5 ...[truncated 832 chars]
Remediation
## Remediation Suggestions - Parse the supplied value using `new URL()` rather than relying on `startsWith('http')`. - Require the `https:` protocol. - Permit only `www.gumtree.com` and any other explicitly reviewed Gumtree hostnames. - Reject URLs containing embedded credentials, unexpected ports, malformed hostnames, or hostname suffix tricks. - Resolve the hostname before making the request and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges. - Disable automatic redirects or validate every redirect destination using the same protocol, hostname, port, and resolved-address rules. - Prefer accepting only a Gumtree path or listing identifier and constructing the complete URL internally. - Apply request timeouts, response-size limits, and content-type checks to reduce secondary denial-of-service risks. Example defensive approach: ```js const base = new URL('https://www.gumtree.com/'); const target = new URL(String(args.url).trim(), base); if (target.protocol !== 'https:' || target.hostname !== 'www.gumtree.com') { return { error: 'Only HTTPS URLs on www.gumtree.com are permitted' }; } const resp = await fetch(target.href, { redirect: 'manual', headers: { Accept: 'text/html,application/xhtml+xml' } }); ``` This example must be supplemented with redirect validation and resolved-IP filtering when the runtime permits DNS resolution or when DNS rebinding is within the threat model.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:37
Finding
Unpinned Global Third-Party Dependency Installation## Vulnerability Details **File Location**: `SKILL.md`, lines 37-38 **Vulnerability Type**: Insecure and mutable third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```markdown - [bb-browser](https://www.npmjs.com/package/bb-browser) installed globally (`npm i -g bb-browser`). - Adapter files: `bb-sites/gumtree/search.js` and `bb-sites/gumtree/listing.js`. ``` ### Technical Analysis The documented installation procedure installs the current npm release of `bb-browser` globally without pinning an exact reviewed version or supplying an integrity constraint. The effective dependency can therefore change after this Skill has been audited. npm packages may execute lifecycle scripts during installation. If a future package release or its dependency chain is compromised, installation can execute attacker-controlled code with the privileges of the user running npm. Global installation also broadens the affected scope because the installed executable is exposed outside this individual project and may subsequently be invoked by other workflows. This finding does not establish that the current `bb-browser` package is malicious. The risk arises from the mutable, unverified installation instruction and its global scope. ### Attack Path 1. A user follows the prerequisite command `npm i -g bb-browser`. 2. npm resolves the package version selected by the mutable default distribution tag rather than an audited exact version. 3. npm downloads the package and its transitive dependencies. 4. Any enabled installation lifecycle scripts execute with the installing user's privileges. 5. If the selected package release or dependency chain has been compromised, attacker-controlled code can modify files and configuration accessible to that user. 6. Because installation is global, the compromised executable may also affect unrelated projects or later invocations. ### Impact Assessment A compromised package relea ...[truncated 571 chars]
Remediation
## Remediation Suggestions - Pin `bb-browser` to an exact version that has been reviewed, rather than relying on the mutable latest release. - Document the expected package version and integrity digest. - Prefer a project-local development dependency with a committed lockfile over a global installation. - Use a trusted package registry and enforce lockfile integrity in automated environments. - Review direct and transitive dependencies with an appropriate package audit process before updating. - Disable lifecycle scripts with `--ignore-scripts` when they are not required, after confirming that doing so does not break legitimate installation behavior. - Avoid running npm installation commands with administrative privileges. - Establish a controlled dependency-update process in which version changes trigger renewed security review. A safer documented command should use a specifically reviewed version, for example: ```bash npm install --save-exact --save-dev bb-browser@REVIEWED_VERSION ``` The project should then commit and enforce the generated lockfile.
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill explicitly relies on network-capable tooling (`bb-browser`) to query Gumtree, but it does not declare any `permissions` or `allowed-tools` scope. This creates a least-privilege and transparency problem: an agent may invoke network access implicitly without an explicit policy boundary, increasing the risk of unintended outbound requests or abuse if the skill is composed into larger workflows.

Session Persistence

Medium
Category
Rogue Agent
Content
Install adapters (private site overrides the community bundle):

```bash
mkdir -p ~/.bb-browser/sites/gumtree
cp bb-sites/gumtree/search.js ~/.bb-browser/sites/gumtree/search.js
cp bb-sites/gumtree/listing.js ~/.bb-browser/sites/gumtree/listing.js
```
Confidence
85% confidence
Finding
The installation steps instruct the user to copy adapter files into `~/.bb-browser/sites/gumtree`, creating persistent modifications in the user's home directory that survive the current session. Persistent agent-installed artifacts can be risky because later runs of `bb-browser` may automatically trust and execute these local overrides, potentially enabling long-lived behavior changes or stale/unreviewed code execution.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The request hard-codes an `Accept-Language` header of `en-GB,en;q=0.9`, which imposes a specific locale preference in the skill's behavior. Under the policy, locale constraints should be user-selectable or clearly justified; this file provides neither.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The fetch request hard-codes the Accept-Language header to "en-GB,en;q=0.9", which imposes a specific locale preference regardless of user choice. This is a natural-language/locale policy concern because the skill does not offer any user opt-in or document a justified region-specific requirement.

Static analysis

No suspicious patterns detected.