Back to skill

Security audit

honeybook-fpx

Security checks for vulnerabilities and agentic risk

Overview

This skill is transparent about its HoneyBook automation goal, but it asks users to extract and replay live browser session credentials for sensitive business and payment data.

Install only if you are comfortable granting a CLI and browser-extension workflow access to live HoneyBook session credentials and private client records. Use it only on accounts you own or are authorized to access, avoid shared machines, avoid storing captures in /tmp, treat the token like a password, and prefer the supported MCP or an official authentication flow where available.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T08 · Insecure Dependencies

Error
Location
SKILL.md:42
Finding
Unpinned Privileged Third-Party CLI Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 42 **Vulnerability Type**: Supply-chain exposure through an unpinned global dependency **Risk Level**: High ### Vulnerable Code ```sh npm install -g @fetchproxy/cli # provides `fpx` ``` ### Technical Analysis The setup installs the latest available version of `@fetchproxy/cli` globally without an exact version, lockfile, integrity hash, or other provenance verification. Because the package is installed globally, its installation scripts and executable code run with the privileges of the user performing the installation. This dependency occupies a sensitive trust boundary: the documented workflow uses `fpx` to access browser `localStorage` containing a reusable HoneyBook bearer token, user ID, and optional trusted-device state. A compromised publisher account, registry, package release, or transitive dependency could therefore introduce arbitrary code after the Skill has been reviewed. The audit did not establish that the current package is malicious. The vulnerability is that the command automatically trusts whichever package version the registry resolves at execution time. ### Attack Path 1. An attacker compromises the npm package publisher, registry delivery path, or a transitive dependency. 2. The attacker publishes a modified version under the legitimate package name. 3. A user follows the Skill instructions and runs `npm install -g @fetchproxy/cli`. 4. npm resolves and executes the compromised release, including any lifecycle scripts. 5. The malicious package runs with the installing user's privileges. 6. During subsequent session capture, it can read or transmit the HoneyBook bearer token and browser-derived storage data. 7. The stolen token may then be replayed against HoneyBook APIs until it expires or is revoked. ### Impact Assessment Successful exploitation could provide code execution under the installing user's account and access to session credentials processed by the ...[truncated 305 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `@fetchproxy/cli` to an exact, reviewed version rather than resolving the latest release. - Record and verify package integrity using a lockfile and registry-provided integrity hash. - Prefer a project-local installation over `npm install -g`. - Disable lifecycle scripts where operationally possible, or separately review all required installation scripts. - Review the package and relevant transitive dependencies before granting access to browser session data. - Run the CLI in a constrained environment with no access to unrelated credentials or files. - Establish an update process that reviews version changes before changing the pin. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:43
Finding
Browser Session Capture Exceeds Minimum Required Scope<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 31–37, 43–49, and 59–71 **Vulnerability Type**: Excessive browser-domain and local-storage privileges **Risk Level**: High ### Vulnerable Code ```text Two apexes are declared on one profile: - `hbportal.co` — the vendor's branded portal (e.g. `acme.hbportal.co`), where the stored session lives. - `honeybook.com` — the main app, where the same session is also valid. ``` ```sh fpx profile add honeybook --domain honeybook.com --domain hbportal.co fpx profile declare honeybook \ --local-storage HONEYBOOK_REACT_CURR_USER \ --local-storage jStorage fpx pair -p honeybook # prints a pair code → approve in Transporter ``` ```sh fpx session -p honeybook --storage-domain hbportal.co > /tmp/hb-session.json ``` ```sh AUTH_TOKEN=$(jq -r '.localStorage.HONEYBOOK_REACT_CURR_USER | fromjson | .authentication_token' /tmp/hb-session.json) USER_ID=$(jq -r '.localStorage.HONEYBOOK_REACT_CURR_USER | fromjson | ._id' /tmp/hb-session.json) # Optional — the API returns 200 without it. The React blob and jStorage hold # DIFFERENT values; either is accepted. `// empty` keeps an absent field from # becoming the literal string "null". TRUSTED_DEVICE=$(jq -r '.localStorage.jStorage | fromjson | .HB_TRUSTED_DEVICE // empty' /tmp/hb-session.json) ``` ### Technical Analysis The Skill grants the Transporter extension and FetchProxy profile access to two apex domains and declares two complete local-storage values for capture. The documented API calls require the authentication token and user ID from `HONEYBOOK_REACT_CURR_USER`; the Skill explicitly states that `HB_TRUSTED_DEVICE` is optional and that the API returns a successful response without it. Consequently, capturing the entire `jStorage` value is not necessary for the declared read-only API workflow. The document also states that this storage object contains additional values such as `SESSION_COMPANY_ID` and routing state. Those values cross th ...[truncated 1598 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `jStorage` from the declared capture fields. - Omit `HB_TRUSTED_DEVICE` from requests because the Skill states that it is optional. - Capture only the minimum required fields from `HONEYBOOK_REACT_CURR_USER`: the authentication token and user ID. - Restrict browser-extension access to the specific vendor portal host whenever the tooling supports host-level scoping. - Do not authorize `honeybook.com` unless a documented operation specifically requires browser storage from that domain. - Require explicit, per-vendor user approval before each new credential capture. - Clearly disclose which values leave the browser and which local components receive them. - Revoke or rotate captured sessions after use when HoneyBook provides an appropriate session-management mechanism. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:59
Finding
Long-Lived Credentials and Private Records Written to Predictable Temporary Files<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 59 and 65–71; `references/requests.md`, lines 31, 49, and 112 **Vulnerability Type**: Unsafe temporary-file handling and plaintext sensitive-data persistence **Risk Level**: High ### Vulnerable Code From `SKILL.md`: ```sh fpx session -p honeybook --storage-domain hbportal.co > /tmp/hb-session.json ``` ```sh AUTH_TOKEN=$(jq -r '.localStorage.HONEYBOOK_REACT_CURR_USER | fromjson | .authentication_token' /tmp/hb-session.json) USER_ID=$(jq -r '.localStorage.HONEYBOOK_REACT_CURR_USER | fromjson | ._id' /tmp/hb-session.json) # Optional — the API returns 200 without it. The React blob and jStorage hold # DIFFERENT values; either is accepted. `// empty` keeps an absent field from # becoming the literal string "null". TRUSTED_DEVICE=$(jq -r '.localStorage.jStorage | fromjson | .HB_TRUSTED_DEVICE // empty' /tmp/hb-session.json) ``` From `references/requests.md`: ```sh hb_get "/api/v2/users/$USER_ID/workspace_files" > /tmp/hb-files.json ``` ```sh hb_get "/api/v2/workspace_files/$FILE_ID" > /tmp/hb-file.json ``` ```sh jq -r 'select(type=="object") | .error_data.server_api_version // empty' /tmp/hb-resp.json ``` ### Technical Analysis The workflow uses fixed, predictable filenames in the shared `/tmp` directory. It does not set a restrictive `umask`, create a private temporary directory, verify file ownership, reject symbolic links, or install a cleanup trap. `/tmp/hb-session.json` contains raw browser session data, including a bearer token described by the Skill as opaque and long-lived. The response files can contain contracts, signatures, invoices, vendor-internal fields, event data, payment schedules, and other private records. Depending on operating-system protections and the user's `umask`, another local user may be able to read the generated files. Predictable redirection targets also create a symlink or pre-created-file risk: an attacker who can prepare `/tmp/hb-session.json` or anoth ...[truncated 1965 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use a private temporary directory and restrictive permissions before capturing any data: ```sh umask 077 HB_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/honeybook.XXXXXXXX") || exit 1 trap 'rm -rf -- "$HB_TMPDIR"' EXIT HUP INT TERM SESSION_FILE="$HB_TMPDIR/session.json" fpx session -p honeybook --storage-domain hbportal.co > "$SESSION_FILE" chmod 600 "$SESSION_FILE" ``` Additional hardening should include: - Keep the bearer token in memory or a narrowly scoped shell variable where possible rather than persisting the complete capture. - Delete the session file immediately after extracting the required fields instead of retaining it until process exit. - Store API responses only when necessary; otherwise pipe them directly into a narrowly scoped `jq` projection. - Never use fixed shared paths such as `/tmp/hb-session.json`. - Verify that temporary files are regular files owned by the current user before reading them. - Avoid following symbolic links when implementing file creation in a script. - Document cleanup behavior and warn users that response bodies may contain financial, contractual, and personal information. - Prefer an operating-system credential store for any session material that must persist across runs. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill instructs users to capture bearer tokens and user identifiers from browser localStorage, which are highly sensitive session credentials. Presenting this as routine setup without prominent warnings or guardrails normalizes credential extraction and increases the likelihood of accidental exposure, reuse, or misuse.

