Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RequestRejectedException should be 400 by default #7568

Closed
brijesh15893 opened this issue Oct 25, 2019 · 12 comments
Closed

RequestRejectedException should be 400 by default #7568

brijesh15893 opened this issue Oct 25, 2019 · 12 comments
Assignees
Labels
in: core An issue in spring-security-core status: ideal-for-contribution An issue that we actively are looking for someone to help us with type: breaks-passivity A change that breaks passivity with the previous release type: enhancement A general enhancement
Milestone

Comments

@brijesh15893
Copy link

Summary

We are getting 500 from spring security jar if we use // in URL, ideally it should give 400 bad request.

Ex. - https://com.sap/Spring//Security - as it has // in URL is should give 400 bad request but we are getting 500

Actual Behavior

https://com.sap/Spring//Security - as it had // in URL is should give 400 bad request

Please describe step by step the behavior you are observing

Use any valid URL and add // in it ex. /ThingConfiguration/v1/Packages// and use spring security version - 5.1.5.RELEASE.

Expected Behavior

it should give 400 bad request

Configuration

Version

spring security version - 5.1.5.RELEASE.

Sample

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 25, 2019
@fhanik fhanik added in: core An issue in spring-security-core status: ideal-for-contribution An issue that we actively are looking for someone to help us with type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 29, 2019
@ankurpathak
Copy link
Contributor

@fhanik I would like to take this one.

@dadikovi
Copy link
Contributor

dadikovi commented May 1, 2020

Additional information:

It seems for me that in these cases the following exception is thrown:

org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL was not normalized. at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:248) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:194)

If I understand properly the task is here that this exception should be handled with 400 http status (not 500). I could find an analogous solution in the BearerTokenAuthenticationFilter, where the exception is passed to authenticationFailureHandler which will return the necessary status code.

So I think this issue should be solved with a similiar solution: maybe with authenticationFailureHandler, or with a new type of failure handler, which is called in org.springframework.security.web.FilterChainProxy#doFilterInternal if an exception is thrown.

@fhanik What do you think about this solution?
@ankurpathak Are you still working on this issue, or can I take it?

@rwinch
Copy link
Member

rwinch commented May 1, 2020

We cannot change the default, but you can now change the behavior with gh-7052

@rwinch rwinch changed the title if URL contains // Spring security giving 500 , it should be 400 RequestRejectedException should be 400 by default May 1, 2020
@rwinch rwinch added this to the 6.x milestone May 1, 2020
@rwinch rwinch added the type: breaks-passivity A change that breaks passivity with the previous release label May 1, 2020
dadikovi added a commit to dadikovi/spring-security that referenced this issue May 2, 2020
This commit changes default rejected handler to HttpStatusRequestRejectedHandler.

Fixes spring-projectsgh-7568
@dadikovi
Copy link
Contributor

dadikovi commented May 2, 2020

Well, I have a few questions, but for illustration I sent a draft commit too.

  • When I tested this exception was thrown from line 192 where the rejected exception is not cought. Is there any reason for this, or is it okay to move the exception catch to the doFilterInternal method itself (see my draft commit)
  • Is my understanding right that filterChainProxy should use HttpStatusRequestRejectedHandler instead of the default implementation?

@rwinch
Copy link
Member

rwinch commented May 4, 2020

When I tested this exception was thrown from line 192 where the rejected exception is not cought. Is there any reason for this, or is it okay to move the exception catch to the doFilterInternal method itself (see my draft commit)

This was the past behavior and it should remain this way for passivity. User's were encouraged to add their own error handling using a Filter or mapping the Exception to the servlet containers error handling

Is my understanding right that filterChainProxy should use HttpStatusRequestRejectedHandler instead of the default implementation?

This will not change until Spring Security 6.x

@walec51
Copy link

walec51 commented Jun 26, 2020

the default 500 code is just bad
change it to 400 in the next major release

@rwinch
Copy link
Member

rwinch commented Jun 29, 2020

@walec51 Yes The plan is to change the behavior in the next major release. We need to remain passive for those that may be catching the RequestRejectedException and handling it in the container error handling or within a Filter that is before Spring Security

@dratler
Copy link
Contributor

dratler commented Sep 21, 2020

Hi @rwinch ,
it this still for the greb ?

@rwinch
Copy link
Member

rwinch commented Oct 26, 2020

Yes, but it won't happen until 6.0 which we don't have branch for yet

burimshala-zz pushed a commit to burimshala-zz/nakadi that referenced this issue Feb 9, 2021
Spring firewall returns 500 when RequestRejectedException is thrown. The correct status code is 400.
This is going to be addressed by spring-projects/spring-security#7568
sparkbit-gerrit pushed a commit to sparkbitpl/sparkbit-commons that referenced this issue Feb 11, 2021
@ST-DDT
Copy link

ST-DDT commented Sep 9, 2021

I found a way to handle it according to my needs.

First the log level and status code:

@Override
public void handle(HttpServletRequest request, HttpServletResponse response, RequestRejectedException requestRejectedException) throws IOException {

	LOGGER.warn("Application firewall: {}", requestRejectedException.getMessage(),
			LOGGER.isDebugEnabled() ? requestRejectedException : null);

	request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, requestRejectedException);

	response.sendError(403, "firewall rejected");
}

And additionally the response body via the ErrorController I already had:
(This made me really happy since I don't have to care about the response Content-Type/serialization)

@RestController
public class ErrorPageController implements ErrorController {

    @RequestMapping("/error")
    public ResponseEntity<ErrorResponse> renderErrorPage(final HttpServletRequest request) {
        return new ResponseEntity(request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE), new ErrorResponse(request.getAttribute(RequestDispatcher.ERROR_EXCEPTION)));
    }

}

I would still prefer a simple @ExceptionHandler(RequestRejectedException.class)...

@wwang107
Copy link

wwang107 commented Apr 7, 2022

I used Kotlin and the following is my workaround

@Component
class RequestRejectedExceptionHandler : RequestRejectedHandler {

    override fun handle(
        request: HttpServletRequest,
        response: HttpServletResponse,
        requestRejectedException: RequestRejectedException
    ) {
        logger.warn(requestRejectedException.toString())
        response.sendError(HttpServletResponse.SC_BAD_REQUEST)
    }
}

@roeniss
Copy link

roeniss commented Oct 31, 2023

I coudn't find the history, but found the HttpStatusRequestRejectedHandler which returns 400 instead of 500.

my case:

  • org.springframework.boot:spring-boot-starter-security:2.4.4
    • org.springframework.security:spring-security-config:5.4.5

There were DefaultRequestRejectedHandler and HttpStatusRequestRejectedHandler. And the former was primary so I changed it with custom configuration:

// kotlin 
@Configuration
class RequestRejectedHandlerConfig {
    @Bean
    fun requestRejectedHandler(): RequestRejectedHandler {
        return HttpStatusRequestRejectedHandler()
    }
}

edit) I've noticed that DefaultRequestRejectedHandler actually redirects request to /error, so I just made another GetMapping instead of config bean:

@Controller
class ErrorController {
    @GetMapping("/error")
    fun error(): ResponseEntity<Any> {
        return ResponseEntity.status(400).build()
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core An issue in spring-security-core status: ideal-for-contribution An issue that we actively are looking for someone to help us with type: breaks-passivity A change that breaks passivity with the previous release type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests