uchicago / shibboleth-oidc

OpenID Connect support for the Shibboleth Identity Provider v3
Apache License 2.0
81 stars 19 forks source link

access to Shibboleth Service Provider causes error "Expected CSRF token not found" #33

Closed dominique-p closed 7 years ago

dominique-p commented 7 years ago

If in the file web.xml there is the following shibboleth-oidc documented filter mapping

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

then when accessing a Shibboleth SP (SAML) and authenticating to the IdP the user gets the following error: HTTP Status 403 - Expected CSRF token not found. Has your session expired?

This is presumably because the token used to prevent CSRF is only handled by the OIDC module and not by the base Shibboleth/SAML handlers.

To avoid this I changed the mapping to:

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/profile/oidc/*</url-pattern>
    </filter-mapping>

which restricts the Spring security checking that include the anti CSRF measures to just the OIDC handlers.

mmoayyed commented 7 years ago

In the login.vm and attribute-release.vm files, have you added the necessary tags to allow for CSRF?

Example: https://github.com/uchicago/shibboleth-oidc/blob/master/idp-webapp-overlay/src/main/webapp/idp/views/login.vm#L78

mmoayyed commented 7 years ago
<filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/profile/oidc/*</url-pattern>
    </filter-mapping>

Seems OK to me also.

dominique-p commented 7 years ago

The necessary csrf related tags are there, but only there:

find . -name '*.vm' |xargs grep -i csrf
./views/login.vm:#set ($csrfToken = $request.getAttribute("_csrf"))
./views/login.vm:<input type="hidden" name="$csrfToken.getParameterName()" value="$csrfToken.getToken()"/>
./views/intercept/attribute-release.vm:             #set ($csrfToken = $request.getAttribute("_csrf"))
./views/intercept/attribute-release.vm:             <input type="hidden" name="$csrfToken.getParameterName()" value="$csrfToken.getToken()"/>
./system/views/oidc/approve.vm:        <input type="hidden" name="csrf" value="$csrf.token" />

It's not in any other vm files (e.g. views/error.vm, views/logout.vm, intercept/terms-of-use.vm, etc.)

mmoayyed commented 7 years ago

Yeah those should be good. Those input/attribute elements are mostly needed during POST calls when the request travels through the Spring Security filter.

dominique-p commented 7 years ago

To be more precise, when the error message Expected CSRF token not found is displayed, the current URL shown by the browser is https://idp-lab.unige.ch/idp/profile/SAML2/POST/SSO. It happens before any other page is shown (no login page). Curiously no corresponding message is logged in idp-process.log (but the HTTP status 403 is logged in the tomcat access local_access_log).

dominique-p commented 7 years ago

Can you reproduce that? (i.e. with a default shibboleth-oidc installed on a vanilla IdP try to access a Shibboleth SP and observe that it causes the Expected CSRF token not found error)

mmoayyed commented 7 years ago

Relevant task https://github.com/uchicago/shibboleth-oidc/issues/43

mmoayyed commented 7 years ago

Unable to duplicate via https://github.com/uchicago/shibboleth-oidc/issues/43 Closing for now.