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

Side by Side Diff: net/http/transport_security_state.cc

Issue 2901183002: Do not send repeated Expect-CT reports to the same host+port (Closed)
Patch Set: fix comment typo Created 3 years, 7 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 unified diff | Download patch
« no previous file with comments | « net/http/transport_security_state.h ('k') | net/http/transport_security_state_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/transport_security_state.h" 5 #include "net/http/transport_security_state.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 25 matching lines...) Expand all
36 #include "base/metrics/field_trial.h" 36 #include "base/metrics/field_trial.h"
37 #endif 37 #endif
38 38
39 namespace net { 39 namespace net {
40 40
41 namespace { 41 namespace {
42 42
43 #include "net/http/transport_security_state_ct_policies.inc" 43 #include "net/http/transport_security_state_ct_policies.inc"
44 #include "net/http/transport_security_state_static.h" 44 #include "net/http/transport_security_state_static.h"
45 45
46 const size_t kMaxHPKPReportCacheEntries = 50; 46 // Parameters for remembering sent HPKP and Expect-CT reports.
47 const int kTimeToRememberHPKPReportsMins = 60; 47 const size_t kMaxReportCacheEntries = 50;
48 const int kTimeToRememberReportsMins = 60;
48 const size_t kReportCacheKeyLength = 16; 49 const size_t kReportCacheKeyLength = 16;
49 50
50 // Points to the active transport security state source. 51 // Points to the active transport security state source.
51 const TransportSecurityStateSource* g_hsts_source = &kHSTSSource; 52 const TransportSecurityStateSource* g_hsts_source = &kHSTSSource;
52 53
53 // Override for CheckCTRequirements() for unit tests. Possible values: 54 // Override for CheckCTRequirements() for unit tests. Possible values:
54 // -1: Unless a delegate says otherwise, do not require CT. 55 // -1: Unless a delegate says otherwise, do not require CT.
55 // 0: Use the default implementation (e.g. production) 56 // 0: Use the default implementation (e.g. production)
56 // 1: Unless a delegate says otherwise, require CT. 57 // 1: Unless a delegate says otherwise, require CT.
57 int g_ct_required_for_testing = 0; 58 int g_ct_required_for_testing = 0;
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 void SetTransportSecurityStateSourceForTesting( 736 void SetTransportSecurityStateSourceForTesting(
736 const TransportSecurityStateSource* source) { 737 const TransportSecurityStateSource* source) {
737 g_hsts_source = source ? source : &kHSTSSource; 738 g_hsts_source = source ? source : &kHSTSSource;
738 } 739 }
739 740
740 TransportSecurityState::TransportSecurityState() 741 TransportSecurityState::TransportSecurityState()
741 : enable_static_pins_(true), 742 : enable_static_pins_(true),
742 enable_static_expect_ct_(true), 743 enable_static_expect_ct_(true),
743 enable_static_expect_staple_(true), 744 enable_static_expect_staple_(true),
744 enable_pkp_bypass_for_local_trust_anchors_(true), 745 enable_pkp_bypass_for_local_trust_anchors_(true),
745 sent_reports_cache_(kMaxHPKPReportCacheEntries) { 746 sent_hpkp_reports_cache_(kMaxReportCacheEntries),
747 sent_expect_ct_reports_cache_(kMaxReportCacheEntries) {
746 // Static pinning is only enabled for official builds to make sure that 748 // Static pinning is only enabled for official builds to make sure that
747 // others don't end up with pins that cannot be easily updated. 749 // others don't end up with pins that cannot be easily updated.
748 #if !defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID) || defined(OS_IOS) 750 #if !defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID) || defined(OS_IOS)
749 enable_static_pins_ = false; 751 enable_static_pins_ = false;
750 enable_static_expect_ct_ = false; 752 enable_static_expect_ct_ = false;
751 #endif 753 #endif
752 DCHECK(CalledOnValidThread()); 754 DCHECK(CalledOnValidThread());
753 } 755 }
754 756
755 // Both HSTS and HPKP cause fatal SSL errors, so return true if a 757 // Both HSTS and HPKP cause fatal SSL errors, so return true if a
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 return CT_REQUIREMENTS_MET; 885 return CT_REQUIREMENTS_MET;
884 } 886 }
885 887
886 // Check Expect-CT first so that other CT requirements do not prevent 888 // Check Expect-CT first so that other CT requirements do not prevent
887 // Expect-CT reports from being sent. 889 // Expect-CT reports from being sent.
888 ExpectCTState state; 890 ExpectCTState state;
889 if (is_issued_by_known_root && IsDynamicExpectCTEnabled() && 891 if (is_issued_by_known_root && IsDynamicExpectCTEnabled() &&
890 GetDynamicExpectCTState(hostname, &state)) { 892 GetDynamicExpectCTState(hostname, &state)) {
891 if (expect_ct_reporter_ && !state.report_uri.is_empty() && 893 if (expect_ct_reporter_ && !state.report_uri.is_empty() &&
892 report_status == ENABLE_EXPECT_CT_REPORTS) { 894 report_status == ENABLE_EXPECT_CT_REPORTS) {
893 expect_ct_reporter_->OnExpectCTFailed( 895 MaybeNotifyExpectCTFailed(
894 host_port_pair, state.report_uri, validated_certificate_chain, 896 host_port_pair, state.report_uri, validated_certificate_chain,
895 served_certificate_chain, signed_certificate_timestamps); 897 served_certificate_chain, signed_certificate_timestamps);
896 } 898 }
897 if (state.enforce) 899 if (state.enforce)
898 return CT_REQUIREMENTS_NOT_MET; 900 return CT_REQUIREMENTS_NOT_MET;
899 } 901 }
900 902
901 CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT; 903 CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT;
902 if (require_ct_delegate_) 904 if (require_ct_delegate_)
903 ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname); 905 ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 std::string serialized_report; 1162 std::string serialized_report;
1161 std::string report_cache_key; 1163 std::string report_cache_key;
1162 if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain, 1164 if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain,
1163 validated_certificate_chain, &serialized_report, 1165 validated_certificate_chain, &serialized_report,
1164 &report_cache_key)) { 1166 &report_cache_key)) {
1165 return PKPStatus::VIOLATED; 1167 return PKPStatus::VIOLATED;
1166 } 1168 }
1167 1169
1168 // Limit the rate at which duplicate reports are sent to the same 1170 // Limit the rate at which duplicate reports are sent to the same
1169 // report URI. The same report will not be sent within 1171 // report URI. The same report will not be sent within
1170 // |kTimeToRememberHPKPReportsMins|, which reduces load on servers and 1172 // |kTimeToRememberReportsMins|, which reduces load on servers and
1171 // also prevents accidental loops (a.com triggers a report to b.com 1173 // also prevents accidental loops (a.com triggers a report to b.com
1172 // which triggers a report to a.com). See section 2.1.4 of RFC 7469. 1174 // which triggers a report to a.com). See section 2.1.4 of RFC 7469.
1173 if (sent_reports_cache_.Get(report_cache_key, base::TimeTicks::Now())) 1175 if (sent_hpkp_reports_cache_.Get(report_cache_key, base::TimeTicks::Now()))
1174 return PKPStatus::VIOLATED; 1176 return PKPStatus::VIOLATED;
1175 sent_reports_cache_.Put( 1177 sent_hpkp_reports_cache_.Put(
1176 report_cache_key, true, base::TimeTicks::Now(), 1178 report_cache_key, true, base::TimeTicks::Now(),
1177 base::TimeTicks::Now() + 1179 base::TimeTicks::Now() +
1178 base::TimeDelta::FromMinutes(kTimeToRememberHPKPReportsMins)); 1180 base::TimeDelta::FromMinutes(kTimeToRememberReportsMins));
1179 1181
1180 report_sender_->Send(pkp_state.report_uri, "application/json; charset=utf-8", 1182 report_sender_->Send(pkp_state.report_uri, "application/json; charset=utf-8",
1181 serialized_report, base::Callback<void()>(), 1183 serialized_report, base::Callback<void()>(),
1182 base::Bind(RecordUMAForHPKPReportFailure)); 1184 base::Bind(RecordUMAForHPKPReportFailure));
1183 return PKPStatus::VIOLATED; 1185 return PKPStatus::VIOLATED;
1184 } 1186 }
1185 1187
1186 bool TransportSecurityState::GetStaticExpectCTState( 1188 bool TransportSecurityState::GetStaticExpectCTState(
1187 const std::string& host, 1189 const std::string& host,
1188 ExpectCTState* expect_ct_state) const { 1190 ExpectCTState* expect_ct_state) const {
1189 DCHECK(CalledOnValidThread()); 1191 DCHECK(CalledOnValidThread());
1190 1192
1191 if (!IsBuildTimely()) 1193 if (!IsBuildTimely())
1192 return false; 1194 return false;
1193 1195
1194 PreloadResult result; 1196 PreloadResult result;
1195 if (!DecodeHSTSPreload(host, &result)) 1197 if (!DecodeHSTSPreload(host, &result))
1196 return false; 1198 return false;
1197 1199
1198 if (!enable_static_expect_ct_ || !result.expect_ct) 1200 if (!enable_static_expect_ct_ || !result.expect_ct)
1199 return false; 1201 return false;
1200 1202
1201 expect_ct_state->domain = host.substr(result.hostname_offset); 1203 expect_ct_state->domain = host.substr(result.hostname_offset);
1202 expect_ct_state->report_uri = GURL( 1204 expect_ct_state->report_uri = GURL(
1203 g_hsts_source->expect_ct_report_uris[result.expect_ct_report_uri_id]); 1205 g_hsts_source->expect_ct_report_uris[result.expect_ct_report_uri_id]);
1204 return true; 1206 return true;
1205 } 1207 }
1206 1208
1209 void TransportSecurityState::MaybeNotifyExpectCTFailed(
1210 const HostPortPair& host_port_pair,
1211 const GURL& report_uri,
1212 const X509Certificate* validated_certificate_chain,
1213 const X509Certificate* served_certificate_chain,
1214 const SignedCertificateTimestampAndStatusList&
1215 signed_certificate_timestamps) {
1216 // Do not send repeated reports to the same host/port pair within
1217 // |kTimeToRememberReportsMins|. Theoretically, there could be scenarios in
1218 // which the same host/port generates different reports and it would be useful
1219 // to the server operator to receive those different reports, but such
1220 // scenarios are not expected to arise very often in practice.
1221 const std::string report_cache_key(host_port_pair.ToString());
1222 if (sent_expect_ct_reports_cache_.Get(report_cache_key,
1223 base::TimeTicks::Now())) {
1224 return;
1225 }
1226 sent_expect_ct_reports_cache_.Put(
1227 report_cache_key, true, base::TimeTicks::Now(),
1228 base::TimeTicks::Now() +
1229 base::TimeDelta::FromMinutes(kTimeToRememberReportsMins));
1230
1231 expect_ct_reporter_->OnExpectCTFailed(
1232 host_port_pair, report_uri, validated_certificate_chain,
1233 served_certificate_chain, signed_certificate_timestamps);
1234 }
1235
1207 bool TransportSecurityState::GetStaticExpectStapleState( 1236 bool TransportSecurityState::GetStaticExpectStapleState(
1208 const std::string& host, 1237 const std::string& host,
1209 ExpectStapleState* expect_staple_state) const { 1238 ExpectStapleState* expect_staple_state) const {
1210 DCHECK(CalledOnValidThread()); 1239 DCHECK(CalledOnValidThread());
1211 1240
1212 if (!IsBuildTimely()) 1241 if (!IsBuildTimely())
1213 return false; 1242 return false;
1214 1243
1215 PreloadResult result; 1244 PreloadResult result;
1216 if (!DecodeHSTSPreload(host, &result)) 1245 if (!DecodeHSTSPreload(host, &result))
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 return; 1470 return;
1442 if (!ssl_info.is_issued_by_known_root) 1471 if (!ssl_info.is_issued_by_known_root)
1443 return; 1472 return;
1444 if (!ssl_info.ct_compliance_details_available) 1473 if (!ssl_info.ct_compliance_details_available)
1445 return; 1474 return;
1446 if (ssl_info.ct_cert_policy_compliance == 1475 if (ssl_info.ct_cert_policy_compliance ==
1447 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS) 1476 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS)
1448 return; 1477 return;
1449 ExpectCTState state; 1478 ExpectCTState state;
1450 if (GetStaticExpectCTState(host_port_pair.host(), &state)) { 1479 if (GetStaticExpectCTState(host_port_pair.host(), &state)) {
1451 expect_ct_reporter_->OnExpectCTFailed( 1480 MaybeNotifyExpectCTFailed(host_port_pair, state.report_uri,
1452 host_port_pair, state.report_uri, ssl_info.cert.get(), 1481 ssl_info.cert.get(),
1453 ssl_info.unverified_cert.get(), 1482 ssl_info.unverified_cert.get(),
1454 ssl_info.signed_certificate_timestamps); 1483 ssl_info.signed_certificate_timestamps);
1455 } 1484 }
1456 return; 1485 return;
1457 } 1486 }
1458 1487
1459 // Otherwise, see if the site has sent a valid Expect-CT header to dynamically 1488 // Otherwise, see if the site has sent a valid Expect-CT header to dynamically
1460 // turn on reporting and/or enforcement. 1489 // turn on reporting and/or enforcement.
1461 if (!IsDynamicExpectCTEnabled()) 1490 if (!IsDynamicExpectCTEnabled())
1462 return; 1491 return;
1463 base::Time now = base::Time::Now(); 1492 base::Time now = base::Time::Now();
1464 base::TimeDelta max_age; 1493 base::TimeDelta max_age;
(...skipping 12 matching lines...) Expand all
1477 ExpectCTState state; 1506 ExpectCTState state;
1478 // If an Expect-CT header is observed over a non-compliant connection, the 1507 // If an Expect-CT header is observed over a non-compliant connection, the
1479 // site owner should be notified about the misconfiguration. If the site was 1508 // site owner should be notified about the misconfiguration. If the site was
1480 // already opted in to Expect-CT, this report would have been sent at 1509 // already opted in to Expect-CT, this report would have been sent at
1481 // connection setup time. If the host is not already a noted Expect-CT host, 1510 // connection setup time. If the host is not already a noted Expect-CT host,
1482 // however, the lack of CT compliance would not have been evaluated/reported 1511 // however, the lack of CT compliance would not have been evaluated/reported
1483 // at connection setup time, so it needs to be reported here while 1512 // at connection setup time, so it needs to be reported here while
1484 // processing the header. 1513 // processing the header.
1485 if (expect_ct_reporter_ && !report_uri.is_empty() && 1514 if (expect_ct_reporter_ && !report_uri.is_empty() &&
1486 !GetDynamicExpectCTState(host_port_pair.host(), &state)) { 1515 !GetDynamicExpectCTState(host_port_pair.host(), &state)) {
1487 expect_ct_reporter_->OnExpectCTFailed( 1516 MaybeNotifyExpectCTFailed(host_port_pair, report_uri, ssl_info.cert.get(),
1488 host_port_pair, report_uri, ssl_info.cert.get(), 1517 ssl_info.unverified_cert.get(),
1489 ssl_info.unverified_cert.get(), 1518 ssl_info.signed_certificate_timestamps);
1490 ssl_info.signed_certificate_timestamps);
1491 } 1519 }
1492 return; 1520 return;
1493 } 1521 }
1494 AddExpectCTInternal(host_port_pair.host(), now, now + max_age, enforce, 1522 AddExpectCTInternal(host_port_pair.host(), now, now + max_age, enforce,
1495 report_uri); 1523 report_uri);
1496 } 1524 }
1497 1525
1498 // static 1526 // static
1499 void TransportSecurityState::SetShouldRequireCTForTesting(bool* required) { 1527 void TransportSecurityState::SetShouldRequireCTForTesting(bool* required) {
1500 if (!required) { 1528 if (!required) {
1501 g_ct_required_for_testing = 0; 1529 g_ct_required_for_testing = 0;
1502 return; 1530 return;
1503 } 1531 }
1504 g_ct_required_for_testing = *required ? 1 : -1; 1532 g_ct_required_for_testing = *required ? 1 : -1;
1505 } 1533 }
1506 1534
1535 void TransportSecurityState::ClearReportCachesForTesting() {
1536 sent_hpkp_reports_cache_.Clear();
1537 sent_expect_ct_reports_cache_.Clear();
1538 }
1539
1507 // static 1540 // static
1508 bool TransportSecurityState::IsBuildTimely() { 1541 bool TransportSecurityState::IsBuildTimely() {
1509 const base::Time build_time = base::GetBuildTime(); 1542 const base::Time build_time = base::GetBuildTime();
1510 // We consider built-in information to be timely for 10 weeks. 1543 // We consider built-in information to be timely for 10 weeks.
1511 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; 1544 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
1512 } 1545 }
1513 1546
1514 TransportSecurityState::PKPStatus 1547 TransportSecurityState::PKPStatus
1515 TransportSecurityState::CheckPublicKeyPinsImpl( 1548 TransportSecurityState::CheckPublicKeyPinsImpl(
1516 const HostPortPair& host_port_pair, 1549 const HostPortPair& host_port_pair,
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 TransportSecurityState::PKPStateIterator::PKPStateIterator( 1862 TransportSecurityState::PKPStateIterator::PKPStateIterator(
1830 const TransportSecurityState& state) 1863 const TransportSecurityState& state)
1831 : iterator_(state.enabled_pkp_hosts_.begin()), 1864 : iterator_(state.enabled_pkp_hosts_.begin()),
1832 end_(state.enabled_pkp_hosts_.end()) { 1865 end_(state.enabled_pkp_hosts_.end()) {
1833 } 1866 }
1834 1867
1835 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { 1868 TransportSecurityState::PKPStateIterator::~PKPStateIterator() {
1836 } 1869 }
1837 1870
1838 } // namespace 1871 } // namespace
OLDNEW
« no previous file with comments | « net/http/transport_security_state.h ('k') | net/http/transport_security_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698