| 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..b800cae377a1f25b64f14a42bc96b9ecfab051aa
|
| --- /dev/null
|
| +++ b/components/data_reduction_proxy/browser/data_reduction_proxy_tamper_detect.h
|
| @@ -0,0 +1,181 @@
|
| +// 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 the 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 the Chrome-Proxy header, which is designed to check
|
| +// whether the Chrome-Proxy header has been modified or not;
|
| +// 2. Fingerprint of the Via header, which is designed to check whether there
|
| +// are 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 deleted;
|
| +// 4. Fingerprint of the 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).
|
| +//
|
| +// At the Chromium client side, the fingerprint of the Chrome-Proxy header will
|
| +// be checked first. If the fingerprint indicates that the Chrome-Proxy header
|
| +// has not been modified, then the other fingerprints will be considered to be
|
| +// reliable and will be checked next; if not, then it's possible that the other
|
| +// fingerprints have been tampered with and thus they will not be checked.
|
| +//
|
| +// Detected tampering information will be reported to UMA. In general, for each
|
| +// fingerprint, the Chromium client reports the number of responses that have
|
| +// been tampered with for different carriers. For the fingerprint of the
|
| +// Content-Length 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 the response sent by the data reduction proxy has been
|
| +// modified by the 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 bool DetectAndReport(const net::HttpResponseHeaders* header,
|
| + bool is_secure_scheme);
|
| +
|
| + // Tamper detection checks |response_headers|. Histogram events are reported
|
| + // by |carrier_id|; |is_secure_scheme| determines which histogram to report
|
| + // (HTTP and HTTPS are reported separately). |chrome_proxy_header_values|
|
| + // points to the vector contains the values of the Chrome-Proxy header, but
|
| + // with the Chrome-Proxy header's fingerprint removed, which is a temporary
|
| + // result saved to use later to avoid parsing the header again.
|
| + 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 of the Chrome-Proxy header */
|
| + VIA = 2, /* Code of fingerprint of the Via header */
|
| + OTHERHEADERS = 3, /* Code of fingerprint of a list of headers */
|
| + CONTENTLENGTH = 4, /* Code of fingerprint of the 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. |has_chrome_proxy|
|
| + // indicates that the data reduction proxy's Via header occurs or not.
|
| + bool IsViaHeaderTampered(const std::string& fingerprint,
|
| + bool* has_chrome_proxy_via_header) const;
|
| + // Reports UMA for tampering of the Via header.
|
| + void ReportViaHeaderTamperedUMA(bool has_chrome_proxy_via_header) 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 the Chrome-Proxy header from the Chrome-Proxy
|
| + // header's |values| vector. The data reduction proxy calculates the
|
| + // fingerprint for the Chrome-Proxy header and then appends calculated
|
| + // fingerprint to the Chrome-Proxy header, so at the Chromium client side,
|
| + // to re-generate the fingerprint, the Chrome-Proxy header's fingerprint value
|
| + // needs to be removed from the Chrome-Proxy header first.
|
| + static void RemoveChromeProxyFingerprint(std::vector<std::string>* values);
|
| +
|
| + // Returns a string representation 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 of the Chrome-Proxy header, with fingerprint of the Chrome-Proxy
|
| + // header value removed. Save it as a temporary result to avoid parsing the
|
| + // Chrome-Proxy header again.
|
| + 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_
|
|
|