Back to skill

Security audit

FSB Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill clearly discloses that it controls the user's Chrome, but its unpinned npm/MCP setup can run changed code later in a logged-in browser context.

Install only if you trust both the FSB Chrome extension and the `fsb-mcp-server` npm package. For safer use, pin an exact reviewed package version in all MCP configs and scripts, supervise browser actions in logged-in sessions, and require explicit confirmation for purchases, account changes, public posts, and other state-changing actions.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Error
Location
scripts/doctor.mjs:105
Finding
Unpinned npm Package Is Downloaded and Executed Automatically<![CDATA[ ## Vulnerability Details **File Location**: - `SKILL.md:11-16` - `SKILL.md:38-40` - `USAGE.md:45-55` - `scripts/doctor.mjs:105-110` - `scripts/install-host.mjs:13-15` - `scripts/install-host.mjs:92-97` - `scripts/install-host.mjs:182-187` - `scripts/print-stdio.mjs:6-11` - `scripts/print-hermes-yaml.mjs:6-11` **Vulnerability Type**: Unpinned third-party dependency execution **Risk Level**: High ### Vulnerable Code `SKILL.md:11-16`: ```yaml metadata: openclaw: {"install":[{"kind":"node","package":"fsb-mcp-server","bins":["fsb-mcp-server"],"label":"Install FSB MCP server (npm)"}]} hermes: mcp_servers: fsb: command: "npx" args: ["-y", "fsb-mcp-server"] ``` `SKILL.md:38-40`: ```markdown ## Doctor-first protocol If anything looks off (no page response, unexpected errors, stale state, missing tab) run `node scripts/doctor.mjs` (which wraps `npx -y fsb-mcp-server doctor`) BEFORE retrying the same call. ``` `USAGE.md:45-55`: ```markdown To discover other supported hosts on the machine (Claude Desktop, Cursor, etc.), run: ``` npx -y fsb-mcp-server install --list ``` Then run the host-specific installer, for example: ``` npx -y fsb-mcp-server install --claude-desktop ``` Notes: - What these commands do: each invocation spawns the `fsb-mcp-server` Node package via npx. `install --list` only prints detected MCP hosts and exits. `install --<host>` writes the FSB stdio block into that host's MCP config file and nothing else. Run only the host installers you actually want configured; decline prompts otherwise. - By default, `npx -y fsb-mcp-server` resolves to the latest published bridge so security fixes ship without re-running the installer. ``` `scripts/doctor.mjs:105-110`: ```js const child = spawn('npx', ['-y', 'fsb-mcp-server', 'doctor'], { stdio: ['ignore', 'pipe', 'pipe'], shell: false, }); ``` `scripts/install-host.mjs:13-15`: ```js const NPX = 'npx'; const PKG = 'fsb-mcp-server'; const MARKERS = ['de ...[truncated 4044 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Pin an exact audited version everywhere.** Replace mutable package references with an exact release, for example: ```yaml args: ["-y", "fsb-mcp-server@0.9.90"] ``` Apply the same exact version in: - `SKILL.md` metadata. - `scripts/doctor.mjs`. - `scripts/install-host.mjs`. - `scripts/print-stdio.mjs`. - `scripts/print-hermes-yaml.mjs`. - Every installation and recovery command in `USAGE.md`. - Any generated MCP host configuration. 2. **Do not use ranges or distribution tags.** Avoid `latest`, omitted versions, caret ranges, tilde ranges, and broad semver ranges. These still allow the executable payload to change without another Skill review. 3. **Verify package integrity.** Publish and document the expected npm integrity digest for the approved package tarball. Where practical, download the package through a locked dependency installation and verify it using a lockfile or an independently published checksum before execution. 4. **Use a reviewed local installation.** Prefer installing the approved dependency from a lockfile and executing its local binary rather than allowing `npx` to resolve from the network on every invocation: ```text node_modules/.bin/fsb-mcp-server ``` 5. **Remove automatic confirmation suppression where feasible.** Avoid `-y` for first-time installation or upgrades. Require an explicit user decision after displaying the exact version, source registry, and expected integrity value. 6. **Separate upgrades from normal operation.** Diagnostic commands and routine MCP host startup should never implicitly upgrade executable code. Provide a dedicated update command that: - Shows the installed and proposed versions. - Links to release notes. - Verifies integrity. - Requires explicit confirmation. - Supports rollback to the previously approved version. 7. **Constrain npm resolution.** Document the required registry an ...[truncated 516 chars]
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (33)

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Content
s no judgment call here.

- Any click on a real web page.
- Any text input into a real form (search box, login field, comment box, anything).
- Any auth flow (login, MFA prompt, vault credential lookup, saved-payment selection).
- Any multi-tab orchestration (open a new tab and switch back, fill a form across two tabs, copy from tab A to tab B).
- Any task that needs the user's logged-in session, cookies, or chrome-state-dependent rendering.
- Any dynamic page where the relevant content is rendered after JS, behind a scroll, or behind a click.

Rule: **If a task hits any bullet above, it does not belong on WebFetch. Escalate to FSB.**

## Stay on WebFetch (carve-out)

WebFetch is fine -- often better -- for read-only public content where no interaction is needed. Spinning up the FSB extension for a static fetch is unnecessary overhead.

Stay-with-WebFetch cases:

- Public documentation pages (HTML / Markdown).
- JSON endpoints (REST APIs, public JSON files).
- RSS / Atom feeds.
- `site
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Vague Triggers

Medium
Confidence
90% confidence
Finding
The guidance repeatedly tells the agent to 'ALWAYS escalate to FSB' for a wide range of website-related situations and to prefer FSB when unsure, which biases tool selection toward a capability that operates on the user's real browser, cookies, and saved credentials. In this context, over-selection is dangerous because it unnecessarily expands exposure of authenticated sessions and increases the chance of unintended sensitive actions or data access compared with safer read-only tools.

Rp1

Medium
Category
MCP Rug Pull
Confidence
97% confidence
Finding
The skill launches an MCP server via `npx -y fsb-mcp-server` without pinning an exact package version or integrity source, so each invocation may fetch whatever version is current at execution time. Because this skill is designed to control the user's real Chrome session, an upstream package compromise or malicious update could immediately gain powerful browser automation capabilities in an authenticated context.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
This command executes the latest published fsb-mcp-server package via npx without pinning a specific version. That creates a supply-chain risk: a compromised maintainer account, malicious release, or breaking change could cause unreviewed code to run on the user's machine during installation or configuration.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The documented installer command runs `fsb-mcp-server` from the latest npm release rather than an audited version. Because this installer writes MCP host configuration and invokes executable package code, an attacker who can influence the package publication path could achieve arbitrary code execution or persistent malicious configuration.

Rp1

Medium
Category
MCP Rug Pull
Confidence
97% confidence
Finding
The text explicitly recommends resolving to the latest published bridge so updates arrive automatically. In a security-sensitive browser-control skill, this increases danger because the package can control browser automation pathways and modify local MCP integration, so users are encouraged to execute changing remote code without prior review.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
This diagnostic command fetches and runs the latest npm package version through npx. Even though it is framed as a harmless version check, it still relies on executing remote package code and therefore exposes users to the same supply-chain compromise risk as the installer path.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
The `status --watch` example invokes an unpinned npm package that will execute code from the latest published release. In this skill's context, the package interacts with a localhost bridge to a real Chrome extension, so compromise could expose browsing context, alter automation behavior, or establish persistence in the user's MCP setup.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
This recovery command again asks the user to run the latest package from npm without version pinning. Because it is presented in troubleshooting guidance, users may execute it repeatedly under stress, amplifying the chance of silently adopting a malicious or compromised release that can modify host configuration.

External Transmission

Medium
Category
Data Exfiltration
Content
### WebFetch (public read-only)

- "Read the README of github.com/fullselfbrowsing/FSB." -- raw public content.
- "Fetch https://api.github.com/repos/fullselfbrowsing/FSB and report stargazers." -- public JSON.
- "Read the latest entry from this RSS feed." -- RSS read.
- "Pull the changelog text from https://example.com/changelog." -- static HTML.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
These tools route through the extension's background service worker, not the content script, so they continue to function on `chrome://`, `edge://`, and Web Store URLs.

| Tool       | What it does                                                  | Example                                                                                              |
|------------|---------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| list_tabs  | Enumerate the agent's owned tabs.                             | `list_tabs({})` -- find a non-restricted tab to switch to.                                           |
| switch_tab | Switch agent focus to another owned tab.                      | `switch_tab({ tab_id: <id from list_tabs> })`                                                        |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
These tools route through the extension's background service worker, not the content script, so they continue to function on `chrome://`, `edge://`, and Web Store URLs.

| Tool       | What it does                                                  | Example                                                                                              |
|------------|---------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| list_tabs  | Enumerate the agent's owned tabs.                             | `list_tabs({})` -- find a non-restricted tab to switch to.                                           |
| switch_tab | Switch agent focus to another owned tab.                      | `switch_tab({ tab_id: <id from list_tabs> })`                                                        |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| switch_tab | Switch agent focus to another owned tab.                      | `switch_tab({ tab_id: <id from list_tabs> })`                                                        |
| open_tab   | Open a new tab in agent scope (background by default).        | `open_tab({ url: "https://example.com" })`                                                           |
| navigate   | Change the URL of the current tab.                            | `navigate({ url: "https://example.com" })` -- works zero-content-script per Phase 247 active-tab work.|
| go_back    | Step back one history entry on the current tab.               | `go_back({})`                                                                                        |
| go_forward | Step forward one history entry on the current tab.            | `go_forward({})`                                                                                     |
| refresh    | Reload the current tab.                                       | `refresh({})` -- useful after the extension installs mid-session.                                    |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| open_tab   | Open a new tab in agent scope (background by default).        | `open_tab({ url: "https://example.com" })`                                                           |
| navigate   | Change the URL of the current tab.                            | `navigate({ url: "https://example.com" })` -- works zero-content-script per Phase 247 active-tab work.|
| go_back    | Step back one history entry on the current tab.               | `go_back({})`                                                                                        |
| go_forward | Step forward one history entry on the current tab.            | `go_forward({})`                                                                                     |
| refresh    | Reload the current tab.                                       | `refresh({})` -- useful after the extension installs mid-session.                                    |

Every tool name in the table above is a registered name in `mcp/ai/tool-definitions.cjs`. Any tool not on this list (`read_page`, `click`, `type_text`, `get_dom_snapshot`, `get_page_snapshot`, `wait_for_element`, etc.) requires content-script attach and will fail on a restricted tab.
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The worked example explicitly instructs the agent to select a size and click an add-to-cart button without any pause for user confirmation, even though adding items to a cart is a user-impacting commerce action. In the context of a browser-driving skill, examples shape agent behavior, so this can normalize silent state-changing actions and increase the chance of unintended purchases or cart manipulation on logged-in retail sites.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
Line L76 states that `client` must be on a fixed shared allowlist and enumerates specific product names. This imposes an organizational/access policy through natural-language documentation, but the file does not explain a justified regional/compliance need or offer any user choice, which fits the policy-violation category for forced constraints.

Whitespace Padding

Medium
Category
Prompt Injection
Content
Every MCP action tool accepts and requires the following fields on every call:

| Field           | Type    | Required | Description                                                                                          |
|-----------------|---------|----------|------------------------------------------------------------------------------------------------------|
| `visual_reason` | string  | required | Short human-readable reason shown in the overlay (for example, `"Logging in to GitHub"`).            |
| `client`        | string  | required | Allowlisted client label. Validated against the v0.9.36 shared badge allowlist (see below).          |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
This second reference is the same underlying issue: invoking an MCP server via unpinned `npx` means the executed code is not fixed or reproducible. Because the surrounding skill is explicitly about controlling Chrome through an extension and MCP bridge, any hostile package update could gain local code execution and potentially abuse browser automation, session data, or user workflows.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The script repeatedly instructs or invokes `npx -y fsb-mcp-server` without pinning an exact package version, which causes execution of whatever version the npm registry resolves at runtime. If the package is compromised, a malicious version is published, or dependency resolution changes, running this diagnostic can fetch and execute unreviewed code on the host machine.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
This user-facing next step tells operators to run `npx -y fsb-mcp-server --version` without an exact version, normalizing execution of an unpinned remote package. Even though it is framed as a diagnostic, it still pulls and runs code resolved at execution time, creating a supply-chain risk.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
The recommended command `npx -y fsb-mcp-server status --watch` is unpinned and would execute whichever package version npm serves at that moment. In a browser-automation skill, that is especially sensitive because the invoked server may gain access to local browser state, tabs, and automation channels.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
This remediation text again directs users to run an unpinned `npx` install command, which can install and execute an unexpected package version from the registry. Because this is part of setup for an MCP/browser bridge, compromise could lead to code execution and broader access to the user's browsing environment.

Rp1

Medium
Category
MCP Rug Pull
Confidence
98% confidence
Finding
The code directly spawns `npx` with `['-y', 'fsb-mcp-server', 'doctor']`, meaning the host will resolve and execute an unpinned package at runtime. This is a real supply-chain vulnerability because the script is not merely documenting the command; it actively performs remote package execution during diagnostics.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
The warning path tells users to re-run `npx -y fsb-mcp-server doctor`, again encouraging execution of an unpinned registry package. While this instance is only output text rather than direct execution, it still perpetuates the same unsafe operational pattern and can lead users to fetch a compromised version later.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The manifest describes FSB as a skill that drives the user's Chrome via an extension and MCP bridge for live web tasks. This script instead detects MCP hosts, invokes package installation into those hosts, and directly edits ~/.hermes/config.yaml, which is host-configuration management rather than browser-driving behavior.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/install-host.mjs:94