Chrome (Windows) 127 - unable to decrypt new v20 ABE (app-bound encryption) cookies - "panic: crypto/cipher: input not full blocks"
Checklist
- [X] I have searched the issue tracker for open issues that relate to the same problem, before opening a new one.
- [X] This issue only relates to a single bug. I will open new issues for any other problems.
Describe the bug
Using this example code, with Windows Chrome 127.0.6533.73.
cookies, err := chrome.ReadCookies(cookiesFile)
I get this panic:
panic: crypto/cipher: input not full blocks
goroutine 1 [running]:
crypto/cipher.(*cbcDecrypter).CryptBlocks(0x659ca0?, {0xc00001a240?, 0xc0000145d0?, 0x10?}, {0xc00001a213?, 0x9?, 0x1?})
/snap/go/10730/src/crypto/cipher/cbc.go:145 +0x40b
github.com/browserutils/kooky/internal/chrome.decryptAESCBC({0xc00001a210, 0x2a, 0x2a}, {0x771724, 0x7, 0x7}, 0x1)
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/internal/chrome/chrome.go:310 +0x194
github.com/browserutils/kooky/internal/chrome.(*CookieStore).decrypt.func3({0xc00001a210?, 0xc000165558?, 0x5f4c95?}, {0x771724?, 0x5af1e0?, 0x4721b2?})
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/internal/chrome/chrome.go:240 +0x25
github.com/browserutils/kooky/internal/chrome.(*CookieStore).decrypt(0xc000136210, {0xc00001a210, 0x2a, 0x2a})
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/internal/chrome/chrome.go:265 +0x8ad
github.com/browserutils/kooky/internal/chrome.(*CookieStore).saveCookieValue(0xc000136210, 0xc0000e2000, {0xc0000b8300?, 0xc0000b6050?})
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/internal/chrome/chrome.go:119 +0x9f
github.com/browserutils/kooky/internal/chrome.(*CookieStore).ReadCookies.func1(0x0?, {0xc0000b8300?, 0xc0000b6050?})
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/internal/chrome/chrome.go:92 +0x494
github.com/browserutils/kooky/internal/utils.VisitTableRows.func1(0xc000014518, {{0x14, {0xc000010500, 0x14, 0x20}}, {0xc00002e1f5, 0x7e, 0x7e}, {0xc0000e0000, 0x14, ...}})
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/internal/utils/visittablerows.go:25 +0x96
github.com/go-sqlite/sqlite3.(*DbFile).VisitTableRecords.(*btreeTable).visitRecordsInorder.func1({0x0, 0xc000014518, {0xc00002e1e0, 0x93, 0x93}, 0x0})
/home/adam/go/pkg/mod/github.com/go-sqlite/[email protected]/btree.go:431 +0x115
github.com/go-sqlite/sqlite3.(*btreeTable).visitRawInorder(0xc0000ac180, 0xc000165a80)
/home/adam/go/pkg/mod/github.com/go-sqlite/[email protected]/btree.go:395 +0x203
github.com/go-sqlite/sqlite3.(*btreeTable).visitRawInorder(0xc0000ac120, 0xc000165a80)
/home/adam/go/pkg/mod/github.com/go-sqlite/[email protected]/btree.go:387 +0x1b6
github.com/go-sqlite/sqlite3.(*btreeTable).visitRecordsInorder(...)
/home/adam/go/pkg/mod/github.com/go-sqlite/[email protected]/btree.go:424
github.com/go-sqlite/sqlite3.(*DbFile).VisitTableRecords(0xc000132b60, {0x5f51bb, 0x7}, 0xc000165ba0)
/home/adam/go/pkg/mod/github.com/go-sqlite/[email protected]/file.go:313 +0x199
github.com/browserutils/kooky/internal/utils.VisitTableRows(0xc000132b60, {0x5f51bb, 0x7}, 0xc000165de8, 0xc000165c90)
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/internal/utils/visittablerows.go:24 +0x367
github.com/browserutils/kooky/internal/chrome.(*CookieStore).ReadCookies(0xc000136210, {0x0, 0x0, 0xc000006101?})
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/internal/chrome/chrome.go:102 +0x448
github.com/browserutils/kooky/browser/chrome.ReadCookies({0x601ca0, 0x37}, {0x0, 0x0, 0x0})
/home/adam/go/pkg/mod/github.com/browserutils/[email protected]/browser/chrome/chrome.go:18 +0x155
How to reproduce
Run code
Example code
package main
import (
"fmt"
"github.com/browserutils/kooky/browser/chrome"
)
func main() {
cookiesFile := "[path to cookies file]"
cookies, err := chrome.ReadCookies(cookiesFile)
if err != nil {
// TODO: handle the error
fmt.Println(err)
return
}
for _, cookie := range cookies {
fmt.Println(cookie)
}
}```
### Kooky version
v0.2.2
### Go compiler version
go1.23.2 linux/amd64
### Browser
Chrome 127.0.6533.73
### Operating system and version
WSL/Windows 10
I'm getting the same. Anyone have ideas?
Because chrome introduce Application-Bound (App-Bound) encryption since 127. Reference: https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html
For windows, could disable the feature via registry key Software\Policies\Google\Chrome\ApplicationBoundEncryptionEnabled.
Don't know how to disable the feature for macOS chrome.
Because chrome introduce Application-Bound (App-Bound) encryption since 127. Reference: https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html ... Don't know how to disable the feature for macOS chrome.
I don't think it has to be disabled necessarily. IIUC it seems like the encryption key is derived from the user's login password + a passphrase stored in the Mac keyring. See https://github.com/kawakatz/macCookies/blob/e97ccea49b4d816862cf8a7ac67b075eb56fab2e/pkg/decrypt/decrypt.go#L84-L90
I encountered this issue in regular (non-wsl) linux (ubuntu 22).
It only affects certain sites/cookies, which trigger the inputs not full blocks panic.
I tried to debug it a bit, and it appears to be an issue with the sqlite code extracting the encrypted_value of the cookies:
The encrypted_value in the sqlite cookies DB is way longer than the value kookys tries to decrypt. When logging the received encrypted_value ( 76313176fc3d3e3b93201d910c6e454f816a47bd739729af5e) in chrome_linux.go right before decryption in L.240 it had 49 chars (25 byte), but the value in my DB (76313176FC3D3E3B93201D910C6E454F816A47BD739729AF5E002D3B0759F75468BAB3ED7FB4000D0EA707A22041CA5848A04F28E901C1D60B2AD50646130994966108882496C9A0C43A3728285BEF9C4F8E6E9B3946E9AB9C61A566ABB2782F03703CC919A6446685826D2BDBF17EDC39D7A8 is 230 char (115 byte). As you can see the value logged by kooky matches the first part of the actual value in the DB.
I also double checked for e.g. issue with my cookies DB using the browser_cookie3 python library, and it extracted the full encrypted_value and decrypted it successfully.
(All testing done on the v0.2.2 release, the padding changes fixed last year don't affect this issue, since they only result in the decrypted value having useless padding, and don't affect the decryption itself.)
I wonder if there's some kind of way of encoding longer values in sqlite that Kooky doesn't understand?
Appears like it might be some type interference going wrong, the column encrypted_value is an interface {}(string) when it panics, and otherwise an interface {}([]uint8) i.e. byte, which I believe is the correct one.
Domain where kooky works
- value is
interface {}([]uint8) [118,49,49,231,237,178,220,39,119,118,114,156,35,21,206,9,255,74,167,253,170,134,130,230,23,207,168,45,251,145,242,117,248,51,240,216,169,145,169,121,122,103,1,197,155,168,114,93,248,222,0,147,21,73,207,233,56,135,191,172,212,112,58,39,...+115 more]
Domain where kooky does not work
- value is
interface {}(string) "v11v\xfc=>;\x93 \x1d\x91\fnEO\x81jG\xbds\x97)\xaf^"
Since the used sqlite library didnt get any update since 2018 there might be something that changed in this 7 years. No issue with firefox though.
Hi @What-is-water93, that changing slice type should be from here: https://github.com/go-sqlite/sqlite3/blob/304649c/btree.go#L141-L204
I have turned this specific panic into an error (00fc21c) as it often happened with chrome changes etc. Now one erroneous cookie won't break the retrieval of many. The bug itself needs fixing too naturally.
This error happens because Chrome changed the way they encrypt and decrypt cookies on OSX. They now use: AES-256-GCM not the older AES-128-CBC with PBKDF2 ("saltysalt"). There was a pull request I spotted a few months ago that mentioned it too (can't find it).
I found this out because I was rolling out my own cookie decryptor in Free Pascal, and the old libs I wrote stopped working on OSX. So rather than reinvent the wheel I tried out kooky and it suffers the same problem.
I've checked the source, and it appears kooky is using the old method of encryption/decryption: https://github.com/browserutils/kooky/blob/v0.2.4/internal/chrome/chrome.go#L325-L340
The new way Chrome handles encryption and decryption is with AES-256-GCM. You can see this in the source code here: https://github.com/chromium/chromium/blob/a5ad0606f64f1081683d4f78b37bf94aa8fc95a5/components/os_crypt/async/common/encryptor.cc
There's nothing official mentioned about this change.
I could probably work on this since I'm going to use Go for my current project anyway, and I need this.