Skip to content

fix(browser): import Chromium cookies from Network DBs (#6875)#7882

Merged
Jinwoo-H merged 3 commits into
stablyai:mainfrom
rodboev:pr/chromium-cookie-import-db-paths
Jul 10, 2026
Merged

fix(browser): import Chromium cookies from Network DBs (#6875)#7882
Jinwoo-H merged 3 commits into
stablyai:mainfrom
rodboev:pr/chromium-cookie-import-db-paths

Conversation

@rodboev

@rodboev rodboev commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Resolve the Electron target profile cookie database with the same Chromium Network/Cookies fallback used for source browser profiles instead of assuming the legacy Cookies path.
  • Read Chromium source cookies through SQLite directly, which lets SQLite coordinate with WAL state and avoids failing before import on a locked source-file copy.
  • Plaintext Chromium rows no longer require an OS encryption key; encrypted rows still require the existing key path.

Closes #6875.

Screenshots

No visual change.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm build
  • Added or updated high-quality tests that would catch regressions, or explained why tests were not needed

Focused validation:

  • pnpm exec vitest run --config config/vitest.config.ts src/main/browser/browser-cookie-import.test.ts - passed, Test Files 1 passed (1), Tests 17 passed (17).
  • pnpm run typecheck:node - passed.
  • pnpm exec oxlint src/main/browser/browser-cookie-import.ts src/main/browser/browser-cookie-import.test.ts - passed.
  • pnpm exec oxfmt --check src/main/browser/browser-cookie-import.ts src/main/browser/browser-cookie-import.test.ts - passed, All matched files use the correct format.

AI Review Report

  • Review focus: Chromium source and target cookie DB path handling, Windows file-lock behavior, Electron session staging, cross-platform browser import behavior, and key handling for encrypted cookies.
  • Firefox and Safari import paths remain unchanged.
  • Chromium encrypted cookies still require the existing platform key path, while plaintext rows can import without unnecessary DPAPI/keychain access.

Security Audit

  • The import remains limited to a previously detected browser cookie DB path and the selected Electron partition.
  • The change does not broaden renderer-selected file access, IPC access, auth scope, or network behavior.
  • Encrypted cookie handling still requires the existing OS key retrieval before decryption; plaintext rows bypass only the unnecessary key requirement.

Notes

No visual change. Live Chrome-on-Windows locking remains manual-validation scope; regression coverage uses real SQLite files for source and target Network/Cookies paths.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5ed9c239-c8bf-4854-8c6e-e985781fb673

📥 Commits

Reviewing files that changed from the base of the PR and between d754466 and 78733fb.

📒 Files selected for processing (6)
  • src/main/browser/browser-session-registry.persistence.test.ts
  • src/main/browser/browser-session-registry.ts
  • src/main/orca-profiles/profile-cloud-dev-auth.ts
  • src/main/orca-profiles/profile-cloud-service-auth-retry.test.ts
  • src/main/orca-profiles/profile-cloud-service-refresh.test.ts
  • src/main/orca-profiles/profile-cloud-service.test.ts
💤 Files with no reviewable changes (3)
  • src/main/orca-profiles/profile-cloud-service-auth-retry.test.ts
  • src/main/orca-profiles/profile-cloud-service.test.ts
  • src/main/orca-profiles/profile-cloud-service-refresh.test.ts
✅ Files skipped from review due to trivial changes (1)
  • src/main/orca-profiles/profile-cloud-dev-auth.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/browser/browser-session-registry.persistence.test.ts
  • src/main/browser/browser-session-registry.ts

📝 Walkthrough

Walkthrough

The Chromium cookie import path now reads the source browser’s live cookies SQLite database directly instead of copying it to a temporary file. Target partition cookie database discovery resolves Network or legacy cookie paths and creates the database when missing. Decryption key extraction is deferred until encrypted values are detected, with cleanup on failure. Session persistence and tests cover Network paths, WAL databases, encrypted cookies, and staging cleanup.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Unrelated formatting-only edits were added in several Orca profile files that are not needed for the Chromium cookie import fix. Remove or split the unrelated Orca profile formatting changes into a separate cleanup PR.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title concisely describes the main Chromium cookie import fix and matches the primary change set.
Description check ✅ Passed The description includes all required sections and enough testing/security detail, with only minor brevity in the AI review report.
Linked Issues check ✅ Passed The changes directly address #6875 by fixing Chromium cookie import for Network/Cookies paths, WAL handling, and plaintext rows without an OS key.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/browser/browser-cookie-import.ts (1)

1473-1474: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Vestigial tmpDir and misleading tmpCookiesPath name.

With temp snapshotting removed, tmpDir is created but nothing is ever written into it — it's only rmSync'd in the various exit paths (Lines 1512, 1526, 1559, 1573, 1695, 1781), so it's now dead scaffolding. Likewise tmpCookiesPath no longer points at a temp copy; it's the live source path, which obscures the WAL-lock reasoning above. Consider dropping tmpDir (and its cleanup calls) and renaming the variable to reflect the live source path.

♻️ Rename and drop the unused temp dir
-  const tmpDir = mkdtempSync(join(tmpdir(), 'orca-cookie-import-'))
-  const tmpCookiesPath = browser.cookiesPath
+  const sourceCookiesPath = browser.cookiesPath

Then remove the corresponding rmSync(tmpDir, ...) cleanup calls and update new DatabaseSync(tmpCookiesPath, ...) (Line 1536) to use sourceCookiesPath.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ecf1589b-917a-4cbe-ab5f-4ce11e323bfa

📥 Commits

Reviewing files that changed from the base of the PR and between 7e1a777 and 6a4fec2.

📒 Files selected for processing (2)
  • src/main/browser/browser-cookie-import.test.ts
  • src/main/browser/browser-cookie-import.ts

@rodboev rodboev force-pushed the pr/chromium-cookie-import-db-paths branch from 6a4fec2 to 8f49611 Compare July 9, 2026 03:38
@AmethystLiang AmethystLiang requested a review from Jinwoo-H July 9, 2026 16:53
Co-authored-by: Orca <help@stably.ai>

@Jinwoo-H Jinwoo-H left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — reviewed against #6875 and added the remaining maintainer fixes:

  • keep modern Network/Cookies import and restart replay on the same database
  • clean staging data after key-access failures
  • cover live WAL, plaintext, encrypted, cleanup, and legacy fallback paths

Focused tests, full typecheck/lint, and the real Electron import flow pass.

# Conflicts:
#	src/main/browser/browser-session-registry.persistence.test.ts

@Jinwoo-H Jinwoo-H left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approved after merging the current main into the PR branch and re-running the focused tests, full typecheck, and full lint.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 48c9d075-c2c0-42a9-b27d-724c33c7635e

📥 Commits

Reviewing files that changed from the base of the PR and between 8f49611 and d754466.

📒 Files selected for processing (6)
  • src/main/browser/browser-cookie-import-test-database.ts
  • src/main/browser/browser-cookie-import.test.ts
  • src/main/browser/browser-cookie-import.ts
  • src/main/browser/browser-session-registry.persistence.test.ts
  • src/main/browser/browser-session-registry.ts
  • src/main/browser/chromium-cookie-path.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/browser/browser-cookie-import.ts

Comment on lines +74 to +82
export function encryptMacChromiumCookie(value: string, password: string): Buffer {
const key = pbkdf2Sync(password, 'saltysalt', 1003, 16, 'sha1')
const cipher = createCipheriv('aes-128-cbc', key, Buffer.alloc(16, ' '))
return Buffer.concat([
Buffer.from('v10'),
cipher.update(Buffer.from(value, 'latin1')),
cipher.final()
])
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a "Why" comment for Chromium macOS encryption parameters.

The encryptMacChromiumCookie function uses non-obvious, Chromium-specific encryption parameters (PBKDF2 with 'saltysalt'/1003 iterations, AES-128-CBC with a 16-space IV, v10 prefix). Per coding guidelines, code driven by a non-obvious constraint should include a brief comment explaining why.

💡 Suggested comment
 export function encryptMacChromiumCookie(value: string, password: string): Buffer {
+  // Why: Chromium on macOS derives the cookie encryption key via PBKDF2
+  // (salt 'saltysalt', 1003 iterations, SHA1) and encrypts with AES-128-CBC
+  // using a fixed 16-byte IV of spaces, prefixing the ciphertext with 'v10'.
   const key = pbkdf2Sync(password, 'saltysalt', 1003, 16, 'sha1')
   const cipher = createCipheriv('aes-128-cbc', key, Buffer.alloc(16, ' '))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function encryptMacChromiumCookie(value: string, password: string): Buffer {
const key = pbkdf2Sync(password, 'saltysalt', 1003, 16, 'sha1')
const cipher = createCipheriv('aes-128-cbc', key, Buffer.alloc(16, ' '))
return Buffer.concat([
Buffer.from('v10'),
cipher.update(Buffer.from(value, 'latin1')),
cipher.final()
])
}
export function encryptMacChromiumCookie(value: string, password: string): Buffer {
// Why: Chromium on macOS derives the cookie encryption key via PBKDF2
// (salt 'saltysalt', 1003 iterations, SHA1) and encrypts with AES-128-CBC
// using a fixed 16-byte IV of spaces, prefixing the ciphertext with 'v10'.
const key = pbkdf2Sync(password, 'saltysalt', 1003, 16, 'sha1')
const cipher = createCipheriv('aes-128-cbc', key, Buffer.alloc(16, ' '))
return Buffer.concat([
Buffer.from('v10'),
cipher.update(Buffer.from(value, 'latin1')),
cipher.final()
])
}

Source: Coding guidelines

@Jinwoo-H Jinwoo-H left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final re-approval on the conflict-resolved head after PR Checks passed, including tests, unpacked Electron build, and packaged CLI smoke.

@Jinwoo-H Jinwoo-H merged commit 693ac1f into stablyai:main Jul 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Could not copy Google Chrome cookies database

2 participants