Ssd 3

High
Confidence
98% confidence
Finding
This section explains that a signed-in browser tab holds a bearer token and user ID in localStorage and that those secrets can be reused to access HoneyBook APIs directly. That is effectively a recipe for replaying a live authenticated session outside the browser, enabling access to sensitive contracts, invoices, proposals, payment methods, and workspace data.

Ssd 3

High
Confidence
99% confidence
Finding
The skill gives step-by-step instructions to capture a vendor session from an open browser tab, export it to a file, and parse out authentication_token and _id values. This operationalizes credential theft/reuse and makes unauthorized disclosure of private client-portal data significantly easier for anyone with local access or social-engineered browser access.

Ssd 3

High
Confidence
98% confidence
Finding
The core request pattern uses captured session secrets as headers to enumerate and retrieve private workspace files, events, messages, tasks, notes, attachments, and payment data from HoneyBook's API. Combined with the earlier extraction steps, this creates a full exfiltration path for sensitive business and customer information.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The skill is presented as a read-only data access method, but it also documents how to send real workspace messages through HoneyBook's API. That mismatch can mislead users and downstream agents into invoking write-capable behavior they did not consent to, potentially causing unauthorized communications or business-impacting actions.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The description says to use this skill 'when you want HoneyBook data without the MCP, in a script, or on a machine where the MCP isn't installed,' but it does not define specific trigger phrases, boundaries, or exclusion conditions. In a manifest-scoped description, this broad wording could overlap with many generic HoneyBook data-access requests and lead to unintended invocation.

