console fill: never copy Google session cookies by default (device-bound); own profile in a Chrome started without automation switches

Google binds its session cookies to the device (Device Bound Session Credentials) and signs out
sessions whose cookies look stolen, which can sign the owner out of their real Chrome. The default is
now storebound's own profile per store; storebound starts Chrome itself (--user-data-dir,
--remote-debugging-port=0, no --enable-automation, navigator.webdriver false) and attaches over CDP.
--use-chrome-session google|apple is an explicit opt-in that warns. /signin/rejected is said plainly.
This commit is contained in:
CRTkafa 2026-10-12 07:46:04 +08:00
parent e0bef82b06
commit 0035931734
22 changed files with 456 additions and 156 deletions

View file

@ -150,8 +150,8 @@ Each entry: **symptom** → cause → what to do → what guards it now. The ful
while the owner is signed in; an older detector counted any frame on a sign-in host as a sign-in page.
- **Do:** read the line "sign-in detected because: <rule> at <url>" and the heartbeats (they name the page). A
top-level `accounts.google.com` / `idmsa.apple.com` / App Store Connect `/login` URL right after the launch means the
copied Chrome session did not carry over (expired or tied to that device): sign in once in the window, or run with
`--fresh-profile`. Anything else: re-run with `--debug-dump` (up to 3 dumps of the sign-in wait) and attach the
copied Chrome session did not carry over (expired or tied to that device): sign in once in the window, or run
without `--use-chrome-session` (pitfall 18). Anything else: re-run with `--debug-dump` (up to 3 dumps of the sign-in wait) and attach the
folder after the owner looked at `screen.jpg`.
- **Guard:** `signInReason` in `cli/console/fill.ts` (top-level URL, the main frame's password / email-entry form, a
visible Apple sign-in frame; no other frame counts), the sign-in watchdog dump, `tests/console-fill.test.ts`.
@ -167,6 +167,29 @@ Each entry: **symptom** → cause → what to do → what guards it now. The ful
- **Guard:** `setUpAllowed` (`cli/lib/console-forms.ts`), `setUpClick` / `setUpType` (`cli/console/fill.ts`),
`tests/console-flow.test.ts` with `tests/fixtures/console/apple-app-privacy-setup.html`.
## 18. Never copy Google session cookies: they are device-bound
- **Symptom:** `console fill play-app-record` with the owner's copied Chrome cookies reached the Play account chooser
once (22:32); between runs Google showed `accounts.google.com/v3/signin/rejected`; from 23:12 the same copy landed on
the account chooser.
- **Cause:** Google binds its session cookies to the device. Chrome's Device Bound Session Credentials keep a key in
the TPM / Secure Enclave that cannot leave the machine; Google only renews the short-lived cookies for the browser
that proves it holds that key (public on Windows from Chrome 146, rolling out on macOS from Chrome 147). Google also
signs out sessions whose cookies look stolen ("logged out of their account for that session and any related
suspicious sessions on that device", then an extra verification). Copied cookies in a second Chrome look exactly
like cookie theft: the copy is refused, and the owner's REAL Chrome session can be signed out or the account asked
to verify again.
- **Do:** never copy Google cookies. The default is storebound's own profile (`~/.storebound/console-profile/<store>`):
the owner signs in there once, by hand; it is kept. `--use-chrome-session google` exists only as an explicit owner
opt-in that prints the warning; an agent never adds it. Apple publishes no such binding, but `--use-chrome-session
apple` is opt-in too. If Google says "Couldn't sign you in" in storebound's window, storebound prints "Google refused
sign-in in this window (/signin/rejected)": try again, or sign in at accounts.google.com first in that window.
- **Guard:** `browserPlan` / `openConsoleBrowser` in `cli/console/session.ts` (no copy without the flag, the copy keeps
only the form's own provider), Chrome started by storebound without `--enable-automation` and with
`navigator.webdriver` false, `googleRejected`; `tests/console-session.test.ts`.
- **Sources:** https://blog.google/security/protecting-cookies-with-device-bound-session-credentials/ ,
https://developer.chrome.com/docs/web-platform/device-bound-session-credentials ,
https://knowledge.workspace.google.com/admin/security/investigate-and-take-action-on-suspicious-session-cookies
## Adding a lesson
Every bug found in real use gets an entry in `docs/pitfalls.md` and here, and, where possible, a check or a test
that fails without the fix (see CONTRIBUTING.md).