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

Unified Diff: net/http/http_network_transaction.cc

Issue 2753453003: Reject unadvertised encodings (Closed)
Patch Set: Reject unadvertised encodings. Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: net/http/http_network_transaction.cc
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index a5395d758bcc4c9d26ef115ca43da28ce9424a0c..3f665eb485f20716efe49c33ef29c89eb311f944 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -32,6 +32,7 @@
#include "net/base/net_errors.h"
#include "net/base/upload_data_stream.h"
#include "net/base/url_util.h"
+#include "net/filter/filter_source_stream.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
@@ -545,6 +546,12 @@ void HttpNetworkTransaction::OnNeedsProxyAuth(
establishing_tunnel_ = true;
response_.headers = proxy_response.headers;
response_.auth_challenge = proxy_response.auth_challenge;
+
+ if (response_.headers.get() && !ContentEncodingsValid()) {
+ DoCallback(ERR_CONTENT_DECODING_FAILED);
+ return;
+ }
+
headers_valid_ = true;
server_ssl_config_ = used_ssl_config;
proxy_info_ = used_proxy_info;
@@ -1246,6 +1253,9 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
DCHECK(response_.headers.get());
+ if (response_.headers.get() && !ContentEncodingsValid())
+ return ERR_CONTENT_DECODING_FAILED;
+
// On a 408 response from the server ("Request Timeout") on a stale socket,
// retry the request.
// Headers can be NULL because of http://crbug.com/384554.
@@ -1711,4 +1721,47 @@ void HttpNetworkTransaction::CopyConnectionAttemptsFromStreamRequest() {
connection_attempts_.push_back(attempt);
}
+bool HttpNetworkTransaction::ContentEncodingsValid() const {
+ HttpResponseHeaders* headers = GetResponseHeaders();
+ DCHECK(headers);
+
+ std::string accept_encoding;
+ request_headers_.GetHeader(HttpRequestHeaders::kAcceptEncoding,
+ &accept_encoding);
+ std::set<std::string> allowed_encodings;
+ if (!HttpUtil::ParseAcceptEncoding(accept_encoding, &allowed_encodings)) {
+ FilterSourceStream::ReportContentDecodingRejected(
+ SourceStream::TYPE_INVALID);
+ return false;
+ }
+
+ std::string content_encoding;
+ headers->GetNormalizedHeader("Content-Encoding", &content_encoding);
+ std::set<std::string> used_encodings;
+ if (!HttpUtil::ParseContentEncoding(content_encoding, &used_encodings)) {
+ FilterSourceStream::ReportContentDecodingRejected(
+ SourceStream::TYPE_INVALID);
+ return false;
+ }
+
+ // When "Accept-Encoding" is not specified, or allows "*" encoding, then any
+ // encoding should be "accepted". This does not mean, that it will be
+ // successfully decoded.
Randy Smith (Not in Mondays) 2017/03/28 19:55:36 This test doesn't seem to be testing for the lack
eustas 2017/04/04 10:34:30 Updated comment.
+ if (allowed_encodings.find("*") != allowed_encodings.end())
+ return true;
Randy Smith (Not in Mondays) 2017/03/28 19:55:36 Move this up above the content encoding parsing?
eustas 2017/04/04 10:34:30 If we do so, then malformed header values go throu
+
+ for (auto const& encoding : used_encodings) {
+ SourceStream::SourceType source_type =
+ FilterSourceStream::ParseEncodingType(encoding);
+ // We don't reject encodings we are not aware. They just will not decode.
+ if (source_type == SourceStream::TYPE_UNKNOWN)
+ continue;
+ if (allowed_encodings.find(encoding) == allowed_encodings.end()) {
+ FilterSourceStream::ReportContentDecodingRejected(source_type);
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698