Add configuration property for Tomcat's rejectIllegalHeader

See gh-26311
pull/26879/head
David Byron 4 years ago committed by Stephane Nicoll
parent c1c1176020
commit e5a539d80e

@ -424,6 +424,11 @@ public class ServerProperties {
*/ */
private final Remoteip remoteip = new Remoteip(); private final Remoteip remoteip = new Remoteip();
/**
* reject illegal header setting.
*/
private Boolean rejectIllegalHeader;
public DataSize getMaxHttpFormPostSize() { public DataSize getMaxHttpFormPostSize() {
return this.maxHttpFormPostSize; return this.maxHttpFormPostSize;
} }
@ -572,6 +577,14 @@ public class ServerProperties {
return this.remoteip; return this.remoteip;
} }
public Boolean getRejectIllegalHeader() {
return this.rejectIllegalHeader;
}
public void setRejectIllegalHeader(Boolean rejectIllegalHeader) {
this.rejectIllegalHeader = rejectIllegalHeader;
}
/** /**
* Tomcat access log properties. * Tomcat access log properties.
*/ */

@ -117,6 +117,8 @@ public class TomcatWebServerFactoryCustomizer
.to((relaxedChars) -> customizeRelaxedPathChars(factory, relaxedChars)); .to((relaxedChars) -> customizeRelaxedPathChars(factory, relaxedChars));
propertyMapper.from(tomcatProperties::getRelaxedQueryChars).as(this::joinCharacters).whenHasText() propertyMapper.from(tomcatProperties::getRelaxedQueryChars).as(this::joinCharacters).whenHasText()
.to((relaxedChars) -> customizeRelaxedQueryChars(factory, relaxedChars)); .to((relaxedChars) -> customizeRelaxedQueryChars(factory, relaxedChars));
propertyMapper.from(tomcatProperties::getRejectIllegalHeader).whenNonNull()
.to((rejectIllegalHeader) -> customizeRejectIllegalHeader(factory, rejectIllegalHeader));
customizeStaticResources(factory); customizeStaticResources(factory);
customizeErrorReportValve(properties.getError(), factory); customizeErrorReportValve(properties.getError(), factory);
} }
@ -192,6 +194,16 @@ public class TomcatWebServerFactoryCustomizer
factory.addConnectorCustomizers((connector) -> connector.setProperty("relaxedQueryChars", relaxedChars)); factory.addConnectorCustomizers((connector) -> connector.setProperty("relaxedQueryChars", relaxedChars));
} }
private void customizeRejectIllegalHeader(ConfigurableTomcatWebServerFactory factory, boolean rejectIllegalHeader) {
factory.addConnectorCustomizers((connector) -> {
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractHttp11Protocol) {
AbstractHttp11Protocol<?> protocol = (AbstractHttp11Protocol<?>) handler;
protocol.setRejectIllegalHeader(rejectIllegalHeader);
}
});
}
private String joinCharacters(List<Character> content) { private String joinCharacters(List<Character> content) {
return content.stream().map(String::valueOf).collect(Collectors.joining()); return content.stream().map(String::valueOf).collect(Collectors.joining());
} }

@ -130,6 +130,7 @@ class ServerPropertiesTests {
map.put("server.tomcat.remoteip.protocol-header", "X-Forwarded-Protocol"); map.put("server.tomcat.remoteip.protocol-header", "X-Forwarded-Protocol");
map.put("server.tomcat.remoteip.remote-ip-header", "Remote-Ip"); map.put("server.tomcat.remoteip.remote-ip-header", "Remote-Ip");
map.put("server.tomcat.remoteip.internal-proxies", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); map.put("server.tomcat.remoteip.internal-proxies", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
map.put("server.tomcat.reject-illegal-header", "true");
map.put("server.tomcat.background-processor-delay", "10"); map.put("server.tomcat.background-processor-delay", "10");
map.put("server.tomcat.relaxed-path-chars", "|,<"); map.put("server.tomcat.relaxed-path-chars", "|,<");
map.put("server.tomcat.relaxed-query-chars", "^ , | "); map.put("server.tomcat.relaxed-query-chars", "^ , | ");
@ -152,6 +153,7 @@ class ServerPropertiesTests {
assertThat(tomcat.getRemoteip().getRemoteIpHeader()).isEqualTo("Remote-Ip"); assertThat(tomcat.getRemoteip().getRemoteIpHeader()).isEqualTo("Remote-Ip");
assertThat(tomcat.getRemoteip().getProtocolHeader()).isEqualTo("X-Forwarded-Protocol"); assertThat(tomcat.getRemoteip().getProtocolHeader()).isEqualTo("X-Forwarded-Protocol");
assertThat(tomcat.getRemoteip().getInternalProxies()).isEqualTo("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); assertThat(tomcat.getRemoteip().getInternalProxies()).isEqualTo("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
assertThat(tomcat.getRejectIllegalHeader()).isTrue();
assertThat(tomcat.getBackgroundProcessorDelay()).hasSeconds(10); assertThat(tomcat.getBackgroundProcessorDelay()).hasSeconds(10);
assertThat(tomcat.getRelaxedPathChars()).containsExactly('|', '<'); assertThat(tomcat.getRelaxedPathChars()).containsExactly('|', '<');
assertThat(tomcat.getRelaxedQueryChars()).containsExactly('^', '|'); assertThat(tomcat.getRelaxedQueryChars()).containsExactly('^', '|');
@ -405,6 +407,11 @@ class ServerPropertiesTests {
.isEqualTo(new RemoteIpValve().getInternalProxies()); .isEqualTo(new RemoteIpValve().getInternalProxies());
} }
@Test
void tomcatRejectIllegalHeaderDefaultsToNull() {
assertThat(this.properties.getTomcat().getRejectIllegalHeader()).isNull();
}
@Test @Test
void tomcatUseRelativeRedirectsDefaultsToFalse() { void tomcatUseRelativeRedirectsDefaultsToFalse() {
assertThat(this.properties.getTomcat().isUseRelativeRedirects()).isFalse(); assertThat(this.properties.getTomcat().isUseRelativeRedirects()).isFalse();

@ -320,6 +320,14 @@ class TomcatWebServerFactoryCustomizerTests {
assertThat(factory.getEngineValves()).isEmpty(); assertThat(factory.getEngineValves()).isEmpty();
} }
@Test
void testCustomizeRejectIllegalHeader() {
bind("server.tomcat.reject-illegal-header=false");
customizeAndRunServer((server) -> assertThat(
((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler())
.getRejectIllegalHeader()).isFalse());
}
@Test @Test
void errorReportValveIsConfiguredToNotReportStackTraces() { void errorReportValveIsConfiguredToNotReportStackTraces() {
TomcatWebServer server = customizeAndGetServer(); TomcatWebServer server = customizeAndGetServer();

Loading…
Cancel
Save