diff options
author | mkwst <mkwst@chromium.org> | 2015-02-22 21:10:31 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-23 05:11:25 +0000 |
commit | ae819bb3096b63a11b8c1ff47dd3b69f85ea241b (patch) | |
tree | ec97dfaf204412c66e4246c597fe00cbdf64083e /content/browser/net/sqlite_persistent_cookie_store.cc | |
parent | d726d218c92888278509ef9b4a9e639cf9fce659 (diff) | |
download | chromium_src-ae819bb3096b63a11b8c1ff47dd3b69f85ea241b.zip chromium_src-ae819bb3096b63a11b8c1ff47dd3b69f85ea241b.tar.gz chromium_src-ae819bb3096b63a11b8c1ff47dd3b69f85ea241b.tar.bz2 |
Implement the "First-Party-Only" cookie attribute.
First-party-only cookies allow servers to mitigate the risk of cross-site
request forgery and related information leakage attacks by asserting that a
particular cookie should only be sent in a "first-party" context.
This patch adds support for the 'First-Party-Only' attribute to the
CookieMonster and CookieStore, but does not yet wire up requests such that
the flag has any effect. https://codereview.chromium.org/940373002 will do so
by correctly setting the first-party URL on the CookieOptions object used to
load cookies for a request.
Spec: https://tools.ietf.org/html/draft-west-first-party-cookies
Intent to Implement: https://groups.google.com/a/chromium.org/d/msg/blink-dev/vT98riFhhT0/3Q-lADqsh0UJ
BUG=459154
TBR=dpolukhin@chromium.org
Review URL: https://codereview.chromium.org/876973003
Cr-Commit-Position: refs/heads/master@{#317544}
Diffstat (limited to 'content/browser/net/sqlite_persistent_cookie_store.cc')
-rw-r--r-- | content/browser/net/sqlite_persistent_cookie_store.cc | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/content/browser/net/sqlite_persistent_cookie_store.cc b/content/browser/net/sqlite_persistent_cookie_store.cc index cb2f98e..75c89fd 100644 --- a/content/browser/net/sqlite_persistent_cookie_store.cc +++ b/content/browser/net/sqlite_persistent_cookie_store.cc @@ -310,6 +310,8 @@ namespace { // Version number of the database. // +// Version 8 adds "first-party only" cookies. +// // Version 7 adds encrypted values. Old values will continue to be used but // all new values written will be encrypted on selected operating systems. New // records read by old clients will simply get an empty cookie value while old @@ -333,7 +335,7 @@ namespace { // Version 3 updated the database to include the last access time, so we can // expire them in decreasing order of use when we've reached the maximum // number of cookies. -const int kCurrentVersionNumber = 7; +const int kCurrentVersionNumber = 8; const int kCompatibleVersionNumber = 5; // Possible values for the 'priority' column. @@ -399,19 +401,20 @@ bool InitTable(sql::Connection* db) { if (!db->DoesTableExist("cookies")) { std::string stmt(base::StringPrintf( "CREATE TABLE cookies (" - "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," - "host_key TEXT NOT NULL," - "name TEXT NOT NULL," - "value TEXT NOT NULL," - "path TEXT NOT NULL," - "expires_utc INTEGER NOT NULL," - "secure INTEGER NOT NULL," - "httponly INTEGER NOT NULL," - "last_access_utc INTEGER NOT NULL, " - "has_expires INTEGER NOT NULL DEFAULT 1, " - "persistent INTEGER NOT NULL DEFAULT 1," - "priority INTEGER NOT NULL DEFAULT %d," - "encrypted_value BLOB DEFAULT '')", + "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," + "host_key TEXT NOT NULL," + "name TEXT NOT NULL," + "value TEXT NOT NULL," + "path TEXT NOT NULL," + "expires_utc INTEGER NOT NULL," + "secure INTEGER NOT NULL," + "httponly INTEGER NOT NULL," + "last_access_utc INTEGER NOT NULL, " + "has_expires INTEGER NOT NULL DEFAULT 1, " + "persistent INTEGER NOT NULL DEFAULT 1," + "priority INTEGER NOT NULL DEFAULT %d," + "encrypted_value BLOB DEFAULT ''," + "firstpartyonly INTEGER NOT NULL DEFAULT 0)", CookiePriorityToDBCookiePriority(net::COOKIE_PRIORITY_DEFAULT))); if (!db->Execute(stmt.c_str())) return false; @@ -723,14 +726,14 @@ bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( smt.Assign(db_->GetCachedStatement( SQL_FROM_HERE, "SELECT creation_utc, host_key, name, value, encrypted_value, path, " - "expires_utc, secure, httponly, last_access_utc, has_expires, " - "persistent, priority FROM cookies WHERE host_key = ?")); + "expires_utc, secure, httponly, firstpartyonly, last_access_utc, " + "has_expires, persistent, priority FROM cookies WHERE host_key = ?")); } else { smt.Assign(db_->GetCachedStatement( SQL_FROM_HERE, "SELECT creation_utc, host_key, name, value, encrypted_value, path, " - "expires_utc, secure, httponly, last_access_utc, has_expires, " - "persistent, priority FROM cookies WHERE host_key = ? " + "expires_utc, secure, httponly, firstpartyonly, last_access_utc, " + "has_expires, persistent, priority FROM cookies WHERE host_key = ? " "AND persistent = 1")); } if (!smt.is_valid()) { @@ -769,18 +772,19 @@ void SQLitePersistentCookieStore::Backend::MakeCookiesFromSQLStatement( } scoped_ptr<net::CanonicalCookie> cc(new net::CanonicalCookie( // The "source" URL is not used with persisted cookies. - GURL(), // Source - smt.ColumnString(2), // name - value, // value - smt.ColumnString(1), // domain - smt.ColumnString(5), // path - Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc - Time::FromInternalValue(smt.ColumnInt64(6)), // expires_utc - Time::FromInternalValue(smt.ColumnInt64(9)), // last_access_utc - smt.ColumnInt(7) != 0, // secure - smt.ColumnInt(8) != 0, // httponly + GURL(), // Source + smt.ColumnString(2), // name + value, // value + smt.ColumnString(1), // domain + smt.ColumnString(5), // path + Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc + Time::FromInternalValue(smt.ColumnInt64(6)), // expires_utc + Time::FromInternalValue(smt.ColumnInt64(10)), // last_access_utc + smt.ColumnInt(7) != 0, // secure + smt.ColumnInt(8) != 0, // httponly + smt.ColumnInt(9) != 0, // firstpartyonly DBCookiePriorityToCookiePriority( - static_cast<DBCookiePriority>(smt.ColumnInt(12))))); // priority + static_cast<DBCookiePriority>(smt.ColumnInt(13))))); // priority DLOG_IF(WARNING, cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++; @@ -916,6 +920,27 @@ bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() { base::TimeTicks::Now() - start_time); } + if (cur_version == 7) { + const base::TimeTicks start_time = base::TimeTicks::Now(); + sql::Transaction transaction(db_.get()); + if (!transaction.Begin()) + return false; + // Alter the table to add a 'firstpartyonly' column. + if (!db_->Execute( + "ALTER TABLE cookies " + "ADD COLUMN firstpartyonly INTEGER DEFAULT 0")) { + LOG(WARNING) << "Unable to update cookie database to version 8."; + return false; + } + ++cur_version; + meta_table_.SetVersionNumber(cur_version); + meta_table_.SetCompatibleVersionNumber( + std::min(cur_version, kCompatibleVersionNumber)); + transaction.Commit(); + UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV8", + base::TimeTicks::Now() - start_time); + } + // Put future migration cases here. if (cur_version < kCurrentVersionNumber) { @@ -999,11 +1024,12 @@ void SQLitePersistentCookieStore::Backend::Commit() { if (!db_.get() || ops.empty()) return; - sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, + sql::Statement add_smt(db_->GetCachedStatement( + SQL_FROM_HERE, "INSERT INTO cookies (creation_utc, host_key, name, value, " - "encrypted_value, path, expires_utc, secure, httponly, last_access_utc, " - "has_expires, persistent, priority) " - "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)")); + "encrypted_value, path, expires_utc, secure, httponly, firstpartyonly, " + "last_access_utc, has_expires, persistent, priority) " + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)")); if (!add_smt.is_valid()) return; @@ -1048,11 +1074,12 @@ void SQLitePersistentCookieStore::Backend::Commit() { add_smt.BindInt64(6, po->cc().ExpiryDate().ToInternalValue()); add_smt.BindInt(7, po->cc().IsSecure()); add_smt.BindInt(8, po->cc().IsHttpOnly()); - add_smt.BindInt64(9, po->cc().LastAccessDate().ToInternalValue()); - add_smt.BindInt(10, po->cc().IsPersistent()); + add_smt.BindInt(9, po->cc().IsFirstPartyOnly()); + add_smt.BindInt64(10, po->cc().LastAccessDate().ToInternalValue()); add_smt.BindInt(11, po->cc().IsPersistent()); - add_smt.BindInt( - 12, CookiePriorityToDBCookiePriority(po->cc().Priority())); + add_smt.BindInt(12, po->cc().IsPersistent()); + add_smt.BindInt(13, + CookiePriorityToDBCookiePriority(po->cc().Priority())); if (!add_smt.Run()) NOTREACHED() << "Could not add a cookie to the DB."; break; |