Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upProvide a way to handle RequestRejectedException #5007
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Jun-Yang
commented
Feb 23, 2018
|
I have the same issue in my project |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
hth
Mar 1, 2018
Cannot use Spring Security greater than 5.0.0. Unless fixed, all releases past 5.0.0 are moot
hth
commented
Mar 1, 2018
•
|
Cannot use Spring Security greater than 5.0.0. Unless fixed, all releases past 5.0.0 are moot |
rwinch
modified the milestones:
5.1.0,
5.1.0.M1
Mar 1, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rwinch
Mar 1, 2018
Member
We will look into this for 5.1. In the meantime, you can handle this by handling the exception (you should be doing this anyways).
Handle the Exception
Spring Boot
For example, with Spring Boot add ErrorPageRegistrar:
@Bean
public static ErrorPageRegistrar securityErrorPageRegistrar() {
return registry -> registry.addErrorPages(new ErrorPage(RequestRejectedException.class, "/errors/400"));
}@Controller
public class SecurityErrorController {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@RequestMapping("/errors/400")
String error(RequestRejectedException e) {
return "errors/400";
}
}src/main/java/resources/templates/errors/400.html
<html>
<head>
<title>Bad Request</title>
</head>
<body>
<h1>Bad Request</h1>
</body>
</html>
NOTE: Ensure the error page is public (i.e. permitAll) so that unauthenticated users are able to view the error page.
Servlet Container
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
...
<error-page>
<exception-type>org.springframework.security.web.firewall.RequestRejectedException</exception-type>
<location>/errors/400</location>
</error-page>
</web-app>
Ensure you add a URL mapping for /errors/400 which sets the status and renders the response you want.
NOTE: Ensure the error page is public (i.e. permitAll) so that unauthenticated users are able to view the error page.
Customizing HttpFirewall
You can also revert to the previous HttpFirewall or customize the StrictHttpFirewall by exposing a bean. Of course this is not recommended as it can lead to exploits.
|
We will look into this for 5.1. In the meantime, you can handle this by handling the exception (you should be doing this anyways). Handle the ExceptionSpring BootFor example, with Spring Boot add ErrorPageRegistrar: @Bean
public static ErrorPageRegistrar securityErrorPageRegistrar() {
return registry -> registry.addErrorPages(new ErrorPage(RequestRejectedException.class, "/errors/400"));
}@Controller
public class SecurityErrorController {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@RequestMapping("/errors/400")
String error(RequestRejectedException e) {
return "errors/400";
}
}
NOTE: Ensure the error page is public (i.e. permitAll) so that unauthenticated users are able to view the error page. Servlet Container
Ensure you add a URL mapping for NOTE: Ensure the error page is public (i.e. permitAll) so that unauthenticated users are able to view the error page. Customizing HttpFirewallYou can also revert to the previous |
rwinch
added
the
waiting-for-triage
label
Mar 1, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
hth
commented
Mar 1, 2018
•
|
I would recommend including #5044 with this issue |
rwinch
changed the title from
Access to non-normalized URIs causes HTTP 500
to
Provide a way to handle RequestRejectedException
Mar 19, 2018
PatrickGotthard
referenced this issue
Mar 19, 2018
Closed
Add URL to RequestRejectedException when rejecting requests #5107
rwinch
referenced this issue
Mar 21, 2018
Closed
Provide a way to swallow RequestRejectedException stacktrace #5149
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Glamdring
Mar 21, 2018
@rwinch I tried those but they still result in an unwanted stacktrace in the log, because the exception is happening outside the normal exception handling flow. Looking at the stacktrace, it is not caught anywhere and so can't be processed by exception or error page handlers
Glamdring
commented
Mar 21, 2018
•
|
@rwinch I tried those but they still result in an unwanted stacktrace in the log, because the exception is happening outside the normal exception handling flow. Looking at the stacktrace, it is not caught anywhere and so can't be processed by exception or error page handlers |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Glamdring
Mar 21, 2018
For anyone trying to get rid of the stacktrace and is running undertow:
@Bean
public UndertowServletWebServerFactory embeddedServletContainerFactory() {
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
factory.addDeploymentInfoCustomizers(new UndertowDeploymentInfoCustomizer() {
@Override
public void customize(DeploymentInfo deploymentInfo) {
deploymentInfo.setExceptionHandler(new ExceptionHandler() {
@Override
public boolean handleThrowable(HttpServerExchange exchange, ServletRequest request,
ServletResponse response, Throwable throwable) {
if (throwable instanceof RequestRejectedException) {
((HttpServletResponse) response).setStatus(HttpServletResponse.SC_BAD_REQUEST);
logger.warn("Request rejected due to: {} for URI {}", throwable.getMessage(),
((HttpServletRequest) request).getRequestURI());
return true;
}
return false;
}
});
}
});
}
Glamdring
commented
Mar 21, 2018
•
|
For anyone trying to get rid of the stacktrace and is running undertow:
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
gionn
Apr 18, 2018
Thanks to this new feature I discovered that Jetty was returning HTML errors for exception thrown outside of spring MVC.
To handle this RequestRejectedException I did:
contextHandler.setErrorHandler( new JsonErrorHandler() );and in JsonErrorHandler
public class JsonErrorHandler extends ErrorHandler
{
private final ObjectMapper mapper = new ObjectMapper();
@Override
protected void generateAcceptableResponse( Request baseRequest, HttpServletRequest request,
HttpServletResponse response, int code, String message, String mimeType ) throws IOException
{
response.setStatus( 400 );
baseRequest.setHandled( true );
Writer writer = getAcceptableWriter( baseRequest, request, response );
if ( writer != null )
{
response.setContentType( MimeTypes.Type.APPLICATION_JSON.asString() );
Throwable th = (Throwable) request.getAttribute( RequestDispatcher.ERROR_EXCEPTION );
writer.write( getPayload( th ) );
}
}getPayload should return a JSON string describing the error.
gionn
commented
Apr 18, 2018
•
|
Thanks to this new feature I discovered that Jetty was returning HTML errors for exception thrown outside of spring MVC. To handle this RequestRejectedException I did: contextHandler.setErrorHandler( new JsonErrorHandler() );and in JsonErrorHandler public class JsonErrorHandler extends ErrorHandler
{
private final ObjectMapper mapper = new ObjectMapper();
@Override
protected void generateAcceptableResponse( Request baseRequest, HttpServletRequest request,
HttpServletResponse response, int code, String message, String mimeType ) throws IOException
{
response.setStatus( 400 );
baseRequest.setHandled( true );
Writer writer = getAcceptableWriter( baseRequest, request, response );
if ( writer != null )
{
response.setContentType( MimeTypes.Type.APPLICATION_JSON.asString() );
Throwable th = (Throwable) request.getAttribute( RequestDispatcher.ERROR_EXCEPTION );
writer.write( getPayload( th ) );
}
}getPayload should return a JSON string describing the error. |
rwinch
modified the milestones:
5.1.0.M1,
5.1.0.M2
May 11, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bhunwal
Jul 3, 2018
@rwinch
I tried your solution, adding
@Bean
public static ErrorPageRegistrar securityErrorPageRegistrar() {
return registry -> registry.addErrorPages(new ErrorPage(RequestRejectedException.class, "/errors/400"));
}
but it is not working for me. do you have any pointer? spring is not forwarding the request to this endpoint. Checked and saw that this bean is initialised/picked up during startup.
after some debugging and searching I came accross
https://stackoverflow.com/questions/27825148/spring-boot-errorpage-not-working-with-standalone-tomcat
and
http://automateddeveloper.blogspot.com/2015/03/spring-boot-tomcat-error-handling.html
which says it wont work when deploying on standalone tomcat.
bhunwal
commented
Jul 3, 2018
•
|
@rwinch
but it is not working for me. do you have any pointer? spring is not forwarding the request to this endpoint. Checked and saw that this bean is initialised/picked up during startup. after some debugging and searching I came accross |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
hth
commented
Jul 6, 2018
|
Hope this one does not get pushed to another milestone. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
axelo
Jul 17, 2018
Another solution to skip the logging is using janino togheter with logback and filtering out the exception.
For example:
-
Add compile group: 'org.codehaus.janino', name: 'janino', version: '3.0.7' as a new dependency.
-
Edit / create logback-spring.xml.
And for the appropriate appender add a EvaluatorFilter using JaninoEventEvaluator ,
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
<expression>return throwable instanceof org.springframework.security.web.firewall.RequestRejectedException;</expression>
</evaluator>
<OnMismatch>NEUTRAL</OnMismatch>
<OnMatch>DENY</OnMatch>
</filter>
<encoder>
<Pattern>
${FILE_LOG_PATTERN}
</Pattern>
</encoder>
<file>${LOG_FILE}</file>
</appender>Now all RequestRejectedException logging should be filtered out by logback.
Some references:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
https://stackify.com/logging-logback/
axelo
commented
Jul 17, 2018
•
|
Another solution to skip the logging is using janino togheter with logback and filtering out the exception. For example:
And for the appropriate appender add a EvaluatorFilter using JaninoEventEvaluator , <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
<expression>return throwable instanceof org.springframework.security.web.firewall.RequestRejectedException;</expression>
</evaluator>
<OnMismatch>NEUTRAL</OnMismatch>
<OnMatch>DENY</OnMatch>
</filter>
<encoder>
<Pattern>
${FILE_LOG_PATTERN}
</Pattern>
</encoder>
<file>${LOG_FILE}</file>
</appender>Now all RequestRejectedException logging should be filtered out by logback. Some references: |
rwinch
modified the milestones:
5.1.0.M2,
5.1.0.RC1
Jul 26, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ct-parker
Aug 12, 2018
I implemented a workaround for this bug that is fairly flexible (see How to intercept a RequestRejectedException in Spring?). I also posted a second solution for those who simply want to suppress or control the logging. Essentially, I extended HttpStrictFirewall to add an attribute to the request that gets picked up by a downstream HandlerInterceptor. At this point, you can handle these like any other request while still utilizing the information from the firewall. It turned out that nearly all of the blocked requests were from clients with cookies disabled (;jsessionid= was in the URL). This included the Google indexer. I would not mind at all if the Spring Security developers used this as a model for making the HttpFirewall more flexible for developers.
ct-parker
commented
Aug 12, 2018
•
|
I implemented a workaround for this bug that is fairly flexible (see How to intercept a RequestRejectedException in Spring?). I also posted a second solution for those who simply want to suppress or control the logging. Essentially, I extended |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
hth
commented
Aug 25, 2018
|
Is this going to be resolved or its gone in oblivion? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rwinch
Aug 27, 2018
Member
@hth Thanks for the nudge.
With a reasonable workaround and lots to do we haven't had time to do it. If someone is interested in submitting a PR I'd be glad to help coach them through it.
|
@hth Thanks for the nudge. With a reasonable workaround and lots to do we haven't had time to do it. If someone is interested in submitting a PR I'd be glad to help coach them through it. |
mario-philipps-icw commentedFeb 8, 2018
Summary
With Spring Security 4.2.4 used in a Spring Boot application, accessing a "non-normalized" URI, e.g. one containing a double //, will cause an HTTP 500.
Actual Behavior
Access to a URI containing a double // causes an HTTP 500 response.
Expected Behavior
Access to such a URI causes some HTTP 4xx response, e.g. 400, 403 or 404. I'd expect that, because it's the client who has to change the request.
Version
Affected version is Spring Security 4.2.4.
Comment
I did some research in the code, and it looks as if the exception thrown in
spring-security/web/src/main/java/org/springframework/security/web/firewall/StrictHttpFirewall.java
Line 123 in 1517e9b