Summary

It seems the SwitchUserFilter responds to all HTTP methods, making it vulnerable to CSRF attacks.

Actual Behavior

SwitchUserFilter works for all HTTP methods and only needs a username parameter, j_username (3.2) or username (4.x) by default.

Expected Behavior

I think the list of HTTP methods the SwitchUserFilter accepts should be configurable, and limited to POST by default, to let the CsrfFilter do its job.

Version

All, up to 4.2.1.

Comment From: typekpb

This is a serious issue. Any chance to provide the workaround or the fix anytime soon?

Comment From: jzheaux

Note that working around this is already possible via setSwitchUserMatcher and setExitUserMatcher:

SwitchUserFilter switchUserFilter() throws Exception {
    RequestMatcher onlyPost = new AntPathRequestMatcher(
            "/login/impersonate", "POST", true, new UrlPathHelper());
    SwitchUserFilter filter = new SwitchUserFilter();
    // ... other filter configuration
    filter.setSwitchUserMatcher(onlyPost);
    filter.setExitUserMatcher(onlyPost);
    filter.afterPropertiesSet();
    return filter;
}

Comment From: jzheaux

Since this fix breaks passivity, I'll also mention here how to restore the old behavior for anyone who may need it.

To allow /login/impersonate for any endpoint, set the switchUserMatcher and exitUserMatcher properties:

SwitchUserFilter switchUserFilter() throws Exception {
    RequestMatcher anyMethod = new AntPathRequestMatcher(
            "/login/impersonate", null, true, new UrlPathHelper());
    SwitchUserFilter filter = new SwitchUserFilter();
    // ... other filter configuration
    filter.setSwitchUserMatcher(anyMethod);
    filter.setExitUserMatcher(anyMethod);
    filter.afterPropertiesSet();
    return filter;
}