Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // This file implements the tamper detection logic, which detects whether | |
| 6 // there are middleboxes and whether they are tampering with the response | |
| 7 // which maybe break correct communication and data transfer between the | |
| 8 // Chromium client and the data reduction proxy. | |
| 9 // | |
| 10 // A high-level description of the tamper detection process works in two steps: | |
| 11 // 1. The data reduction proxy selects a fraction of responses to analyze; | |
| 12 // for the selected ones, the data reduction proxy generates a series of | |
| 13 // fingerprints for the responses, and appends them to the Chrome-Proxy | |
| 14 // header; | |
| 15 // 2. At Chromium client side, when the Chromium client sees such fingerprints, | |
| 16 // it uses the same method as the data reduction proxy to re-generate the | |
| 17 // fingerprints, and compares them to the fingerprints in the response, to | |
| 18 // see if the response has been tampered with and report to UMA. | |
| 19 // | |
| 20 // Four fingerprints are generated at the data reduction proxy side: | |
| 21 // 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.
| |
| 22 // Chrome-Proxy header has been modified or not; | |
| 23 // 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.
| |
| 24 // middleboxes between the Chromium client and the data reduction proxy; | |
| 25 // 3. Fingerprint of a list of headers, which is designed to check whether the | |
| 26 // values of a list of headers (list is defined by the data reduction proxy) | |
| 27 // have been modified or not; | |
|
bengr
2014/07/18 22:47:54
modified or deleted?
xingx
2014/07/21 18:51:46
Done.
| |
| 28 // 4. Fingerprint of Content-Length header, which is designed to check whether | |
| 29 // the response body has been modified or not (assume that different | |
| 30 // 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.
| |
| 31 // | |
| 32 // 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.
| |
| 33 // 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.
| |
| 34 // 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.
| |
| 35 // checked next; if not, then it's possible that other fingerprints have been | |
| 36 // tampered with and thus would not be checked. | |
| 37 // | |
| 38 // Detected tampering information will be reported to UMA. In general, for each | |
| 39 // 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.
| |
| 40 // 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.
| |
| 41 // header, which indicates whether the response body has been modified or not, | |
| 42 // the reports of tampering are separated by MIME type of the response body. | |
| 43 | |
| 44 #ifndef COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_TAMPER_DETE CTION_H_ | |
| 45 #define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_TAMPER_DETE CTION_H_ | |
| 46 | |
| 47 #include <map> | |
| 48 #include <string> | |
| 49 #include <vector> | |
| 50 | |
| 51 #include "net/proxy/proxy_service.h" | |
| 52 | |
| 53 namespace net { | |
| 54 class HttpResponseHeaders; | |
| 55 } | |
| 56 | |
| 57 namespace data_reduction_proxy { | |
| 58 | |
| 59 // This class detects if response sent by the data reduction proxy has been | |
| 60 // modified by intermediaries on the Web. | |
| 61 class DataReductionProxyTamperDetection { | |
| 62 public: | |
| 63 // Checks if the response contains tamper detection fingerprints added by the | |
| 64 // data reduction proxy, and determines if the response had been tampered | |
| 65 // with if so. Results are reported to UMA. HTTP and HTTPS traffic are | |
| 66 // reported separately, specified by |is_secure_scheme|. | |
| 67 static void CheckResponseFingerprint(const net::HttpResponseHeaders* header, | |
| 68 bool is_secure_scheme); | |
| 69 | |
| 70 // Tamper detection checks |response_headers|. |is_secure_scheme| determines | |
| 71 // which histogram to report (HTTP and HTTPS are reported separately). | |
| 72 // |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.
| |
| 73 // |chrome_proxy_header_values| points to the vector contains the values of | |
| 74 // Chrome-Proxy header, but with Chrome-Proxy header's fingerprint removed, | |
| 75 // 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.
| |
| 76 // twice. | |
| 77 DataReductionProxyTamperDetection( | |
| 78 const net::HttpResponseHeaders* response_headers, | |
| 79 bool is_secure_scheme, | |
| 80 unsigned carrier_id, | |
| 81 std::vector<std::string>* chrome_proxy_header_values); | |
| 82 | |
| 83 virtual ~DataReductionProxyTamperDetection(); | |
| 84 | |
| 85 private: | |
| 86 friend class DataReductionProxyTamperDetectionTest; | |
| 87 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 88 TestFingerprintCommon); | |
| 89 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 90 ChromeProxy); | |
| 91 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 92 Via); | |
| 93 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 94 OtherHeaders); | |
| 95 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 96 ContentLength); | |
| 97 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 98 HeaderRemoving); | |
| 99 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 100 ValuesToSortedString); | |
| 101 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 102 GetHeaderValues); | |
| 103 FRIEND_TEST_ALL_PREFIXES(DataReductionProxyTamperDetectionTest, | |
| 104 Completed); | |
| 105 | |
| 106 // Enum for fingerprint type. | |
| 107 enum FingerprintCode { | |
| 108 CHROMEPROXY = 1, /* Code of fingerprint for Chrome-Proxy header */ | |
| 109 VIA = 2, /* Code of fingerprint for Via header */ | |
| 110 OTHERHEADERS = 3, /* Code of fingerprint for a list of headers */ | |
| 111 CONTENTLENGTH = 4, /* Code of fingerprint for Content-Length header */ | |
| 112 NONEXIST = 5, | |
| 113 }; | |
| 114 | |
| 115 // Returns true if the Chrome-Proxy header has been tampered with. | |
| 116 bool IsChromeProxyHeaderTampered(const std::string& fingerprint) const; | |
| 117 // Reports UMA for tampering of the Chrome-Proxy header. | |
| 118 void ReportChromeProxyHeaderTamperedUMA() const; | |
| 119 | |
| 120 // Returns true if the Via header has been tampered with. | |
| 121 bool IsViaHeaderTampered(const std::string& fingerprint) const; | |
| 122 // Reports UMA for tampering of the Via header. | |
| 123 void ReportViaHeaderTamperedUMA() const; | |
| 124 | |
| 125 // Returns true if a list of headers have been tampered with. | |
| 126 bool AreOtherHeadersTampered(const std::string& fingerprint) const; | |
| 127 // Reports UMA for tampering of values of the list of headers. | |
| 128 void ReportOtherHeadersTamperedUMA() const; | |
| 129 | |
| 130 // Returns true if the Content-Length header has been tampered with. | |
| 131 bool IsContentLengthHeaderTampered(const std::string& fingerprint) const; | |
| 132 // Reports UMA for tampering of the Content-Length header. | |
| 133 void ReportContentLengthHeaderTamperedUMA() const; | |
| 134 | |
| 135 // Returns the fingerprint code (enum) for the given fingerprint name. | |
| 136 FingerprintCode GetFingerprintCode(const std::string& fingerprint_name); | |
| 137 | |
| 138 // 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.
| |
| 139 // |values| vector. The data reduction proxy calculates the fingerprint for | |
| 140 // Chrome-Proxy header and then appends calculated fingerprint to | |
| 141 // Chrome-Proxy header, so at Chromium client side, to re-generate the | |
| 142 // fingerprint, Chrome-Proxy header's fingerprint value needs to be removed | |
| 143 // from Chrome-Proxy header first. | |
| 144 static void RemoveChromeProxyFingerprint(std::vector<std::string>* values); | |
| 145 | |
| 146 // Returns a string of concatenated sorted values of |values|. | |
| 147 static std::string ValuesToSortedString(std::vector<std::string>* values); | |
| 148 | |
| 149 // Returns raw MD5 hash value for a given string |input|. It is different to | |
| 150 // base::MD5String which is base16 encoded. | |
| 151 static std::string GetMD5(const std::string& input); | |
| 152 | |
| 153 // Returns all the values of |header_name| of the response |headers| as a | |
| 154 // vector. This function is used for values that need to be sorted later. | |
| 155 static std::vector<std::string> GetHeaderValues( | |
| 156 const net::HttpResponseHeaders* headers, | |
| 157 const std::string& header_name); | |
| 158 | |
| 159 // Pointer to response headers. | |
| 160 const net::HttpResponseHeaders* response_headers_; | |
| 161 | |
| 162 // If true, the connection to the data reduction proxy is over HTTPS; | |
| 163 const bool is_secure_scheme_; | |
| 164 | |
| 165 // Carrier ID. | |
| 166 const unsigned carrier_id_; | |
| 167 | |
| 168 // Values for Chrome-Proxy header, with fingerprint of Chrome-Proxy header | |
| 169 // value removed. Save it as a temporary result to avoid parsing the | |
| 170 // Chrome-Proxy header twice. | |
| 171 std::vector<std::string>* clean_chrome_proxy_header_values_; | |
| 172 | |
| 173 // Maps a fingerprint name (string) to a fingerprint code (enum). | |
| 174 std::map<std::string, FingerprintCode> fingerprint_name_code_map_; | |
| 175 }; | |
| 176 | |
| 177 } // namespace data_reduction_proxy | |
| 178 #endif // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_TAMPER_D ETECTION_H_ | |
| OLD | NEW |