External Transmission

Medium
Category
Data Exfiltration
Content
same endpoint):

```sh
API_VERSION=$(curl -s 'https://api.honeybook.com/api/gon?callback=parseGon' \
  | grep -oE '"api_version":[[:space:]]*[0-9]+' | grep -oE '[0-9]+$')
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
required at all:

```sh
curl -s "https://api.honeybook.com/api/v2/users/$USER_ID/workspace_files" \
  -H 'accept: application/json, text/plain, */*' \
  -H "hb-api-auth-token: $AUTH_TOKEN" \
  -H "hb-api-user-id: $USER_ID" \
Confidence
90% confidence
Finding
This external request transmits captured authentication headers, including a bearer-style auth token and user ID, to access private user workspace files. In context, the transmission is dangerous because it is part of a documented session-replay mechanism using browser-extracted credentials.

External Transmission

Medium
Category
Data Exfiltration
Content
```sh
# Projects ("events") and the workspace id each one carries
curl -s "https://api.honeybook.com/api/v2/client/events" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/events/$EVENT_ID/details" "${HB_HEADERS[@]}"
# The feed: messages (feed_message / workspace_email / workspace_file_email) and activity
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/feed" "${HB_HEADERS[@]}" \
Confidence
89% confidence
Finding
This outbound call queries client events using previously captured session headers. In context, it facilitates authenticated retrieval of sensitive portal records through replayed browser credentials rather than a supported integration path.

External Transmission

Medium
Category
Data Exfiltration
Content
```sh
# Projects ("events") and the workspace id each one carries
curl -s "https://api.honeybook.com/api/v2/client/events" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/events/$EVENT_ID/details" "${HB_HEADERS[@]}"
# The feed: messages (feed_message / workspace_email / workspace_file_email) and activity
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/feed" "${HB_HEADERS[@]}" \
  | jq '.feed.feed_items[] | select(.type|test("email|message")) | {id:._id, subject:.data.subject, from:.sender_id, sent:.data.sent_on}'
Confidence
89% confidence
Finding
This request fetches detailed event data from HoneyBook using reused session headers. The danger is contextual: it expands the scope of accessible private records once browser-derived credentials have been extracted.

External Transmission

Medium
Category
Data Exfiltration
Content
curl -s "https://api.honeybook.com/api/v2/client/events" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/events/$EVENT_ID/details" "${HB_HEADERS[@]}"
# The feed: messages (feed_message / workspace_email / workspace_file_email) and activity
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/feed" "${HB_HEADERS[@]}" \
  | jq '.feed.feed_items[] | select(.type|test("email|message")) | {id:._id, subject:.data.subject, from:.sender_id, sent:.data.sent_on}'
# Tasks (curr_date MUST be MM/DD/YYYY), notes, loose files, payment schedule
curl -s "https://api.honeybook.com/api/v2/tasks/workspaces/$WS_ID?page=1&perPage=30&sort_by=due_date&sort_desc=false&curr_date=09%2F02%2F2026" "${HB_HEADERS[@]}"
Confidence
90% confidence
Finding
This outbound request pulls workspace feed items, including email and message metadata, through captured session credentials. In context, it enables disclosure of private communications and activity data beyond what a safe read-only shell helper should expose via session replay.

