Chromium Code Reviews| Index: components/data_reduction_proxy/browser/data_reduction_proxy_tamper_detect.h |
| diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_tamper_detect.h b/components/data_reduction_proxy/browser/data_reduction_proxy_tamper_detect.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2e6ec5a96bff92b41ae94cda6340a075cf646421 |
| --- /dev/null |
| +++ b/components/data_reduction_proxy/browser/data_reduction_proxy_tamper_detect.h |
| @@ -0,0 +1,178 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +// This file implements the tamper detection logic, which detects whether |
| +// there are middleboxes and whether they are tampering with the response |
| +// which maybe break correct communication and data transfer between the |
| +// Chromium client and the data reduction proxy. |
| +// |
| +// A high-level description of the tamper detection process works in two steps: |
| +// 1. The data reduction proxy selects a fraction of responses to analyze; |
| +// for the selected ones, the data reduction proxy generates a series of |
| +// fingerprints for the responses, and appends them to the Chrome-Proxy |
| +// header; |
| +// 2. At Chromium client side, when the Chromium client sees such fingerprints, |
| +// it uses the same method as the data reduction proxy to re-generate the |
| +// fingerprints, and compares them to the fingerprints in the response, to |
| +// see if the response has been tampered with and report to UMA. |
| +// |
| +// Four fingerprints are generated at the data reduction proxy side: |
| +// 1. Fingerprint of Chrome-Proxy header, which is designed to check whether |
|
bengr
2014/07/18 22:47:54
of the
xingx
2014/07/21 18:51:46
Done.
|
| +// Chrome-Proxy header has been modified or not; |
| +// 2. Fingerprint of Via header, which is designed to check whether there are |
|
bengr
2014/07/18 22:47:55
of the
xingx
2014/07/21 18:51:46
Done.
|
| +// middleboxes between the Chromium client and the data reduction proxy; |
| +// 3. Fingerprint of a list of headers, which is designed to check whether the |
| +// values of a list of headers (list is defined by the data reduction proxy) |
| +// have been modified or not; |
|
bengr
2014/07/18 22:47:54
modified or deleted?
xingx
2014/07/21 18:51:46
Done.
|
| +// 4. Fingerprint of Content-Length header, which is designed to check whether |
| +// the response body has been modified or not (assume that different |
| +// Content-Length value indicates different response body). |
|
bengr
2014/07/18 22:47:55
Should we be making this assumption? Content-Lengt
xingx
2014/07/21 18:51:46
No modification made, need to discuss.
|
| +// |
| +// At Chromium client side, the fingerprint of Chrome-Proxy header would be |
|
bengr
2014/07/18 22:47:55
At Chromium client side -> At the Chromium client
xingx
2014/07/21 18:51:46
Done.
|
| +// checked first. If such fingerprint indicates that the Chrome-Proxy header |
|
bengr
2014/07/18 22:47:55
such -> the
xingx
2014/07/21 18:51:45
Done.
|
| +// has not been modified, then other fingerprints are reliable and would be |
|
bengr
2014/07/18 22:47:55
other -> the other
are -> will be considered to be
xingx
2014/07/21 18:51:45
Done.
|
| +// checked next; if not, then it's possible that other fingerprints have been |
| +// tampered with and thus would not be checked. |
| +// |
| +// Detected tampering information will be reported to UMA. In general, for each |
| +// fingerprint, Chromium client reports the number of responses that have been |
|
bengr
2014/07/18 22:47:55
Chromium -> the Chromium
xingx
2014/07/21 18:51:46
Done.
|
| +// tampered with for different carriers. For the fingerprint of Content-Length |
|
bengr
2014/07/18 22:47:55
of -> of the
xingx
2014/07/21 18:51:45
Done.
|
| +// header, which indicates whether the response body has been modified or not, |
| +// the reports of tampering are separated by MIME type of the response body. |
| + |
| +#ifndef COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_TAMPER_DETECTION_H_ |
| +#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_TAMPER_DETECTION_H_ |
| + |
| +#include <map> |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "net/proxy/proxy_service.h" |
| + |
| +namespace net { |
| +class HttpResponseHeaders; |
| +} |
| + |
| +namespace data_reduction_proxy { |
| + |
| +// This class detects if response sent by the data reduction proxy has been |
| +// modified by intermediaries on the Web. |
| +class DataReductionProxyTamperDetection { |
| + public: |
| + // Checks if the response contains tamper detection fingerprints added by the |
| + // data reduction proxy, and determines if the response had been tampered |
| + // with if so. Results are reported to UMA. HTTP and HTTPS traffic are |
| + // reported separately, specified by |is_secure_scheme|. |
| + static void CheckResponseFingerprint(const net::HttpResponseHeaders* header, |
| + bool is_secure_scheme); |
| + |
| + // Tamper detection checks |response_headers|. |is_secure_scheme| determines |
| + // which histogram to report (HTTP and HTTPS are reported separately). |
| + // |carrier_id| is used to specify the bucket for histograms. |
|
bengr
2014/07/18 22:47:55
Change this sentence to:
Histogram events are repo
xingx
2014/07/21 18:51:46
Done.
|
| + // |chrome_proxy_header_values| points to the vector contains the values of |
| + // Chrome-Proxy header, but with Chrome-Proxy header's fingerprint removed, |
| + // which is a temporary result saved to use later to avoid parsing the header |
|
bengr
2014/07/18 22:47:55
header -> header again.
xingx
2014/07/21 18:51:46
Done.
|
| + // twice. |
| + DataReductionProxyTamperDetection( |
| + const net::HttpResponseHeaders* response_headers, |
| + bool is_secure_scheme, |
| + unsigned carrier_id, |
| + std::vector<std::string>* chrome_proxy_header_values); |
| + |
| + virtual ~DataReductionProxyTamperDetection(); |
| + |
| + private: |
| + friend class DataReductionProxyTamperDetectionTest; |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + TestFingerprintCommon); |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + ChromeProxy); |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + Via); |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + OtherHeaders); |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + ContentLength); |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + HeaderRemoving); |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + ValuesToSortedString); |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + GetHeaderValues); |
| + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, |
| + Completed); |
| + |
| + // Enum for fingerprint type. |
| + enum FingerprintCode { |
| + CHROMEPROXY = 1, /* Code of fingerprint for Chrome-Proxy header */ |
| + VIA = 2, /* Code of fingerprint for Via header */ |
| + OTHERHEADERS = 3, /* Code of fingerprint for a list of headers */ |
| + CONTENTLENGTH = 4, /* Code of fingerprint for Content-Length header */ |
| + NONEXIST = 5, |
| + }; |
| + |
| + // Returns true if the Chrome-Proxy header has been tampered with. |
| + bool IsChromeProxyHeaderTampered(const std::string& fingerprint) const; |
| + // Reports UMA for tampering of the Chrome-Proxy header. |
| + void ReportChromeProxyHeaderTamperedUMA() const; |
| + |
| + // Returns true if the Via header has been tampered with. |
| + bool IsViaHeaderTampered(const std::string& fingerprint) const; |
| + // Reports UMA for tampering of the Via header. |
| + void ReportViaHeaderTamperedUMA() const; |
| + |
| + // Returns true if a list of headers have been tampered with. |
| + bool AreOtherHeadersTampered(const std::string& fingerprint) const; |
| + // Reports UMA for tampering of values of the list of headers. |
| + void ReportOtherHeadersTamperedUMA() const; |
| + |
| + // Returns true if the Content-Length header has been tampered with. |
| + bool IsContentLengthHeaderTampered(const std::string& fingerprint) const; |
| + // Reports UMA for tampering of the Content-Length header. |
| + void ReportContentLengthHeaderTamperedUMA() const; |
| + |
| + // Returns the fingerprint code (enum) for the given fingerprint name. |
| + FingerprintCode GetFingerprintCode(const std::string& fingerprint_name); |
| + |
| + // Removes the fingerprint of Chrome-Proxy header from Chrome-Proxy header's |
|
bengr
2014/07/18 22:47:55
"the Chrome-Proxy" every time in this comment.
xingx
2014/07/21 18:51:45
Done.
|
| + // |values| vector. The data reduction proxy calculates the fingerprint for |
| + // Chrome-Proxy header and then appends calculated fingerprint to |
| + // Chrome-Proxy header, so at Chromium client side, to re-generate the |
| + // fingerprint, Chrome-Proxy header's fingerprint value needs to be removed |
| + // from Chrome-Proxy header first. |
| + static void RemoveChromeProxyFingerprint(std::vector<std::string>* values); |
| + |
| + // Returns a string of concatenated sorted values of |values|. |
| + static std::string ValuesToSortedString(std::vector<std::string>* values); |
| + |
| + // Returns raw MD5 hash value for a given string |input|. It is different to |
| + // base::MD5String which is base16 encoded. |
| + static std::string GetMD5(const std::string& input); |
| + |
| + // Returns all the values of |header_name| of the response |headers| as a |
| + // vector. This function is used for values that need to be sorted later. |
| + static std::vector<std::string> GetHeaderValues( |
| + const net::HttpResponseHeaders* headers, |
| + const std::string& header_name); |
| + |
| + // Pointer to response headers. |
| + const net::HttpResponseHeaders* response_headers_; |
| + |
| + // If true, the connection to the data reduction proxy is over HTTPS; |
| + const bool is_secure_scheme_; |
| + |
| + // Carrier ID. |
| + const unsigned carrier_id_; |
| + |
| + // Values for Chrome-Proxy header, with fingerprint of Chrome-Proxy header |
| + // value removed. Save it as a temporary result to avoid parsing the |
| + // Chrome-Proxy header twice. |
| + std::vector<std::string>* clean_chrome_proxy_header_values_; |
| + |
| + // Maps a fingerprint name (string) to a fingerprint code (enum). |
| + std::map<std::string, FingerprintCode> fingerprint_name_code_map_; |
| +}; |
| + |
| +} // namespace data_reduction_proxy |
| +#endif // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_TAMPER_DETECTION_H_ |