Prevents padding headers from being indexed

This commit is contained in:
klzgrad 2020-05-23 22:22:33 +08:00
parent c434911a6d
commit 28cf37d673
2 changed files with 51 additions and 5 deletions

View File

@ -16,6 +16,7 @@
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/log/net_log.h"
#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
namespace net {
@ -27,6 +28,24 @@ constexpr int kResponseHeaderSize = sizeof(kResponseHeader) - 1;
// A plain 200 is 10 bytes. Expected 48 bytes. "Padding" uses up 7 bytes.
constexpr int kMinPaddingSize = 30;
constexpr int kMaxPaddingSize = kMinPaddingSize + 32;
bool g_nonindex_codes_initialized;
uint8_t g_nonindex_codes[17];
void InitializeNonindexCodes() {
if (g_nonindex_codes_initialized)
return;
g_nonindex_codes_initialized = true;
unsigned i = 0;
for (const auto& symbol : spdy::HpackHuffmanCodeVector()) {
if (symbol.id >= 0x20 && symbol.id <= 0x7f && symbol.length >= 8) {
g_nonindex_codes[i++] = symbol.id;
if (i >= sizeof(g_nonindex_codes))
break;
}
}
CHECK(i == sizeof(g_nonindex_codes));
}
} // namespace
HttpProxySocket::HttpProxySocket(
@ -40,7 +59,9 @@ HttpProxySocket::HttpProxySocket(
was_ever_used_(false),
header_write_size_(-1),
net_log_(transport_->NetLog()),
traffic_annotation_(traffic_annotation) {}
traffic_annotation_(traffic_annotation) {
InitializeNonindexCodes();
}
HttpProxySocket::~HttpProxySocket() {
Disconnect();
@ -308,7 +329,13 @@ int HttpProxySocket::DoHeaderWrite() {
handshake_buf_ = base::MakeRefCounted<IOBuffer>(header_write_size_);
char* p = handshake_buf_->data();
std::memcpy(p, kResponseHeader, kResponseHeaderSize);
std::memset(p + kResponseHeaderSize, '.', padding_size);
std::memset(p + kResponseHeaderSize, g_nonindex_codes[16], padding_size);
// Prevents index reuse
uint64_t bits = base::RandUint64();
for (int i = 0; i < 16; i++) {
p[kResponseHeaderSize + i] = g_nonindex_codes[bits & 0b1111];
bits >>= 4;
}
std::memcpy(p + kResponseHeaderSize + padding_size, "\r\n\r\n", 4);
return transport_->Write(handshake_buf_.get(), header_write_size_,

View File

@ -58,6 +58,7 @@
#include "net/socket/udp_server_socket.h"
#include "net/ssl/ssl_key_logger_impl.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
#include "net/tools/naive/naive_proxy.h"
#include "net/tools/naive/redirect_resolver.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@ -392,7 +393,18 @@ class ProxyServer;
namespace {
class NaiveProxyDelegate : public ProxyDelegate {
public:
NaiveProxyDelegate(const Params& params) : params_(params) {}
NaiveProxyDelegate(const Params& params) : params_(params) {
unsigned i = 0;
for (const auto& symbol : spdy::HpackHuffmanCodeVector()) {
if (symbol.id >= 0x20 && symbol.id <= 0x7f && symbol.length >= 8) {
nonindex_codes_[i++] = symbol.id;
if (i >= sizeof(nonindex_codes_))
break;
}
}
CHECK(i == sizeof(nonindex_codes_));
}
void OnResolveProxy(const GURL& url,
const std::string& method,
const ProxyRetryInfoMap& proxy_retry_info,
@ -401,8 +413,14 @@ class NaiveProxyDelegate : public ProxyDelegate {
void OnBeforeTunnelRequest(const ProxyServer& proxy_server,
HttpRequestHeaders* extra_headers) override {
extra_headers->SetHeader("Padding",
std::string(base::RandInt(16, 32), '.'));
std::string padding(base::RandInt(16, 32), nonindex_codes_[16]);
// Prevents index reuse
uint64_t bits = base::RandUint64();
for (int i = 0; i < 16; i++) {
padding[i] = nonindex_codes_[bits & 0b1111];
bits >>= 4;
}
extra_headers->SetHeader("Padding", padding);
extra_headers->MergeFrom(params_.extra_headers);
}
@ -414,6 +432,7 @@ class NaiveProxyDelegate : public ProxyDelegate {
private:
const Params& params_;
uint8_t nonindex_codes_[17];
};
std::unique_ptr<URLRequestContext> BuildCertURLRequestContext(NetLog* net_log) {