Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Unified Diff: content/browser/net/sqlite_persistent_cookie_store.cc

Issue 24734007: Encrypt all stored cookies on selected operating systems. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/DEPS ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/net/sqlite_persistent_cookie_store.cc
diff --git a/content/browser/net/sqlite_persistent_cookie_store.cc b/content/browser/net/sqlite_persistent_cookie_store.cc
index 517a8c18a1646d10af600c125a9e1b00d754d606..45879dcd78219d1c68b7747fe5faa6bdad6ea54a 100644
--- a/content/browser/net/sqlite_persistent_cookie_store.cc
+++ b/content/browser/net/sqlite_persistent_cookie_store.cc
@@ -26,6 +26,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/time/time.h"
+#include "components/webdata/encryptor/encryptor.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cookie_store_factory.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -277,6 +278,9 @@ namespace {
// Version number of the database.
//
+// Version 7 adds encrypted values. Old values will continue to be used but
+// all new values written will be encrypted on selected operating systems.
+//
// Version 6 adds cookie priorities. This allows developers to influence the
// order in which cookies are evicted in order to meet domain cookie limits.
//
@@ -293,7 +297,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 = 6;
+const int kCurrentVersionNumber = 7;
const int kCompatibleVersionNumber = 5;
// Possible values for the 'priority' column.
@@ -363,6 +367,7 @@ bool InitTable(sql::Connection* db) {
"host_key TEXT NOT NULL,"
"name TEXT NOT NULL,"
"value TEXT NOT NULL,"
+ "encrypted_value BLOB NOT NULL,"
Scott Hess - ex-Googler 2013/09/27 23:07:12 Put the encrypted_value at the end so that the cre
bcwhite 2013/09/30 15:04:29 Done.
"path TEXT NOT NULL,"
"expires_utc INTEGER NOT NULL,"
"secure INTEGER NOT NULL,"
@@ -679,15 +684,16 @@ bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
if (restore_old_session_cookies_) {
smt.Assign(db_->GetCachedStatement(
SQL_FROM_HERE,
- "SELECT creation_utc, host_key, name, value, path, expires_utc, "
- "secure, httponly, last_access_utc, has_expires, persistent, priority "
- "FROM cookies WHERE host_key = ?"));
+ "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 = ?"));
} else {
smt.Assign(db_->GetCachedStatement(
SQL_FROM_HERE,
- "SELECT creation_utc, host_key, name, value, path, expires_utc, "
- "secure, httponly, last_access_utc, has_expires, persistent, priority "
- "FROM cookies WHERE host_key = ? AND persistent = 1"));
+ "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 = ? "
+ "AND persistent = 1"));
}
if (!smt.is_valid()) {
smt.Clear(); // Disconnect smt_ref from db_.
@@ -701,20 +707,24 @@ bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
for (; it != domains.end(); ++it) {
smt.BindString(0, *it);
while (smt.Step()) {
+ std::string value = smt.ColumnString(3);
erikwright (departed) 2013/10/07 20:39:25 I suppose it's possible that there's a hit for rea
bcwhite 2013/10/08 16:10:25 Done.
Scott Hess - ex-Googler 2013/10/08 17:11:53 The big hit is I/O, and how SQLite stores things m
bcwhite 2013/10/08 18:23:36 So... Yes or no? Personally I prefer the previou
Scott Hess - ex-Googler 2013/10/08 19:13:51 I don't care either way, so defer to Erik.
+ std::string encrypted_value = smt.ColumnString(4);
+ if (!encrypted_value.empty())
+ Encryptor::DecryptString(encrypted_value, &value);
scoped_ptr<net::CanonicalCookie> cc(new net::CanonicalCookie(
// The "source" URL is not used with persisted cookies.
GURL(), // Source
smt.ColumnString(2), // name
- smt.ColumnString(3), // value
+ value, // value
smt.ColumnString(1), // domain
- smt.ColumnString(4), // path
+ smt.ColumnString(5), // path
Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc
- Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc
- Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc
- smt.ColumnInt(6) != 0, // secure
- smt.ColumnInt(7) != 0, // httponly
+ 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
DBCookiePriorityToCookiePriority(
- static_cast<DBCookiePriority>(smt.ColumnInt(11))))); // priority
+ static_cast<DBCookiePriority>(smt.ColumnInt(12))))); // priority
DLOG_IF(WARNING,
cc->CreationDate() > Time::Now()) << L"CreationDate too recent";
cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++;
@@ -837,6 +847,27 @@ bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() {
base::TimeTicks::Now() - start_time);
}
+ if (cur_version == 6) {
+ const base::TimeTicks start_time = base::TimeTicks::Now();
+ sql::Transaction transaction(db_.get());
+ if (!transaction.Begin())
+ return false;
+ // Alter the table to add empty "encrypted value" column.
+ std::string stmt(base::StringPrintf(
+ "ALTER TABLE cookies ADD COLUMN encrypted_value BLOB DEFAULT ''"));
+ if (!db_->Execute(stmt.c_str())) {
+ LOG(WARNING) << "Unable to update cookie database to version 7.";
+ return false;
+ }
+ ++cur_version;
+ meta_table_.SetVersionNumber(cur_version);
+ meta_table_.SetCompatibleVersionNumber(
+ std::min(cur_version, kCompatibleVersionNumber));
+ transaction.Commit();
+ UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV7",
+ base::TimeTicks::Now() - start_time);
+ }
+
// Put future migration cases here.
if (cur_version < kCurrentVersionNumber) {
@@ -921,10 +952,10 @@ void SQLitePersistentCookieStore::Backend::Commit() {
return;
sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE,
- "INSERT INTO cookies (creation_utc, host_key, name, value, path, "
- "expires_utc, secure, httponly, last_access_utc, has_expires, "
- "persistent, priority) "
- "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"));
+ "INSERT INTO cookies (creation_utc, host_key, name, value, "
+ "encrypted_value, path, expires_utc, secure, httponly, last_access_utc, "
+ "has_expires, persistent, priority) "
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
if (!add_smt.is_valid())
return;
@@ -942,28 +973,38 @@ void SQLitePersistentCookieStore::Backend::Commit() {
if (!transaction.Begin())
return;
+ std::string value, encrypted_value; // Only one will ever get a value below.
Scott Hess - ex-Googler 2013/09/27 23:07:12 I would put this inside the loop. Since the code
bcwhite 2013/09/30 15:04:29 Sure. I was trying to avoid re-constructing the o
for (PendingOperationsList::iterator it = ops.begin();
it != ops.end(); ++it) {
// Free the cookies as we commit them to the database.
scoped_ptr<PendingOperation> po(*it);
switch (po->op()) {
case PendingOperation::COOKIE_ADD:
+ // On operating systems that support an encryption API but don't
+ // automatically protect all user data, encrypt the cookie.
+#if defined(OS_WIN) || defined(OS_MACOSX)
+ Encryptor::EncryptString(po->cc().Value(), &encrypted_value);
+#else
+ value = po->cc().Value();
+#endif
cookies_per_origin_[
CookieOrigin(po->cc().Domain(), po->cc().IsSecure())]++;
add_smt.Reset(true);
add_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue());
add_smt.BindString(1, po->cc().Domain());
add_smt.BindString(2, po->cc().Name());
- add_smt.BindString(3, po->cc().Value());
- add_smt.BindString(4, po->cc().Path());
- add_smt.BindInt64(5, po->cc().ExpiryDate().ToInternalValue());
- add_smt.BindInt(6, po->cc().IsSecure());
- add_smt.BindInt(7, po->cc().IsHttpOnly());
- add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue());
- add_smt.BindInt(9, po->cc().IsPersistent());
+ add_smt.BindString(3, value);
+ add_smt.BindBlob(4, encrypted_value.data(),
+ static_cast<int>(encrypted_value.length()));
+ add_smt.BindString(5, po->cc().Path());
+ 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(11, po->cc().IsPersistent());
add_smt.BindInt(
- 11, CookiePriorityToDBCookiePriority(po->cc().Priority()));
+ 12, CookiePriorityToDBCookiePriority(po->cc().Priority()));
if (!add_smt.Run())
NOTREACHED() << "Could not add a cookie to the DB.";
break;
« no previous file with comments | « content/browser/DEPS ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698