1jehuang / 1jehuang/jcode

Browser bridge installs an unverified, unpinned native executable

Open
#634 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: no bug priority: high triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Summary

jcode browser setup downloads and installs the Firefox bridge (a browser CLI, the .xpi extension, and a native messaging host binary) from a second repository with no integrity verification and no version pin. The main release binary got checksum verification in #63, but this download path never got the equivalent.

Verified against v0.61.1 (438789eb).

Evidence

download_browser_binary in crates/jcode-base/src/browser.rs:408 fetches the release list from:

const GITHUB_API_LATEST: &str =
    "https://api.github.com/repos/1jehuang/firefox-agent-bridge/releases/latest";

It then downloads three assets straight to disk via write_file_atomically (browser.rs:517) with no digest or signature check anywhere in the function:

  • the browser CLI binary,
  • browser-agent-bridge.xpi,
  • firefox-agent-bridge-host (the native messaging host).

The two executables are written 0o755 (browser.rs:538). A repo-wide grep for sha256/checksum/signature/verify around this path finds nothing but a log string; there is no SHA256SUMS fetch and no pin to a known release tag (it resolves releases/latest at install time).

The native host is then registered as a Firefox native messaging host (install_native_host_manifest, browser.rs:589) with path pointing at the downloaded firefox-agent-bridge-host, so it runs as a stdio subprocess of Firefox and drives a profile with the user's logins and cookies.

Why this matters

This is the same trust concern #63 already accepted and fixed for the main jcode release: a user has no way to confirm the binary they run matches the intended artifact. It applies more sharply here because:

  • the asset is an executable (the native host) that runs outside jcode and attaches to the real Firefox profile;
  • the source is a separate repo, so it widens the trust root beyond 1jehuang/jcode;
  • releases/latest is unpinned, so what gets installed depends on whatever is newest at setup time.

A compromised firefox-agent-bridge release (or account/token takeover on it) results in an arbitrary executable being installed and run, with no client-side signal. Because it registers as a native host attached to the real Firefox profile, that executable can read any tab and exfiltrate logged-in session cookies, or run as arbitrary local code under the user's account. The unpinned releases/latest means this can also change under a user who already ran setup once.

Suggested fix

Apply #63's approach to this path:

  1. Publish SHA256SUMS in the firefox-agent-bridge releases.
  2. Have download_browser_binary fetch it and verify each asset, failing closed on mismatch.
  3. Pin to a known release tag jcode expects for the installed version, rather than releases/latest, so the bridge version is deterministic per jcode version.
  4. Optionally, sign the assets (minisign/cosign) as the stronger follow-up #63 left open.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in crates/jcode-base/src/browser.rs at download_browser_binary (around lines 408 and 517), then review the existing checksum approach from #63. Trace how the three assets are downloaded and how install_native_host_manifest registers the host at line 589. Done means the bridge release is pinned per jcode version, every asset is verified, and setup fails closed on mismatch.

Written by the indexing model from the issue text.

Assessment

Tech stack
github, rust
Domain
cli, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.