| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_tamp
er_detection.h" | 5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_tamp
er_detection.h" |
| 6 | 6 |
| 7 #include <stddef.h> |
| 8 |
| 7 #include <algorithm> | 9 #include <algorithm> |
| 8 #include <cstring> | 10 #include <cstring> |
| 9 | 11 |
| 10 #include "base/base64.h" | 12 #include "base/base64.h" |
| 13 #include "base/macros.h" |
| 11 #include "base/md5.h" | 14 #include "base/md5.h" |
| 12 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/metrics/sparse_histogram.h" | 16 #include "base/metrics/sparse_histogram.h" |
| 14 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "build/build_config.h" |
| 16 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_heade
rs.h" | 20 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_heade
rs.h" |
| 17 #include "net/base/mime_util.h" | 21 #include "net/base/mime_util.h" |
| 18 #include "net/http/http_response_headers.h" | 22 #include "net/http/http_response_headers.h" |
| 19 #include "net/http/http_util.h" | 23 #include "net/http/http_util.h" |
| 20 | 24 |
| 21 #if defined(OS_ANDROID) | 25 #if defined(OS_ANDROID) |
| 22 #include "net/android/network_library.h" | 26 #include "net/android/network_library.h" |
| 23 #endif | 27 #endif |
| 24 | 28 |
| 25 // Macro for UMA reporting of tamper detection. HTTP response first reports to | 29 // Macro for UMA reporting of tamper detection. HTTP response first reports to |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 histogram_compression_ratio, compression_ratio); \ | 78 histogram_compression_ratio, compression_ratio); \ |
| 75 } \ | 79 } \ |
| 76 } while (0) | 80 } while (0) |
| 77 | 81 |
| 78 namespace data_reduction_proxy { | 82 namespace data_reduction_proxy { |
| 79 | 83 |
| 80 // static | 84 // static |
| 81 bool DataReductionProxyTamperDetection::DetectAndReport( | 85 bool DataReductionProxyTamperDetection::DetectAndReport( |
| 82 const net::HttpResponseHeaders* headers, | 86 const net::HttpResponseHeaders* headers, |
| 83 bool scheme_is_https, | 87 bool scheme_is_https, |
| 84 int64 content_length) { | 88 int64_t content_length) { |
| 85 if (headers == nullptr) { | 89 if (headers == nullptr) { |
| 86 return false; | 90 return false; |
| 87 } | 91 } |
| 88 | 92 |
| 89 // Abort tamper detection, if the fingerprint of the Chrome-Proxy header is | 93 // Abort tamper detection, if the fingerprint of the Chrome-Proxy header is |
| 90 // absent. | 94 // absent. |
| 91 std::string chrome_proxy_fingerprint; | 95 std::string chrome_proxy_fingerprint; |
| 92 if (!GetDataReductionProxyActionFingerprintChromeProxy( | 96 if (!GetDataReductionProxyActionFingerprintChromeProxy( |
| 93 headers, &chrome_proxy_fingerprint)) | 97 headers, &chrome_proxy_fingerprint)) |
| 94 return false; | 98 return false; |
| 95 | 99 |
| 96 // Get carrier ID. | 100 // Get carrier ID. |
| 97 unsigned carrier_id = 0; | 101 unsigned carrier_id = 0; |
| 98 #if defined(OS_ANDROID) | 102 #if defined(OS_ANDROID) |
| 99 base::StringToUint(net::android::GetTelephonyNetworkOperator(), &carrier_id); | 103 base::StringToUint(net::android::GetTelephonyNetworkOperator(), &carrier_id); |
| 100 #endif | 104 #endif |
| 101 | 105 |
| 102 DataReductionProxyTamperDetection tamper_detection( | 106 DataReductionProxyTamperDetection tamper_detection( |
| 103 headers, scheme_is_https, carrier_id); | 107 headers, scheme_is_https, carrier_id); |
| 104 | 108 |
| 105 // Checks if the Chrome-Proxy header has been tampered with. | 109 // Checks if the Chrome-Proxy header has been tampered with. |
| 106 if (tamper_detection.ValidateChromeProxyHeader(chrome_proxy_fingerprint)) { | 110 if (tamper_detection.ValidateChromeProxyHeader(chrome_proxy_fingerprint)) { |
| 107 tamper_detection.ReportUMAForChromeProxyHeaderValidation(); | 111 tamper_detection.ReportUMAForChromeProxyHeaderValidation(); |
| 108 return true; | 112 return true; |
| 109 } | 113 } |
| 110 | 114 |
| 111 // Chrome-Proxy header has not been tampered with, and thus other | 115 // Chrome-Proxy header has not been tampered with, and thus other |
| 112 // fingerprints are valid. | 116 // fingerprints are valid. |
| 113 bool tampered = false; | 117 bool tampered = false; |
| 114 int64 original_content_length = -1; | 118 int64_t original_content_length = -1; |
| 115 std::string fingerprint; | 119 std::string fingerprint; |
| 116 | 120 |
| 117 if (GetDataReductionProxyActionFingerprintVia(headers, &fingerprint)) { | 121 if (GetDataReductionProxyActionFingerprintVia(headers, &fingerprint)) { |
| 118 bool has_chrome_proxy_via_header; | 122 bool has_chrome_proxy_via_header; |
| 119 if (tamper_detection.ValidateViaHeader( | 123 if (tamper_detection.ValidateViaHeader( |
| 120 fingerprint, &has_chrome_proxy_via_header)) { | 124 fingerprint, &has_chrome_proxy_via_header)) { |
| 121 tamper_detection.ReportUMAForViaHeaderValidation( | 125 tamper_detection.ReportUMAForViaHeaderValidation( |
| 122 has_chrome_proxy_via_header); | 126 has_chrome_proxy_via_header); |
| 123 tampered = true; | 127 tampered = true; |
| 124 } | 128 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 const unsigned carrier_id) | 169 const unsigned carrier_id) |
| 166 : response_headers_(headers), | 170 : response_headers_(headers), |
| 167 scheme_is_https_(is_secure), | 171 scheme_is_https_(is_secure), |
| 168 carrier_id_(carrier_id) { | 172 carrier_id_(carrier_id) { |
| 169 DCHECK(headers); | 173 DCHECK(headers); |
| 170 } | 174 } |
| 171 | 175 |
| 172 DataReductionProxyTamperDetection::~DataReductionProxyTamperDetection() {}; | 176 DataReductionProxyTamperDetection::~DataReductionProxyTamperDetection() {}; |
| 173 | 177 |
| 174 void DataReductionProxyTamperDetection::ReportUMAForTamperDetectionCount( | 178 void DataReductionProxyTamperDetection::ReportUMAForTamperDetectionCount( |
| 175 int64 original_content_length) const { | 179 int64_t original_content_length) const { |
| 176 REPORT_TAMPER_DETECTION_UMA( | 180 REPORT_TAMPER_DETECTION_UMA( |
| 177 scheme_is_https_, "DataReductionProxy.HeaderTamperDetectionHTTPS", | 181 scheme_is_https_, "DataReductionProxy.HeaderTamperDetectionHTTPS", |
| 178 "DataReductionProxy.HeaderTamperDetectionHTTP", carrier_id_); | 182 "DataReductionProxy.HeaderTamperDetectionHTTP", carrier_id_); |
| 179 | 183 |
| 180 std::string mime_type; | 184 std::string mime_type; |
| 181 response_headers_->GetMimeType(&mime_type); | 185 response_headers_->GetMimeType(&mime_type); |
| 182 | 186 |
| 183 if (net::MatchesMimeType("text/javascript", mime_type) || | 187 if (net::MatchesMimeType("text/javascript", mime_type) || |
| 184 net::MatchesMimeType("application/x-javascript", mime_type) || | 188 net::MatchesMimeType("application/x-javascript", mime_type) || |
| 185 net::MatchesMimeType("application/javascript", mime_type)) { | 189 net::MatchesMimeType("application/javascript", mime_type)) { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 ReportUMAForOtherHeadersValidation() const { | 385 ReportUMAForOtherHeadersValidation() const { |
| 382 REPORT_TAMPER_DETECTION_UMA( | 386 REPORT_TAMPER_DETECTION_UMA( |
| 383 scheme_is_https_, | 387 scheme_is_https_, |
| 384 "DataReductionProxy.HeaderTamperedHTTPS_OtherHeaders", | 388 "DataReductionProxy.HeaderTamperedHTTPS_OtherHeaders", |
| 385 "DataReductionProxy.HeaderTamperedHTTP_OtherHeaders", | 389 "DataReductionProxy.HeaderTamperedHTTP_OtherHeaders", |
| 386 carrier_id_); | 390 carrier_id_); |
| 387 } | 391 } |
| 388 | 392 |
| 389 bool DataReductionProxyTamperDetection::ValidateContentLength( | 393 bool DataReductionProxyTamperDetection::ValidateContentLength( |
| 390 const std::string& fingerprint, | 394 const std::string& fingerprint, |
| 391 int64 content_length, | 395 int64_t content_length, |
| 392 int64* original_content_length) const { | 396 int64_t* original_content_length) const { |
| 393 DCHECK(original_content_length); | 397 DCHECK(original_content_length); |
| 394 // Abort, if Content-Length value from the Data Reduction Proxy does not | 398 // Abort, if Content-Length value from the Data Reduction Proxy does not |
| 395 // exist or it cannot be converted to an integer. | 399 // exist or it cannot be converted to an integer. |
| 396 if (!base::StringToInt64(fingerprint, original_content_length)) | 400 if (!base::StringToInt64(fingerprint, original_content_length)) |
| 397 return false; | 401 return false; |
| 398 | 402 |
| 399 return *original_content_length != content_length; | 403 return *original_content_length != content_length; |
| 400 } | 404 } |
| 401 | 405 |
| 402 void DataReductionProxyTamperDetection::ReportUMAForContentLength( | 406 void DataReductionProxyTamperDetection::ReportUMAForContentLength( |
| 403 int64 content_length, | 407 int64_t content_length, |
| 404 int64 original_content_length) const { | 408 int64_t original_content_length) const { |
| 405 // Gets MIME type of the response and reports to UMA histograms separately. | 409 // Gets MIME type of the response and reports to UMA histograms separately. |
| 406 // Divides MIME types into 4 groups: JavaScript, CSS, Images, and others. | 410 // Divides MIME types into 4 groups: JavaScript, CSS, Images, and others. |
| 407 REPORT_TAMPER_DETECTION_UMA( | 411 REPORT_TAMPER_DETECTION_UMA( |
| 408 scheme_is_https_, | 412 scheme_is_https_, |
| 409 "DataReductionProxy.HeaderTamperedHTTPS_ContentLength", | 413 "DataReductionProxy.HeaderTamperedHTTPS_ContentLength", |
| 410 "DataReductionProxy.HeaderTamperedHTTP_ContentLength", | 414 "DataReductionProxy.HeaderTamperedHTTP_ContentLength", |
| 411 carrier_id_); | 415 carrier_id_); |
| 412 | 416 |
| 413 // Gets MIME type. | 417 // Gets MIME type. |
| 414 std::string mime_type; | 418 std::string mime_type; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 std::vector<std::string> values; | 545 std::vector<std::string> values; |
| 542 std::string value; | 546 std::string value; |
| 543 void* iter = NULL; | 547 void* iter = NULL; |
| 544 while (headers->EnumerateHeader(&iter, header_name, &value)) { | 548 while (headers->EnumerateHeader(&iter, header_name, &value)) { |
| 545 values.push_back(value); | 549 values.push_back(value); |
| 546 } | 550 } |
| 547 return values; | 551 return values; |
| 548 } | 552 } |
| 549 | 553 |
| 550 } // namespace data_reduction_proxy | 554 } // namespace data_reduction_proxy |
| OLD | NEW |