docs(browse): warn that the bundled Chromium still trusts the compromised eMudhra intermediates (#3338)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-25 02:32:12 +00:00
1 parent e66c43c572
commit 7450f3d4d4
2 files changed
+38 -3

No files matched your search

+30 -3
View File
@@ -267,7 +267,7 @@ flow, and a layered prompt-injection defense — all behind a compiled CLI that
prints plain text to stdout. ~100-200ms per call. Zero context-token overhead.
It runs whenever the probe above does not print `READY`, and `$B` is a
legitimate tool in that context; on a Mac with Aside open the skills never
reach for it.
reach for it. Its HTTPS trust has a known gap: see [TLS trust](#tls-trust-the-bundled-chromiums-root-store).
---
@@ -562,7 +562,7 @@ from `snapshot`, or `@c` refs from `snapshot -C`. Full table:
|---------|-------------|
| `cookie <name>=<value>` | Set cookie on current page domain |
| `cookie-import <json>` | Import cookies from JSON file |
| `cookie-import-browser [browser] [--domain d] [--profile p] [--all] [--clear-storage] [--verify-auth]` | Copy selected browser cookies; picker by default, explicit scoped or all-domain import, optional storage reset and sign-in assertion |
| `cookie-import-browser [browser] [--domain d] [--profile p] [--all] [--clear-storage] [--verify-auth]` | Copy selected browser cookies; picker by default, explicit scoped or all-domain import, optional storage reset and sign-in assertion. The imported session rides on the bundled Chromium's root store ([TLS trust](#tls-trust-the-bundled-chromiums-root-store)) |
| `header <name>:<value>` | Set custom request header (sensitive values auto-redacted) |
| `useragent <string>` | Set user agent (triggers context recreation, invalidates refs) |
@@ -673,7 +673,7 @@ pass `--force-restart` to replace it explicitly (see "Daemon lifecycle" above).
| Command | Description |
|---------|-------------|
| `handoff [reason]` | Open visible Chrome at current page for user takeover (CAPTCHA, MFA, complex auth) |
| `handoff [reason]` | Open visible Chrome at current page for user takeover (CAPTCHA, MFA, complex auth). What you type there trusts the bundled Chromium's root store ([TLS trust](#tls-trust-the-bundled-chromiums-root-store)) |
| `resume` | Re-snapshot after user takeover, return control to AI |
### Meta + chains
@@ -1296,6 +1296,33 @@ only writer when the chat-path agent was removed, so they reported stale or
empty data. The live defenses report through their own call sites. See
ARCHITECTURE.md § "Prompt injection defense" for the full threat model.
### TLS trust: the bundled Chromium's root store
The fallback engine checks HTTPS certificates against the root store compiled
into its bundled Playwright Chromium. The default headless browser never gets
the CRLSet revocation updates Chrome pushes to running browsers. Headed mode and
`handoff` do fetch them, but only about a minute after each launch, so the
first pages they open, including the page `handoff` reopens, are checked
against the compiled root store alone. The bundled build does not enforce
Certificate Transparency. That matters most for the flows that put real
sessions and credentials into the browser: `cookie-import-browser`,
`fill`/`type`, and `handoff`. Aside uses your own browser's trust store and
updates.
**Known gap: the compromised eMudhra intermediates
([#3338](https://github.com/garrytan/gstack/issues/3338)).** Chrome blocked them
by CRLSet on 2026-10-17 and removes their root, emSign ECC Root CA - G3, from
the Chrome Root Store on 2026-10-27. gstack's pinned Playwright 1.62.1
(Chromium 151), every release through 1.64.1 (Chromium 156) and the 1.65
alphas (Chromium 157) still trust them, so
`$B goto https://dv-g3b-emudhra.we-have-a-problem.com/` loads a page saying
"That's bad!" instead of failing with `ERR_CERT_AUTHORITY_INVALID` (headed mode
fails it with `ERR_CERT_REVOKED` once its CRLSet arrives). gstack will move to
the first Playwright release whose Chromium carries the removal. Until then,
don't import cookies or type credentials in this engine on a network you do not
trust, and prefer Aside for signed-in work where you have it. The same `goto`
tells you when your build is fixed.
---
## Screenshots, PDFs, visual
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## [Unreleased]
**BROWSER.md now says that gstack's own browser still trusts the compromised eMudhra intermediates, and how to check (#3338).** Chrome blocks the eight eMudhra intermediate CAs whose keys leaked on 2026-10-17 with a CRLSet push, and removes their root, emSign ECC Root CA - G3, from the Chrome Root Store on 2026-10-27. gstack's fallback browser gets neither in time: its default headless browser never receives CRLSet updates, headed mode and `handoff` receive them only about a minute after each launch, and the root store compiled into the bundled Chromium still trusts the root. On 2026-10-24, `$B goto https://dv-g3b-emudhra.we-have-a-problem.com/` returned 200 and "That's bad!" on gstack's pinned Playwright 1.62.1 (Chromium 151.0.7922.34). The same check against Playwright 1.64.1 (Chromium 156.0.8078.4) and the 1.65.0 alpha of 2026-10-24 (Chromium 157.0.8103.15) also loaded the page. Chrome for Testing builds from 158.0.8115.0 fail it with `ERR_CERT_AUTHORITY_INVALID`, so a Playwright bump has to wait for a release that bundles one of those builds.
### Changed
- **`BROWSER.md`**: a new "TLS trust: the bundled Chromium's root store" section, at the end of the security stack, says the fallback engine checks certificates against that compiled root store, that the headless browser never gets CRLSet updates while headed mode and `handoff` get them about a minute after launch, and that the bundled build does not enforce Certificate Transparency. It names the flows that put real sessions and credentials into the browser (`cookie-import-browser`, `fill`/`type`, `handoff`) and gives the one-line `$B goto` check. The fallback-engine introduction and the `cookie-import-browser` and `handoff` command rows link to it. Aside is unaffected, because it is your own browser with its own updates.
- The edits above the cookie workflow excerpt change no line count, so the `setup-browser-cookies/SKILL.md workflow` judge input is byte-identical (prompt SHA-256 `c851e635…`, 12,805 bytes, before and after).
## [1.91.191.0] - 2026-10-25
**`gstack-version-bump write --changelog` moves the branch's `[Unreleased]` entry under the new version, and /ship Step 12 stops treating a provisional queue pick as a verified slot.** Stamping by hand meant writing VERSION with `gstack-version-bump write` and then renaming the `## [Unreleased]` heading yourself, because only `gstack-restamp` re-headed the CHANGELOG. Separately, when `gstack-next-version` could not read some open PRs' VERSION it returned `complete:false` and a provisional pick, and Step 12 printed the warning and then wrote that version as if the queue had been checked (left over from #3258, noted in GSTA-45).