Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Following on from CSRF Mitigation Options - Development Center - Shibboleth Wiki, here we explore how the CsrfFlowExecutionListener[1] CSRF mitigation technique can be applied to the IdP's external authentication mechanism, helping to help prevent Login CSRF across ‘external’ authentication strategies.

...

  • (1) Server-side with no client-side with user interaction
    • Server-side as part of a JSP scriplet inside a JSP compiled Servlet, or a generic custom Servlet. Either of which do not interact with the client e.g. do not write a response (HTML) back to the user-agent (browser mostly) to generate a UI which accepts user input.
  • (2) Server-side with client-side user interaction that does not deal with sensitive information.
    • Authenticaton Authentication that does require input from the user, but that input is not sensitive and could not be meaningfully manipulated by an attacker.
  • (3) Server-side with a single client-side user interaction where the user posts senstive sensitive information back to the server e.g. username and password.
    • Authentication which interacts with the user via the browser, such that the user posts login information (or invokes some sensitive operation etc.) back to the servlet before controlled is returned to the IdP.
  • (4) Server-side with many sensitive client-side user interactions.
    • Similar to (3), but the authentication mechanism may be invovled involved with multiple senstive sensitive interactions with the user before control is returned to the IdP.

For (1) and (2), as there is no interaction with the user which could be forged by an attacker, simply passing the a CSRF token in and out of the Servlet server-side authentication strategy provides no security benefit.

For (3), the developer must embedd the embed a CSRF token into any HTML forms that are written back to the client. Once POSTed back to the Servlet, the developer must (within that request/response cycle) call finishExternalAuthentication on the ExternalAuthentication API. The ExternalAuthenticationImpl then needs to gurantee guarantee the token is present in the redirect back to the IdP webflow.

For (4), The token becomes redundent A CSRF token is redundant for any interaction with the user that is not the final interaction before the token is sent back to the IdP to be checked. That is unless the developer of the authentication strategy takes responsibility for checking the token during each request.

In implementaitonimplementation, consideration must also be given to situations where CSRF protection has been disabled, and how best to communicate that to the developer.[1] The CsrfFlowExecutionListener provides a core cross-cutting security concern across IdP view states by injecting and validation CSRF tokens.

Implementation

If CSRF protection is enabled, and external view states are included by default, any external authentication servlet must adhere to the following process:

  • The CsrfFlowExecutionListener generates a CsrfToken when the ExternalTransfer view-state is reached.
    • The token is placed into the spring-webflow viewScope.
  • The token is then extracted from the spring-webflow viewScope and exposed to the external authentication servlet, either;
    • By injecting it into the ExternalAuthenticationImpl before the view is rendered in the view-scope, and placed inside the HTTP request attributes - see Option 1; or
    • The token is retrieved from the FlowExecution active session and exposed by the public ExternalAuthentication API - see Option 2.
  • The token should then be used, where sensible, inside any external authentication process flow that involves user interaction/input via the web browser. Nearly always, the token should be used inside HTML forms (and possibly AJAX post requests) that carry sensitive information or invoke senstive sensitive operations in the authentication flow. However, as listed discussed in the section aboveintroduction, not all external authentication strategies will benefit from this.
  • The token must then be present in the redirect back to the IdP and hence spring-webflow e.g. as a query parameter, where it can be evaluated by the CsrfTokenFlowExecutionListener against that stored in the viewScope.

...

Extend ExternalAuthenticationImpl to take a CsrfToken in its constructor (or as a parameter), and inject it during the sub context creation in the view-state (on-render).

...

To work as protection for a CSRF attack, the CSRF token parameter name and value must be embedded in HTTP forms sent in a response to the user-agent. For example, as a simple example in JSP:

Code Block
languagexml
linenumberstrue
<%@ page pageEncoding="UTF-8" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ page import="net.shibboleth.idp.authn.ExternalAuthentication" %>
<%@ page import="net.shibboleth.idp.authn.ExternalAuthenticationException" %>
<%@ page import="net.shibboleth.utilities.java.support.net.CsrfToken" %>
<%
CsrfToken csrfToken = null;
String redirect = null;
  try {
      final String key = ExternalAuthentication.startExternalAuthentication(request);
      csrfToken = ExternalAuthentication.getCsrfToken(key,request);
      redirect = ExternalAuthentication.getExternalRedirect("/idp/external.jsp",key);
 
  } catch (final ExternalAuthenticationException e) {
      throw new ServletException("Error processing external authentication request", e);
  }
%>
<form action="<%=redirect%>" method="post">
		<input name="username" id="username">
		 <input type="hidden" name="<%=csrfToken.getParameterName()%>" value="<%=csrfToken.getToken()%>" id="csrf_token">
		<input type="submit" value="Login">
</form>

...

Code Block
languagejava
response.sendRedirect(extContext.getFlowExecutionUrl()+"&csrf_token="+request.getParameter("csrf_token"));


---

[1] The CsrfFlowExecutionListener provides a core cross-cutting security concern across IdP view states by injecting and validation CSRF tokens.