browserutils / kooky

Go code to read cookies from browser cookie stores.
MIT License
204 stars 41 forks source link

Handle Chrome SQLite rows that are missing unused values #42

Closed barnardb closed 3 years ago

barnardb commented 3 years ago

On one of my machines, the Chrome SQLite cookie database has the following definition for the cookies table:

CREATE TABLE cookies (
    creation_utc INTEGER NOT NULL,
    host_key TEXT NOT NULL,
    name TEXT NOT NULL,
    value TEXT NOT NULL,
    path TEXT NOT NULL,
    expires_utc INTEGER NOT NULL,
    is_secure INTEGER NOT NULL,
    is_httponly INTEGER NOT NULL,
    last_access_utc INTEGER NOT NULL,
    has_expires INTEGER NOT NULL DEFAULT 1,
    is_persistent INTEGER NOT NULL DEFAULT 1,
    priority INTEGER NOT NULL DEFAULT 1,
    encrypted_value BLOB DEFAULT ‘’,
    samesite INTEGER NOT NULL DEFAULT -1,
    source_scheme INTEGER NOT NULL DEFAULT 0,
    source_port INTEGER NOT NULL DEFAULT -1,
    is_same_party INTEGER NOT NULL DEFAULT 0,
    UNIQUE (host_key, name, path)
)

The table has 17 columns, and kookie was failing when trying to parse a row with only 15 columns.

According to §2.1 Record Format of the SQLite Database File Format documentation,

A record might have fewer values than the number of columns in the corresponding table. This can happen, for example, after an ALTER TABLE ... ADD COLUMN SQL statement has increased the number of columns in the table schema without modifying preexisting rows in the table. Missing values at the end of the record are filled in using the default value for the corresponding columns defined in the table schema.

So it is not inherently problematic for a row to have fewer values than the table has columns. Unfortunately, go-sqlite/sqlite3 doesn't currently seem to support default values. Fortunately, in my case the missing values are not ones that kooky actually uses. We can improve the check that kooky performs to only insist that it has at least as many values to be able to all of the values that it is actually interested in. That is what this PR does.

I have not added a test for this case as I don't want to share the actual cookie database, and I don't have a lot of SQLite know-how.