Add option to enable/disable net security expiration (issue #1994)

- Net security (CT, HSTS) expiration based on build age is now
  disabled by default.
- Add new enable_net_security_expiration option to CefSettings and
  CefRequestContextSettings.
This commit is contained in:
Marshall Greenblatt 2016-11-18 16:11:38 -05:00
parent 2b5c3a7185
commit 8c4ba9f2d8
8 changed files with 158 additions and 4 deletions

View File

@ -376,6 +376,19 @@ typedef struct _cef_settings_t {
///
int ignore_certificate_errors;
///
// Set to true (1) to enable date-based expiration of built in network
// security information (i.e. certificate transparency logs, HSTS preloading
// and pinning information). Enabling this option improves network security
// but may cause HTTPS load failures when using CEF binaries built more than
// 10 weeks in the past. See https://www.certificate-transparency.org/ and
// https://www.chromium.org/hsts for details. Also configurable using the
// "enable-net-security-expiration" command-line switch. Can be overridden for
// individual CefRequestContext instances via the
// CefRequestContextSettings.enable_net_security_expiration value.
///
int enable_net_security_expiration;
///
// Opaque background color used for accelerated content. By default the
// background color will be white. Only the RGB compontents of the specified
@ -443,6 +456,17 @@ typedef struct _cef_request_context_settings_t {
///
int ignore_certificate_errors;
///
// Set to true (1) to enable date-based expiration of built in network
// security information (i.e. certificate transparency logs, HSTS preloading
// and pinning information). Enabling this option improves network security
// but may cause HTTPS load failures when using CEF binaries built more than
// 10 weeks in the past. See https://www.certificate-transparency.org/ and
// https://www.chromium.org/hsts for details. Can be set globally using the
// CefSettings.enable_net_security_expiration value.
///
int enable_net_security_expiration;
///
// Comma delimited ordered list of language codes without any whitespace that
// will be used in the "Accept-Language" HTTP header. Can be set globally

View File

@ -607,6 +607,8 @@ struct CefSettingsTraits {
target->uncaught_exception_stack_size = src->uncaught_exception_stack_size;
target->context_safety_implementation = src->context_safety_implementation;
target->ignore_certificate_errors = src->ignore_certificate_errors;
target->enable_net_security_expiration =
src->enable_net_security_expiration;
target->background_color = src->background_color;
cef_string_set(src->accept_language_list.str,
@ -639,6 +641,8 @@ struct CefRequestContextSettingsTraits {
target->persist_session_cookies = src->persist_session_cookies;
target->persist_user_preferences = src->persist_user_preferences;
target->ignore_certificate_errors = src->ignore_certificate_errors;
target->enable_net_security_expiration =
src->enable_net_security_expiration;
cef_string_set(src->accept_language_list.str,
src->accept_language_list.length, &target->accept_language_list, copy);
}

View File

@ -372,6 +372,9 @@ void CefContext::PopulateRequestContextSettings(
settings->ignore_certificate_errors =
settings_.ignore_certificate_errors ||
command_line->HasSwitch(switches::kIgnoreCertificateErrors);
settings->enable_net_security_expiration =
settings_.enable_net_security_expiration ||
command_line->HasSwitch(switches::kEnableNetSecurityExpiration);
CefString(&settings->accept_language_list) =
CefString(&settings_.accept_language_list);
}

View File

@ -209,8 +209,12 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
storage_->set_host_resolver(net::HostResolver::CreateDefaultResolver(NULL));
storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
storage_->set_transport_security_state(
base::WrapUnique(new net::TransportSecurityState));
std::unique_ptr<net::TransportSecurityState> transport_security_state(
new net::TransportSecurityState);
transport_security_state->set_enforce_net_security_expiration(
settings_.enable_net_security_expiration ? true : false);
storage_->set_transport_security_state(std::move(transport_security_state));
std::vector<scoped_refptr<const net::CTLogVerifier>> ct_logs(
net::ct::CreateLogVerifiersForKnownLogs());
@ -219,8 +223,11 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
ct_verifier->AddLogs(ct_logs);
storage_->set_cert_transparency_verifier(std::move(ct_verifier));
storage_->set_ct_policy_enforcer(
base::WrapUnique(new net::CTPolicyEnforcer));
std::unique_ptr<net::CTPolicyEnforcer> ct_policy_enforcer(
new net::CTPolicyEnforcer);
ct_policy_enforcer->set_enforce_net_security_expiration(
settings_.enable_net_security_expiration ? true : false);
storage_->set_ct_policy_enforcer(std::move(ct_policy_enforcer));
std::unique_ptr<net::ProxyService> system_proxy_service =
ProxyServiceFactory::CreateProxyService(

View File

@ -122,4 +122,7 @@ const char kPluginPolicy_Block[] = "block";
// Expose preferences used only by unit tests.
const char kEnablePreferenceTesting[] = "enable-preference-testing";
// Enable date-based expiration of built in network security information.
const char kEnableNetSecurityExpiration[] = "enable-net-security-expiration";
} // namespace switches

View File

@ -51,6 +51,7 @@ extern const char kPluginPolicy_Allow[];
extern const char kPluginPolicy_Detect[];
extern const char kPluginPolicy_Block[];
extern const char kEnablePreferenceTesting[];
extern const char kEnableNetSecurityExpiration[];
} // namespace switches

View File

@ -304,4 +304,10 @@ patches = [
'name': 'webkit_eventhandler_2288083002',
'path': '../',
},
{
# Support an option to enable/disable net security expiration.
# https://bitbucket.org/chromiumembedded/cef/issues/1994
'name': 'net_security_expiration_1994',
'path': '../',
},
]

View File

@ -0,0 +1,106 @@
diff --git net/cert/ct_policy_enforcer.cc net/cert/ct_policy_enforcer.cc
index a4e1e81..f3c627d 100644
--- net/cert/ct_policy_enforcer.cc
+++ net/cert/ct_policy_enforcer.cc
@@ -33,15 +33,6 @@ namespace net {
namespace {
-// Returns true if the current build is recent enough to ensure that
-// built-in security information (e.g. CT Logs) is fresh enough.
-// TODO(eranm): Move to base or net/base
-bool IsBuildTimely() {
- const base::Time build_time = base::GetBuildTime();
- // We consider built-in information to be timely for 10 weeks.
- return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
-}
-
// Returns a rounded-down months difference of |start| and |end|,
// together with an indication of whether the last month was
// a full month, because the range starts specified in the policy
@@ -455,4 +446,13 @@ ct::EVPolicyCompliance CTPolicyEnforcer::DoesConformToCTEVPolicy(
return details.status;
}
+bool CTPolicyEnforcer::IsBuildTimely() const {
+ if (!enforce_net_security_expiration_)
+ return true;
+
+ const base::Time build_time = base::GetBuildTime();
+ // We consider built-in information to be timely for 10 weeks.
+ return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
+}
+
} // namespace net
diff --git net/cert/ct_policy_enforcer.h net/cert/ct_policy_enforcer.h
index c49e091..d3edffa 100644
--- net/cert/ct_policy_enforcer.h
+++ net/cert/ct_policy_enforcer.h
@@ -100,6 +100,17 @@ class NET_EXPORT CTPolicyEnforcer {
const ct::EVCertsWhitelist* ev_whitelist,
const SCTList& verified_scts,
const BoundNetLog& net_log);
+
+ void set_enforce_net_security_expiration(bool enforce) {
+ enforce_net_security_expiration_ = enforce;
+ }
+
+ private:
+ // Returns true if the current build is recent enough to ensure that
+ // built-in security information (e.g. CT Logs) is fresh enough.
+ bool IsBuildTimely() const;
+
+ bool enforce_net_security_expiration_ = true;
};
} // namespace net
diff --git net/http/transport_security_state.cc net/http/transport_security_state.cc
index 5e67d4c..0774364 100644
--- net/http/transport_security_state.cc
+++ net/http/transport_security_state.cc
@@ -1232,8 +1232,10 @@ void TransportSecurityState::SetShouldRequireCTForTesting(bool* required) {
g_ct_required_for_testing = *required ? 1 : -1;
}
-// static
-bool TransportSecurityState::IsBuildTimely() {
+bool TransportSecurityState::IsBuildTimely() const {
+ if (!enforce_net_security_expiration_)
+ return true;
+
const base::Time build_time = base::GetBuildTime();
// We consider built-in information to be timely for 10 weeks.
return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
diff --git net/http/transport_security_state.h net/http/transport_security_state.h
index c29f859..cc41507 100644
--- net/http/transport_security_state.h
+++ net/http/transport_security_state.h
@@ -446,6 +446,10 @@ class NET_EXPORT TransportSecurityState
// nullptr to reset.
static void SetShouldRequireCTForTesting(bool* required);
+ void set_enforce_net_security_expiration(bool enforce) {
+ enforce_net_security_expiration_ = enforce;
+ }
+
private:
friend class TransportSecurityStateTest;
FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, UpdateDynamicPKPOnly);
@@ -469,7 +473,7 @@ class NET_EXPORT TransportSecurityState
// IsBuildTimely returns true if the current build is new enough ensure that
// built in security information (i.e. HSTS preloading and pinning
// information) is timely.
- static bool IsBuildTimely();
+ bool IsBuildTimely() const;
// Helper method for actually checking pins.
PKPStatus CheckPublicKeyPinsImpl(
@@ -557,6 +561,8 @@ class NET_EXPORT TransportSecurityState
// True if static expect-staple state should be used.
bool enable_static_expect_staple_;
+ bool enforce_net_security_expiration_ = true;
+
ExpectCTReporter* expect_ct_reporter_ = nullptr;
RequireCTDelegate* require_ct_delegate_ = nullptr;