The PROXY protocol spec specifically indicates that a receiver should not try to guess whether or not a PROXY protocol header is present[1]:

The receiver MUST be configured to only receive the protocol described in this specification and MUST not try to guess whether the protocol header is present or not. This means that the protocol explicitly prevents port sharing between public and private access. Otherwise it would open a major security breach by allowing untrusted parties to spoof their connection addresses. The receiver SHOULD ensure proper access filtering so that only trusted proxies are allowed to use this protocol.

I have an (unfortunate) scenario where traffic to the same backend may be arriving through either an HAProxy *or* a Citrix NetScaler where source IP information needs to be passed to the backend, at least during a DNS swing from one to the other while records TTL out.

The spec as I read it intends to protect against a malicious actor sending traffic with a PROXY protocol header set with an arbitrary client IP. In other words, the "MUST NOT" directive is there to ensure that backends that are not *explicitly* configured to receive PROXY protocol traffic can't be tricked into treating traffic from a random host as PROXY protocol traffic.

Is that correct?

Is it against the spirit or letter of the spec, though, to test not for the absence or presence of the PROXY protocol header itself but rather (a) whether the PROXY protocol version is 1 or 2 and (b) if another client source IP preservation/representation protocol, like the Citrix Client IP option, is in use? Or does that still expose a possible exploit vector? Protections could still be provided to the backend servers in either case such that PROXY protocol traffic or Citrix Client IP traffic would only be permitted from known/trusted proxies.

I haven't been able to brainstorm a weakness/exploit in that type of setup, as it would basically amount to (pseudo-code):

if header.type == "proxyv1":
    # do PROXY protocol v1 stuff
elif header.type == "proxyv2":
    # do PROXY protocol v2 stuff
elif header.type == "cip":
    # do Citrix Client IP stuff
    # no good; drop it like it's hot

...with the network configured to permit only trusted proxies to talk directly to the backends.

Unless I'm missing something?

Hugo Slabbert       | email, xmpp/jabber:
pgp key: B178313E   | also on Signal


Attachment: signature.asc
Description: Digital signature

Reply via email to