mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
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 <shawkins@redhat.com> * Update docs/guides/server/reverseproxy.adoc Co-authored-by: Martin Bartoš <mabartos@redhat.com> Signed-off-by: Steven Hawkins <shawkins@redhat.com> --------- Signed-off-by: Steve Hawkins <shawkins@redhat.com> Signed-off-by: Steven Hawkins <shawkins@redhat.com> Co-authored-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
parent
9bf0af612a
commit
a819a213f9
@ -28,7 +28,7 @@ You only need to proxy port `8443` (or `8080`) even when you use different host
|
||||
|
||||
{project_name} will parse the reverse proxy headers based on the `proxy-headers` option which accepts several values:
|
||||
|
||||
* By default if the option is not specified, no reverse proxy headers are parsed.
|
||||
* 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.
|
||||
* `forwarded` enables parsing of the `Forwarded` header as per https://www.rfc-editor.org/rfc/rfc7239.html[RFC7239].
|
||||
* `xforwarded` enables parsing of non-standard `X-Forwarded-*` headers, such as `X-Forwarded-For`, `X-Forwarded-Proto`, `X-Forwarded-Host`, and `X-Forwarded-Port`.
|
||||
|
||||
@ -38,7 +38,7 @@ For example:
|
||||
|
||||
<@kc.start parameters="--proxy-headers forwarded"/>
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
Take extra precautions to ensure that the client address is properly set by your reverse proxy via the `Forwarded` or `X-Forwarded-For` headers.
|
||||
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:
|
||||
|
||||
== PROXY Protocol
|
||||
|
||||
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 `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.
|
||||
|
||||
This is useful when running behind a compatible https passthrough proxy because the request headers cannot be manipulated.
|
||||
|
||||
|
||||
@ -13,10 +13,10 @@ public class ProxyOptions {
|
||||
.category(OptionCategory.PROXY)
|
||||
.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.")
|
||||
.build();
|
||||
|
||||
|
||||
public static final Option<Boolean> PROXY_PROTOCOL_ENABLED = new OptionBuilder<>("proxy-protocol-enabled", Boolean.class)
|
||||
.category(OptionCategory.PROXY)
|
||||
.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.")
|
||||
.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.")
|
||||
.defaultValue(Boolean.FALSE)
|
||||
.build();
|
||||
|
||||
@ -34,7 +34,7 @@ public class ProxyOptions {
|
||||
.category(OptionCategory.PROXY)
|
||||
.defaultValue(Boolean.FALSE)
|
||||
.build();
|
||||
|
||||
|
||||
public static final Option<List<String>> PROXY_TRUSTED_ADDRESSES = OptionBuilder.listOptionBuilder("proxy-trusted-addresses", String.class)
|
||||
.category(OptionCategory.PROXY)
|
||||
.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.")
|
||||
|
||||
@ -21,6 +21,11 @@ final class ProxyPropertyMappers {
|
||||
.build(),
|
||||
fromOption(ProxyOptions.PROXY_PROTOCOL_ENABLED)
|
||||
.to("quarkus.http.proxy.use-proxy-protocol")
|
||||
.validator(v -> {
|
||||
if (Boolean.parseBoolean(v) && Configuration.getOptionalKcValue(ProxyOptions.PROXY_HEADERS).isPresent()) {
|
||||
throw new PropertyException("proxy protocol cannot be enabled when using the `proxy-headers` option");
|
||||
}
|
||||
})
|
||||
.build(),
|
||||
fromOption(ProxyOptions.PROXY_FORWARDED_HOST)
|
||||
.to("quarkus.http.proxy.enable-forwarded-host")
|
||||
@ -42,7 +47,7 @@ final class ProxyPropertyMappers {
|
||||
.build()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static void validateAddress(String address) {
|
||||
if (Inet.parseCidrAddress(address) != null) {
|
||||
return;
|
||||
|
||||
@ -573,4 +573,11 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
nonRunningPicocli = pseudoLaunch("start-dev", "--log=syslog", "--log-syslog-output=json", "--log-syslog-json-format=ecs");
|
||||
assertEquals(CommandLine.ExitCode.OK, nonRunningPicocli.exitCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void proxyProtolNotAllowedWithProxyHeaders() {
|
||||
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start-dev", "--proxy-headers=forwarded", "--proxy-protocol-enabled=true");
|
||||
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
|
||||
assertThat(nonRunningPicocli.getErrString(), containsString(" protocol cannot be enabled when using the `proxy-headers` option"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,7 +265,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -316,7 +316,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -272,7 +272,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -317,7 +317,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -222,7 +222,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -267,7 +267,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -271,7 +271,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -316,7 +316,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -269,7 +269,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
@ -314,7 +314,8 @@ Proxy:
|
||||
--proxy-protocol-enabled <true|false>
|
||||
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. Default: false.
|
||||
one from the actual connecting client. Cannot be enabled when the
|
||||
`proxy-headers` is used. Default: false.
|
||||
--proxy-trusted-addresses <trusted proxies>
|
||||
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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user