Skip to content

Commit a819a21

Browse files
shawkinsmabartos
andauthored
fix: hardening to prevent usage of proxy-protocol with proxy-headers (#37463)
* fix: hardening to prevent usage of proxy-protocol with proxy-headers closes: #37458 Signed-off-by: Steve Hawkins <[email protected]> * Update docs/guides/server/reverseproxy.adoc Co-authored-by: Martin Bartoš <[email protected]> Signed-off-by: Steven Hawkins <[email protected]> --------- Signed-off-by: Steve Hawkins <[email protected]> Signed-off-by: Steven Hawkins <[email protected]> Co-authored-by: Martin Bartoš <[email protected]>
1 parent 9bf0af6 commit a819a21

14 files changed

+39
-17
lines changed

docs/guides/server/reverseproxy.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ You only need to proxy port `8443` (or `8080`) even when you use different host
2828

2929
{project_name} will parse the reverse proxy headers based on the `proxy-headers` option which accepts several values:
3030

31-
* By default if the option is not specified, no reverse proxy headers are parsed.
31+
* By default if the option is not specified, no reverse proxy headers are parsed. This should be used when no proxy is in use or with https passthrough.
3232
* `forwarded` enables parsing of the `Forwarded` header as per https://www.rfc-editor.org/rfc/rfc7239.html[RFC7239].
3333
* `xforwarded` enables parsing of non-standard `X-Forwarded-*` headers, such as `X-Forwarded-For`, `X-Forwarded-Proto`, `X-Forwarded-Host`, and `X-Forwarded-Port`.
3434

@@ -38,7 +38,7 @@ For example:
3838

3939
<@kc.start parameters="--proxy-headers forwarded"/>
4040

41-
WARNING: If either `forwarded` or `xforwarded` is selected, make sure your reverse proxy properly sets and overwrites the `Forwarded` or `X-Forwarded-*` headers respectively. To set these headers, consult the documentation for your reverse proxy. Misconfiguration will leave {project_name} exposed to security vulnerabilities.
41+
WARNING: If either `forwarded` or `xforwarded` is selected, make sure your reverse proxy properly sets and overwrites the `Forwarded` or `X-Forwarded-*` headers respectively. To set these headers, consult the documentation for your reverse proxy. Do not use `forwarded` or `xforwarded` with https passthrough. Misconfiguration will leave {project_name} exposed to security vulnerabilities.
4242

4343
Take extra precautions to ensure that the client address is properly set by your reverse proxy via the `Forwarded` or `X-Forwarded-For` headers.
4444
If this header is incorrectly configured, rogue clients can set this header and trick {project_name} into thinking the client is connected from a different IP address than the actual address. This precaution can be more critical if you do any deny or allow listing of IP addresses.
@@ -146,7 +146,7 @@ For example:
146146

147147
== PROXY Protocol
148148

149-
The `proxy-protocol-enabled` option controls whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the one from the actual connecting client.
149+
The `proxy-protocol-enabled` option controls whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the one from the actual connecting client. The value cannot be `true` when using the `proxy-headers` option.
150150

151151
This is useful when running behind a compatible https passthrough proxy because the request headers cannot be manipulated.
152152

quarkus/config-api/src/main/java/org/keycloak/config/ProxyOptions.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ public enum Headers {
1313
.category(OptionCategory.PROXY)
1414
.description("The proxy headers that should be accepted by the server. Misconfiguration might leave the server exposed to security vulnerabilities. Takes precedence over the deprecated proxy option.")
1515
.build();
16-
16+
1717
public static final Option<Boolean> PROXY_PROTOCOL_ENABLED = new OptionBuilder<>("proxy-protocol-enabled", Boolean.class)
1818
.category(OptionCategory.PROXY)
19-
.description("Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the one from the actual connecting client.")
19+
.description("Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the one from the actual connecting client. Cannot be enabled when the `proxy-headers` is used.")
2020
.defaultValue(Boolean.FALSE)
2121
.build();
2222

@@ -34,7 +34,7 @@ public enum Headers {
3434
.category(OptionCategory.PROXY)
3535
.defaultValue(Boolean.FALSE)
3636
.build();
37-
37+
3838
public static final Option<List<String>> PROXY_TRUSTED_ADDRESSES = OptionBuilder.listOptionBuilder("proxy-trusted-addresses", String.class)
3939
.category(OptionCategory.PROXY)
4040
.description("A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. A trusted proxy address is specified as an IP address (IPv4 or IPv6) or Classless Inter-Domain Routing (CIDR) notation.")

quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/ProxyPropertyMappers.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ public static PropertyMapper<?>[] getProxyPropertyMappers() {
2121
.build(),
2222
fromOption(ProxyOptions.PROXY_PROTOCOL_ENABLED)
2323
.to("quarkus.http.proxy.use-proxy-protocol")
24+
.validator(v -> {
25+
if (Boolean.parseBoolean(v) && Configuration.getOptionalKcValue(ProxyOptions.PROXY_HEADERS).isPresent()) {
26+
throw new PropertyException("proxy protocol cannot be enabled when using the `proxy-headers` option");
27+
}
28+
})
2429
.build(),
2530
fromOption(ProxyOptions.PROXY_FORWARDED_HOST)
2631
.to("quarkus.http.proxy.enable-forwarded-host")
@@ -42,7 +47,7 @@ public static PropertyMapper<?>[] getProxyPropertyMappers() {
4247
.build()
4348
};
4449
}
45-
50+
4651
private static void validateAddress(String address) {
4752
if (Inet.parseCidrAddress(address) != null) {
4853
return;

quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/cli/PicocliTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,4 +573,11 @@ public void logSyslogJsonFormat() {
573573
nonRunningPicocli = pseudoLaunch("start-dev", "--log=syslog", "--log-syslog-output=json", "--log-syslog-json-format=ecs");
574574
assertEquals(CommandLine.ExitCode.OK, nonRunningPicocli.exitCode);
575575
}
576+
577+
@Test
578+
public void proxyProtolNotAllowedWithProxyHeaders() {
579+
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start-dev", "--proxy-headers=forwarded", "--proxy-protocol-enabled=true");
580+
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
581+
assertThat(nonRunningPicocli.getErrString(), containsString(" protocol cannot be enabled when using the `proxy-headers` option"));
582+
}
576583
}

quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.approved.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ Proxy:
265265
--proxy-protocol-enabled <true|false>
266266
Whether the server should use the HA PROXY protocol when serving requests from
267267
behind a proxy. When set to true, the remote address returned will be the
268-
one from the actual connecting client. Default: false.
268+
one from the actual connecting client. Cannot be enabled when the
269+
`proxy-headers` is used. Default: false.
269270
--proxy-trusted-addresses <trusted proxies>
270271
A comma separated list of trusted proxy addresses. If set, then proxy headers
271272
from other addresses will be ignored. By default all addresses are trusted.

quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.approved.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ Proxy:
316316
--proxy-protocol-enabled <true|false>
317317
Whether the server should use the HA PROXY protocol when serving requests from
318318
behind a proxy. When set to true, the remote address returned will be the
319-
one from the actual connecting client. Default: false.
319+
one from the actual connecting client. Cannot be enabled when the
320+
`proxy-headers` is used. Default: false.
320321
--proxy-trusted-addresses <trusted proxies>
321322
A comma separated list of trusted proxy addresses. If set, then proxy headers
322323
from other addresses will be ignored. By default all addresses are trusted.

quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.approved.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ Proxy:
272272
--proxy-protocol-enabled <true|false>
273273
Whether the server should use the HA PROXY protocol when serving requests from
274274
behind a proxy. When set to true, the remote address returned will be the
275-
one from the actual connecting client. Default: false.
275+
one from the actual connecting client. Cannot be enabled when the
276+
`proxy-headers` is used. Default: false.
276277
--proxy-trusted-addresses <trusted proxies>
277278
A comma separated list of trusted proxy addresses. If set, then proxy headers
278279
from other addresses will be ignored. By default all addresses are trusted.

quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.approved.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,8 @@ Proxy:
317317
--proxy-protocol-enabled <true|false>
318318
Whether the server should use the HA PROXY protocol when serving requests from
319319
behind a proxy. When set to true, the remote address returned will be the
320-
one from the actual connecting client. Default: false.
320+
one from the actual connecting client. Cannot be enabled when the
321+
`proxy-headers` is used. Default: false.
321322
--proxy-trusted-addresses <trusted proxies>
322323
A comma separated list of trusted proxy addresses. If set, then proxy headers
323324
from other addresses will be ignored. By default all addresses are trusted.

quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.approved.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ Proxy:
222222
--proxy-protocol-enabled <true|false>
223223
Whether the server should use the HA PROXY protocol when serving requests from
224224
behind a proxy. When set to true, the remote address returned will be the
225-
one from the actual connecting client. Default: false.
225+
one from the actual connecting client. Cannot be enabled when the
226+
`proxy-headers` is used. Default: false.
226227
--proxy-trusted-addresses <trusted proxies>
227228
A comma separated list of trusted proxy addresses. If set, then proxy headers
228229
from other addresses will be ignored. By default all addresses are trusted.

quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.approved.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ Proxy:
267267
--proxy-protocol-enabled <true|false>
268268
Whether the server should use the HA PROXY protocol when serving requests from
269269
behind a proxy. When set to true, the remote address returned will be the
270-
one from the actual connecting client. Default: false.
270+
one from the actual connecting client. Cannot be enabled when the
271+
`proxy-headers` is used. Default: false.
271272
--proxy-trusted-addresses <trusted proxies>
272273
A comma separated list of trusted proxy addresses. If set, then proxy headers
273274
from other addresses will be ignored. By default all addresses are trusted.

0 commit comments

Comments
 (0)