fix(cookie-extract): let --from-browser target a specific Chrome profile#526
Open
LucasRollo wants to merge 3 commits into
Open
fix(cookie-extract): let --from-browser target a specific Chrome profile#526LucasRollo wants to merge 3 commits into
LucasRollo wants to merge 3 commits into
Conversation
rookiepy and browser_cookie3 both resolve to the first matching cookie database — in practice always the "Default" profile — with no way to target another profile from their public APIs. Anyone keeping research accounts in a separate Chrome profile (as README's dedicated-account guidance suggests) would have `agent-reach configure --from-browser chrome` silently read cookies from their real Default profile instead. - add list_chrome_profiles(): enumerate profiles from the browser's own Local State file (name, email, exact Cookies DB path); supports chrome/edge/brave/opera on macOS/Windows/Linux - extract_all()/configure_from_browser(): new optional profile= param; when set, routes through browser_cookie3 with an explicit cookie_file (rookiepy has no profile override). No profile given = behavior unchanged - CLI: new --chrome-profile flag; when several profiles exist and no flag is given, prompt interactively at a TTY, or list the folders and abort instead of guessing when non-interactive Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Explain how to extract cookies from a non-Default Chrome profile (the recommended setup for keeping burner/research accounts out of your main profile), how to find a profile's folder name (run the command, or chrome://version → Profile Path), and that only Chromium browsers support per-profile extraction. Adds matching Quick Reference rows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n correctly
Self-review of the --chrome-profile feature turned up several issues:
- Picker accepted "0"/negative input and silently selected the WRONG
profile: profiles[int(choice)-1] with only ValueError/IndexError guards
let int("0")-1 == -1 resolve to profiles[-1] (the last profile). Extract
the choice-parsing into _resolve_profile_choice() with an explicit
1<=n<=len bound, and unit-test 0 / negative / out-of-range / non-numeric.
- Opera can't actually be targeted by profile (it's Chromium-based but has
no Default/Profile N folders, and on Windows lives under %APPDATA% not
%LOCALAPPDATA%). Dropped it from the profile table so profile selection
is chrome/edge/brave only; opera still works for plain extraction. An
explicit --chrome-profile on opera/firefox now fails with a clear message.
- Requesting a profile on a rookiepy-only install raised a message telling
you to install rookiepy (already present); now it names browser_cookie3
as the actual requirement for profile mode.
- --chrome-profile help text no longer claims you're "prompted" in cases
where the non-interactive path aborts instead.
- Deduped a double Local State read on the not-found path; sort profiles
numerically so "Profile 10" follows "Profile 2"; handle EOF at the prompt;
clearer "profile exists but has no cookies yet" hint.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
agent-reach configure --from-browser chrome(and the auto-import during install) silently reads cookies from the Default Chrome profile only, with no way to pick another profile.Both extraction backends resolve to the first matching cookie DB and stop:
browser_cookie3's Chrome path list is['.../Default/Cookies', '.../Profile */Cookies']and it returns the first glob match (next(...)), soDefaultalways wins when present.rookiepydoes the same in its Rustfind_chrome_based_paths(first existing path wins, earlyreturn), and exposes no profile parameter through its Python API.This directly undercuts the project's own security guidance. The README and
docs/install.mdrecommend using a dedicated/secondary account for cookie-auth platforms (Twitter, XHS, Reddit, etc.). The natural way to do that is a separate Chrome profile for burner accounts — but with this bug, extraction ignores that profile and grabs cookies from the user's real Default profile instead. The safe workflow the docs recommend can't actually be followed.Fix
list_chrome_profiles(browser)— enumerates profiles from the browser's ownLocal Statefile (the same source Chrome's profile picker uses), returning each profile's folder, display name, account email, and exactCookiesDB path. Supports chrome/edge/brave/opera across macOS/Windows/Linux.extract_all()/configure_from_browser()— new optionalprofile=parameter. When set, it resolves that profile's exact cookie DB and routes throughbrowser_cookie3(cookie_file=...)(rookiepy has no profile override). When omitted, behavior is byte-for-byte unchanged — no regression for existing users.--chrome-profileflag — when multiple profiles exist and none is specified: prompts interactively (numbered list with name + email) at a TTY; otherwise lists the available folders and aborts rather than silently guessing.Tests
tests/test_cookie_extract_profiles.py— profile discovery, missing/emptyLocal State, profiles without aCookiesDB yet, the core regression (right profile → right cookie path), and the two error paths (unknown profile, firefox+profile).Example