Skip to content

Commit fa9746a

Browse files
author
Kevin Dorosh
committed
PR comments; fix bug with large requests being allowed
Signed-off-by: Kevin Dorosh <kevin.dorosh@solo.io>
1 parent f47232f commit fa9746a

File tree

4 files changed

+27
-12
lines changed

4 files changed

+27
-12
lines changed

api/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ message ProxyProtocol {
4545
//
4646
// .. attention::
4747
//
48+
// This breaks conformance with the specification.
4849
// Only enable if ALL traffic to the listener comes from a trusted source.
4950
// For more information on the security implications of this feature, see
50-
// https://www.haproxy.org/download/1.9/doc/proxy-protocol.txt
51+
// https://www.haproxy.org/download/2.1/doc/proxy-protocol.txt
5152
//
5253
bool allow_requests_without_proxy_protocol = 2;
5354
}

source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc

+5-6
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void Filter::onRead() {
9393
if (read_state == ReadOrParseState::Error) {
9494
config_->stats_.downstream_cx_proxy_proto_error_.inc();
9595
cb_->continueFilterChain(false);
96-
} else if (read_state == ReadOrParseState::SkipFilterError) {
96+
} else if (read_state == ReadOrParseState::SkipFilter) {
9797
resetAndContinue(cb_->socket().ioHandle());
9898
}
9999
}
@@ -320,7 +320,7 @@ ReadOrParseState Filter::parseExtensions(Network::IoHandle& io_handle, uint8_t*
320320
const auto recv_result = io_handle.recv(buf, to_read, 0);
321321
if (!recv_result.ok()) {
322322
if (recv_result.err_->getErrorCode() == Api::IoError::IoErrorCode::Again) {
323-
return ReadOrParseState::TryAgainLaterError;
323+
return ReadOrParseState::TryAgainLater;
324324
}
325325
ENVOY_LOG(debug, "failed to read proxy protocol (no bytes avail)");
326326
return ReadOrParseState::Error;
@@ -435,7 +435,7 @@ ReadOrParseState Filter::readProxyHeader(Network::IoHandle& io_handle) {
435435

436436
if (!result.ok()) {
437437
if (result.err_->getErrorCode() == Api::IoError::IoErrorCode::Again) {
438-
return ReadOrParseState::TryAgainLaterError;
438+
return ReadOrParseState::TryAgainLater;
439439
}
440440
ENVOY_LOG(debug, "failed to read proxy protocol (no bytes read)");
441441
return ReadOrParseState::Error;
@@ -445,16 +445,15 @@ ReadOrParseState Filter::readProxyHeader(Network::IoHandle& io_handle) {
445445
if (nread < 1) {
446446
ENVOY_LOG(debug, "failed to read proxy protocol (no bytes read)");
447447
return ReadOrParseState::Error;
448-
} else if (nread < PROXY_PROTO_V2_HEADER_LEN &&
449-
config_.get()->allowRequestsWithoutProxyProtocol()) {
448+
} else if (config_.get()->allowRequestsWithoutProxyProtocol()) {
450449
if (memcmp(buf_, PROXY_PROTO_V1_SIGNATURE,
451450
std::min<size_t>(buf_off_ + nread, PROXY_PROTO_V1_SIGNATURE_LEN)) &&
452451
memcmp(buf_, PROXY_PROTO_V2_SIGNATURE,
453452
std::min<size_t>(buf_off_ + nread, PROXY_PROTO_V2_SIGNATURE_LEN))) {
454453
// the bytes we have seen so far do not match v1 or v2 proxy protocol, so we can safely
455454
// short-circuit
456455
ENVOY_LOG(debug, "request does not use v1 or v2 proxy protocol, forwarding as is");
457-
return ReadOrParseState::SkipFilterError;
456+
return ReadOrParseState::SkipFilter;
458457
}
459458
}
460459

source/extensions/filters/listener/proxy_protocol/proxy_protocol.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ using ConfigSharedPtr = std::shared_ptr<Config>;
7575

7676
enum ProxyProtocolVersion { Unknown = -1, InProgress = -2, V1 = 1, V2 = 2 };
7777

78-
enum class ReadOrParseState { Done, TryAgainLaterError, Error, SkipFilterError };
78+
enum class ReadOrParseState { Done, TryAgainLater, Error, SkipFilter };
7979

8080
/**
8181
* Implementation the PROXY Protocol listener filter

test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc

+19-4
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,30 @@ TEST_P(ProxyProtocolTest, V1Basic) {
222222
disconnect();
223223
}
224224

225-
TEST_P(ProxyProtocolTest, AllowNoProxyProtocol) {
226-
// allows request through even though it doesn't use proxy protocol
225+
TEST_P(ProxyProtocolTest, AllowTinyNoProxyProtocol) {
226+
// allows a small request (less bytes than v1/v2 header) through even though it doesn't use proxy
227+
// protocol
227228
envoy::extensions::filters::listener::proxy_protocol::v3::ProxyProtocol proto_config;
228229
proto_config.set_allow_requests_without_proxy_protocol(true);
229230
connect(true, &proto_config);
230231

231-
write("more data");
232+
write("data");
232233

233-
expectData("more data");
234+
expectData("data");
235+
236+
disconnect();
237+
}
238+
239+
TEST_P(ProxyProtocolTest, AllowLargeNoProxyProtocol) {
240+
// allows a large request (more bytes than v1/v2 header) through even though it doesn't use proxy
241+
// protocol
242+
envoy::extensions::filters::listener::proxy_protocol::v3::ProxyProtocol proto_config;
243+
proto_config.set_allow_requests_without_proxy_protocol(true);
244+
connect(true, &proto_config);
245+
246+
write("more data more data more data");
247+
248+
expectData("more data more data more data");
234249

235250
disconnect();
236251
}

0 commit comments

Comments
 (0)