Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring option create-session="never" is ignored in some scenarios?

For some web services I want to disable use of sessions. I added create-session="never" to the config:

<beans:bean id="http403EntryPoint"
    class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<http use-expressions="true" entry-point-ref="http403EntryPoint"
    create-session="never">
    <custom-filter ref="x509Filter" position="PRE_AUTH_FILTER"/>
</http>

This works for most cases, except when the pre-authenticated user has a client certificate which is not registered in the application, so our AuthenticationUserDetailsService throws a UsernameNotFoundException. If the user has no certificate or has a registered certificate, no session is created (no Set-Cookie header in the HTTP response). In the described case a cookie is sent. It (the cookie respectively the session) is also evaluated on each following request, even if the client certificate is changed (basically allowing a session fixation attack - the app uses the saved authentication instead of re-authenticating on each call).

We use Spring security 3.0.5. Tested with Tomcat 6 and 7 and also JBoss 7.1.1.

Why is a session created in the described scenario?

PS: The session fixation problem can be probably workarounded by setting checkForPrincipalChanges in the AbstractPreAuthenticatedProcessingFilter, but I am interested in the answer to why a session is created at all.

like image 537
David Balažic Avatar asked Apr 29 '15 14:04

David Balažic


1 Answers

The culprit was https://jira.spring.io/browse/SEC-1476 :

In case of unauthorized access the following method in class AbstractPreAuthenticatedProcessingFilter would create a session and store the exception there:

protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {
    SecurityContextHolder.clearContext();

    if (logger.isDebugEnabled()) {
        logger.debug("Cleared security context due to exception", failed);
    }
    request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, failed);
}

In the fix they changed the last line, they removed the getSession() call so the AuthenticationException is stored in the request.

To fix our project I created a new class that extends X509AuthenticationFilter and there I overrode the method unsuccessfulAuthentication with same content except I also removed the getSession() call.

like image 187
David Balažic Avatar answered Dec 16 '22 06:12

David Balažic