Roger
00ad0e0bd4
feat: add output package with Formatter interface ( #537 )
...
* docs: add RFC-004 for CLI (cobra) and output design
* feat: add output package with Formatter interface and BrowserData.Each
* fix: golangci config array syntax + add output package tests
* refactor: encapsulated Output as Writer, collect-then-write pattern
* refactor: unified row type with reflection-based CSV/JSON output
* fix: ProfileName empty guard, writeFile close error check, sync RFC-004
2026-04-04 01:41:02 +08:00
Roger
1a3aea553e
feat: add Firefox Browser with new v2 architecture ( #536 )
...
* feat: add Firefox Browser implementation with new v2 architecture
Add Firefox NewBrowsers + Extract pipeline following the Chromium v2
pattern. Firefox-specific differences handled:
- Profile discovery: random directory names (e.g. abc123.default-release)
- Master key: NSS/ASN1PBE from key4.db (platform-agnostic, no DPAPI/Keychain)
- Key validation: reuse logins.json from acquireFiles tempPaths
- Extract: only Password needs masterKey; Cookie is plaintext
- No CreditCard or SessionStorage support
Files:
- firefox_new.go: Browser struct, NewBrowsers, Extract, getMasterKey,
extractCategory, deriveKeys, validateKeyWithLogins, profile discovery
- masterkey.go: extracted shared NSS logic (processMasterKey, queryMetaData,
queryNssPrivateCandidates, parseLoginCipherPairs, canDecryptAnyLoginCipherPair)
- firefox_new_test.go: table-driven tests with shared fixtures
- source.go: remove dataSource wrapper, use []sourcePath directly
- firefox.go: remove functions moved to masterkey.go
* fix: address Copilot review feedback on Firefox v2
- Fix stale comment referencing removed readLoginCipherPairs
- Rename finallyKey to derivedKey for clarity in processMasterKey
- Add sqlite driver import to masterkey.go for self-containedness
* refactor: rewrite Firefox masterkey and improve naming
Masterkey rewrite:
- Replace raw SQL functions with structured key4DB type (globalSalt,
passwordCheck, privateKeys) for clear data modeling
- Split processMasterKey into verifyPasswordCheck + decryptPrivateKey
- Add nssKeyTypeTag constant for the magic bytes
- Rename finallyKey to derivedKey
- Add sqlite driver import for self-containedness
- Return error (not fallback) when logins validation explicitly fails
Naming cleanup:
- loginPair → encryptedLogin (clarify these are encrypted blobs)
- parseLoginPairs → sampleEncryptedLogins (clarify sampling purpose)
- canDecryptLogin → tryDecryptLogins (accurate verb, plural alignment)
- Expand abbreviated variables: p→login, uPBE→userPBE, pPBE→pwdPBE
Password extraction:
- Keep entries when decryptPBE fails (URL preserved, user/pwd empty)
- Align with Chromium behavior where decrypt failure doesn't skip records
Old code cleanup:
- firefox.go GetMasterKey now delegates to retrieveMasterKey
- Remove functions moved to masterkey.go
* docs: add RFC-003 for crypto package naming cleanup
Track accumulated naming and structural issues in crypto/asn1pbe.go
and cross-browser shared code for a future dedicated refactoring pass.
* refactor: move masterkey tests to masterkey_test.go
- Rename firefox_test.go to masterkey_test.go since all tests in
this file test masterkey.go functions (readKey4DB, sampleEncryptedLogins)
- Fix TestReadKey4DB to check nssPrivate rows as a set instead of
assuming SQLite insertion order
- Future deletion of firefox.go won't accidentally remove masterkey tests
2026-04-04 01:41:02 +08:00
Roger
e86e3e62d6
feat: add browserdata/datautil helpers ( #513 )
...
* feat: add browserdata/datautil helpers (QuerySQLite, QueryRows, DecryptChromiumValue)
Phase 2 of architecture refactoring (RFC-002 Section 3):
- datautil/sqlite.go: QuerySQLite() — shared SQLite open/query/scan helper
with optional journal_mode=off for Firefox databases
- datautil/query.go: QueryRows[T]() — generic helper (Go 1.20) that wraps
QuerySQLite and collects results into a typed slice
- datautil/decrypt.go: DecryptChromiumValue() — unified Chromium decryption
(DPAPI first, then AES-GCM/CBC fallback)
- datautil/sqlite_test.go: tests for all helpers
* refactor: move DecryptChromiumValue from datautil to browser/chromium
- Remove browserdata/datautil/decrypt.go (Chromium-specific, not a generic util)
- Will be added as browser/chromium/decrypt.go (unexported decryptValue)
in the chromium extract methods PR
- Update RFCs to reflect the change
- Remove decrypt test from datautil tests
* refactor: move datautil to utils/sqliteutil for consistency
- Rename browserdata/datautil/ → utils/sqliteutil/
- Aligns with existing utils/ convention (fileutil, typeutil, byteutil)
- QuerySQLite/QueryRows are generic SQLite helpers, not browserdata-specific
- Update package name from datautil to sqliteutil
- Update both RFCs to reflect new location
* fix: apply review suggestions for sqliteutil
- QuerySQLite: validate dbPath exists before sql.Open to prevent
silently creating empty databases
- Tests: check db.Close() errors with require.NoError
2026-04-04 01:41:01 +08:00
Roger
9959c0839a
docs: add architecture refactoring RFCs and switch gitignore to whitelist ( #510 )
...
* docs: add architecture refactoring RFCs and switch gitignore to whitelist
- Rename rfc/ to rfcs/
- RFC-001: overall architecture redesign (data models, crypto layer,
browser registration, CLI separation, error handling)
- RFC-002: data extraction and file acquisition refactoring
- Replace .gitignore blacklist (212 lines) with precise whitelist (43 lines)
to prevent accidental commit of sensitive browser data files
* feat: update architecture refactoring documentation
- Refactor the architecture to improve scalability and maintainability
- Streamline browser data and file acquisition processes for efficiency
* docs(rfcs): add extract_* naming convention and queryRows[T] helper
- RFC-001: add file naming convention section explaining extract_* prefix
grouping, add datautil/query.go for queryRows[T] generic helper
- RFC-002: update all extract examples to use datautil.QueryRows[T],
add Section 3.2 with queryRows[T] definition
* feat: update architecture refactoring documentation
- RFC-001: rename BrowserConfig→Config, BrowsingData→Extract,
add public/private visibility table, add isValidBrowserDir
in PickBrowsers, remove storage from Chromium struct,
NewChain returns KeyRetriever interface, add error wrapping
convention, unexport PBKDF2 params, flatten log/level
- RFC-002: replace outPutter with writeFile/writeJSON/writeCSV,
remove golang.org/x/text dependency (3-byte BOM), add Windows
locked file handling (copyLocked), fix discoverDataFiles to
check file vs dir type, Firefox New() takes profileDir only,
add decryptPBE helper, add error handling section, add
profile discovery with tests, add platform config example
2026-03-23 01:07:56 +08:00