Back to skill

Security audit

Find Job UK

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a Gumtree job-search helper, but its listing script can fetch arbitrary URLs and its install path adds persistent/global components, so users should review it before installing.

Install only if you are comfortable with a global bb-browser dependency and persistent adapter files. Prefer pinning the bb-browser version, reviewing the bundled JavaScript, and restricting listing lookups to Gumtree URLs or running the tool in a constrained environment.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
bb-sites/gumtree/listing.js:65
Finding
Unrestricted Absolute URL Fetch Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `bb-sites/gumtree/listing.js`, lines 65–76 **Vulnerability Type**: Server-Side Request Forgery (SSRF) through insufficient URL validation **Risk Level**: High ### Vulnerable Code ```javascript 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, { headers: { ``` ### Technical Analysis The listing adapter is intended to retrieve pages from `www.gumtree.com`, but it only prepends the Gumtree origin when the supplied value does not begin with `http`. Any attacker-controlled absolute HTTP or HTTPS URL is therefore passed directly to `fetch()`. The code does not validate: - The URL scheme. - The destination hostname. - The destination port. - Whether the address resolves to a loopback, link-local, or private-network address. - The destination of HTTP redirects. The metadata declaration naming `www.gumtree.com` is not a substitute for validation inside the adapter. Unless the bb-browser runtime independently and reliably restricts network access to that domain, this creates an SSRF primitive. After fetching the response, the adapter reads the complete response body and parses JSON-LD and Open Graph metadata. Data obtained from an internal endpoint could consequently be exposed through returned fields such as `title`, `description`, `firstImageUrl`, or `imageUrls`. ### Attack Path 1. An attacker supplies a crafted absolute URL as the listing argument, such as a loopback URL, private-network service, or cloud metadata endpoint. 2. Because the value begins with `http`, the adapter does not prepend `https://www.gumtree.com`. 3. The untrusted URL is passed directly to `fetch()`. 4. The runtime makes a request from its own network co ...[truncated 1056 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the supplied value using `new URL()` and reject malformed URLs. 2. Require the `https:` scheme. 3. Allow only an explicit hostname, preferably exactly `www.gumtree.com`. 4. Reject embedded credentials, unexpected ports, protocol-relative URLs, and alternate textual representations of prohibited addresses. 5. Disable automatic redirects or validate the scheme, hostname, port, and resolved address after every redirect. 6. Resolve the hostname and reject loopback, link-local, private, reserved, and otherwise non-public IP ranges for both IPv4 and IPv6. 7. Consider accepting only Gumtree-relative listing paths rather than arbitrary absolute URLs. 8. Apply outbound network controls so the runtime cannot reach localhost, private networks, or cloud metadata services. A minimal hostname restriction should resemble: ```javascript const candidate = new URL(String(args.url), 'https://www.gumtree.com'); if ( candidate.protocol !== 'https:' || candidate.hostname !== 'www.gumtree.com' || candidate.username || candidate.password || candidate.port ) { return { error: 'Only HTTPS URLs on www.gumtree.com are allowed' }; } ``` This validation should be supplemented with redirect validation and network-level egress restrictions. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:25
Finding
Unpinned Global npm Dependency Creates a Supply-Chain Execution Risk<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 25 **Vulnerability Type**: Unpinned third-party dependency installed globally **Risk Level**: Medium ### Vulnerable Code ```bash npm i -g bb-browser ``` ### Technical Analysis The documented prerequisite installs the latest version of `bb-browser` globally from npm. No exact version, lockfile, package integrity value, or reviewed artifact is specified. Because npm package versions are mutable from the consumer's perspective when an unconstrained package name is used, the effective code installed by this instruction can change after the skill has been audited. npm installation may also execute package lifecycle scripts. A global installation increases the impact because the package is placed in shared user- or system-level executable locations rather than being isolated to this project. This finding does not establish that `bb-browser` is malicious. The vulnerability is the unsafe dependency acquisition process, which permits an unexpectedly changed or compromised future release to execute during installation. ### Attack Path 1. The user follows the prerequisite instructions and runs `npm i -g bb-browser`. 2. npm resolves the package name to the latest release available at that time. 3. If the package publisher, npm account, release pipeline, or package contents have been compromised, npm downloads the affected version. 4. Package lifecycle scripts may execute during installation with the privileges of the user running npm. 5. The resulting executable is installed globally and can subsequently process the copied Gumtree adapters or be invoked in future sessions. ### Impact Assessment A compromised dependency or lifecycle script can generally act with the privileges of the account performing installation. Potential impact includes: - Reading or modifying files available to that user. - Accessing user credentials and environment variables. - Making arbitrary network requests. - Modif ...[truncated 429 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `bb-browser` to a reviewed exact version instead of resolving the latest release: ```bash npm install --global --save-exact bb-browser@<reviewed-version> ``` 2. Document the expected npm package integrity hash and verify the downloaded artifact. 3. Prefer a project-local dependency recorded in `package.json` and a committed lockfile over a global installation. 4. Use `npm ci` with the reviewed lockfile where practical. 5. Disable lifecycle scripts with `--ignore-scripts` if bb-browser does not require them. 6. Review package provenance, publisher identity, release signatures, transitive dependencies, and lifecycle scripts before updating the pinned version. 7. Run the tool under a dedicated, least-privileged account or sandbox with restricted filesystem and network access. 8. Establish a controlled dependency-update process in which each new version is reviewed before the documentation is changed. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill claims specialization around jobs and part-time vacancies, but the analyzer indicates the underlying capability supports arbitrary classifieds queries and does not use or enforce a dedicated hours parameter. This kind of description-behavior mismatch can cause unsafe overtrust and policy bypass, since operators may allow the skill under the assumption it cannot access non-job content when it actually can.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill claims specialization around jobs and part-time vacancies, but the analyzer indicates the underlying capability supports arbitrary classifieds queries and does not use or enforce a dedicated hours parameter. This kind of description-behavior mismatch can cause unsafe overtrust and policy bypass, since operators may allow the skill under the assumption it cannot access non-job content when it actually can.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill requires and instructs use of bb-browser to perform live Gumtree queries, which is a network-capable action, yet the skill declares no explicit tool scope such as permissions or allowed-tools. Missing scope increases the chance the skill is run with broader-than-necessary capabilities and makes review harder because operators cannot tell from metadata what external access is intended.

