From 7689eda0374420c934fba755661e9f975f61b396 Mon Sep 17 00:00:00 2001 From: johnnogueira Date: Mon, 22 Jun 2026 04:02:11 -0700 Subject: [PATCH] cli: add --dump cookies to export browser jar as JSON (#313) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds DumpFormat::Cookies that serializes the full browser cookie jar as pretty-printed JSON after page load. Unlike document.cookie, this captures HttpOnly cookies inaccessible from JS — useful for extracting session tokens set by anti-bot challenges. --- crates/obscura-cli/src/main.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/obscura-cli/src/main.rs b/crates/obscura-cli/src/main.rs index d2ab8dd..9669490 100644 --- a/crates/obscura-cli/src/main.rs +++ b/crates/obscura-cli/src/main.rs @@ -190,6 +190,10 @@ enum DumpFormat { /// replay the asset graph with their own HTTP client when they /// need the originals alongside the page (cf. issue 124). Assets, + /// Dump all cookies in the browser jar as a JSON array, including + /// HttpOnly cookies that are inaccessible via document.cookie. + /// Useful for extracting session tokens set by anti-bot challenges. + Cookies, } fn print_banner(port: u16) { @@ -628,6 +632,7 @@ async fn run_fetch( DumpFormat::Links => dump_links(&page), DumpFormat::Markdown => dump_markdown(&mut page), DumpFormat::Assets => dump_assets(&page), + DumpFormat::Cookies => dump_cookies(&page), // Handled above via the short-circuit branch; unreachable here. DumpFormat::Original => unreachable!("Original dump handled before page navigation"), }; @@ -719,6 +724,11 @@ async fn wait_for_selector(page: &mut Page, selector: &str, timeout_secs: u64) - } } +fn dump_cookies(page: &Page) -> String { + let cookies = page.context.cookie_jar.get_all_cookies(); + serde_json::to_string_pretty(&cookies).unwrap_or_else(|_| "[]".to_string()) +} + fn dump_html(page: &Page) -> String { page.with_dom(|dom| { if let Ok(Some(html_node)) = dom.query_selector("html") {