External Transmission

Medium
Category
Data Exfiltration
Content
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/feed" "${HB_HEADERS[@]}" \
  | jq '.feed.feed_items[] | select(.type|test("email|message")) | {id:._id, subject:.data.subject, from:.sender_id, sent:.data.sent_on}'
# Tasks (curr_date MUST be MM/DD/YYYY), notes, loose files, payment schedule
curl -s "https://api.honeybook.com/api/v2/tasks/workspaces/$WS_ID?page=1&perPage=30&sort_by=due_date&sort_desc=false&curr_date=09%2F02%2F2026" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/notes/workspace/$WS_ID" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/attachments" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/payments" "${HB_HEADERS[@]}"
Confidence
88% confidence
Finding
This request retrieves task data for a workspace using the harvested HoneyBook session. It is part of a broader unauthorized-access pattern that allows scripted extraction of internal project and client information.

External Transmission

Medium
Category
Data Exfiltration
Content
| jq '.feed.feed_items[] | select(.type|test("email|message")) | {id:._id, subject:.data.subject, from:.sender_id, sent:.data.sent_on}'
# Tasks (curr_date MUST be MM/DD/YYYY), notes, loose files, payment schedule
curl -s "https://api.honeybook.com/api/v2/tasks/workspaces/$WS_ID?page=1&perPage=30&sort_by=due_date&sort_desc=false&curr_date=09%2F02%2F2026" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/notes/workspace/$WS_ID" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/attachments" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/payments" "${HB_HEADERS[@]}"
```
Confidence
88% confidence
Finding
This call reads workspace notes with the captured session headers. Notes frequently contain sensitive internal context, so enabling scripted access through session replay materially increases confidentiality risk.

External Transmission

Medium
Category
Data Exfiltration
Content
# Tasks (curr_date MUST be MM/DD/YYYY), notes, loose files, payment schedule
curl -s "https://api.honeybook.com/api/v2/tasks/workspaces/$WS_ID?page=1&perPage=30&sort_by=due_date&sort_desc=false&curr_date=09%2F02%2F2026" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/notes/workspace/$WS_ID" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/attachments" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/payments" "${HB_HEADERS[@]}"
```
Confidence
88% confidence
Finding
This request fetches workspace attachments using browser-derived authentication headers. In context, that supports exfiltration of uploaded files and documents, which may include contracts and other sensitive customer records.

External Transmission

Medium
Category
Data Exfiltration
Content
curl -s "https://api.honeybook.com/api/v2/tasks/workspaces/$WS_ID?page=1&perPage=30&sort_by=due_date&sort_desc=false&curr_date=09%2F02%2F2026" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/notes/workspace/$WS_ID" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/attachments" "${HB_HEADERS[@]}"
curl -s "https://api.honeybook.com/api/v2/workspaces/$WS_ID/payments" "${HB_HEADERS[@]}"
```

Sending a message is a two-step "client pending task", not a POST of the
Confidence
90% confidence
Finding
This outbound call accesses workspace payment information using captured session credentials. Payment-related data is especially sensitive, so documenting scripted retrieval through browser-token reuse creates elevated confidentiality and compliance risk.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
- Session data (`AUTH_TOKEN`, `TRUSTED_DEVICE`) is opaque and
  long-lived server-side (no client-visible JWT expiry) — keep it in shell
  variables, not a world-readable file, if you must persist it at all.
- This project is developed and maintained by AI (Claude).
Confidence
83% confidence
Finding
The note acknowledges that session data is long-lived and suggests keeping it in shell variables rather than a world-readable file, but this is still an unsafe default because the workflow already writes session material to /tmp and normalizes handling raw auth secrets in the shell. Long-lived credentials in temp files, shell history, process environments, or logs can be recovered by other local users or tooling.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The example function explicitly sends live HoneyBook session credentials in custom headers (`hb-api-auth-token`, `hb-api-user-id`, and optionally `hb-trusted-device`) and presents them as ready-to-run shell commands without any prominent warning about safe handling, storage, shell history, logs, or process exposure. In this skill’s context, those headers grant direct access to client-portal data such as contracts, invoices, payment methods, and workspace details, so accidental disclosure or reuse of captured values could expose sensitive customer and financial information.

Static analysis

No suspicious patterns detected.