Session Persistence

Medium
Category
Rogue Agent
Content
- This bundle includes [`bb-sites/gumtree/search.js`](bb-sites/gumtree/search.js) and [`bb-sites/gumtree/listing.js`](bb-sites/gumtree/listing.js). Install:

```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
76% confidence
Finding
The installation instructions copy site scripts into ~/.bb-browser/sites/gumtree, creating persistent behavior that survives the current session. Persistence is risky because modified or malicious scraper code placed in a user-scoped plugin directory can continue to run on future invocations, and the skill does not describe integrity verification or cleanup.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
The request hard-codes `Accept-Language: en-GB,en;q=0.9`, which imposes a specific language/locale preference. Under the policy, locale constraints should be optional or clearly justified; this file does not offer user opt-in or explain why English (UK) is required.

Missing User Warnings

Low
Confidence
87% confidence
Finding
This code performs an HTTP request to Gumtree using user-supplied search terms and location, which transmits potentially sensitive user intent or approximate location to an external site. Within this file there is no confirmation prompt, logging, comment, or docstring warning the user that their inputs will be sent over the network.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The request hard-codes the Accept-Language header to 'en-GB,en;q=0.9', which imposes a specific language/locale preference regardless of the user's settings or choice. This is a natural-language policy concern because the skill does not offer any language or locale opt-in, override, or documented justification for the constraint.

Static analysis

No suspicious patterns detected.