Versions Compared

Key

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

...

Add a cryptographically secure anti-csrf token to the request context viewScope, on-entry to any view-state. Then check the returned token (in the HTTP request) matches that stored in the viewScope on proceed  a proceed event/transition. If the token is invalid, prevent execution of the transition and re-render the view, else proceed.

...

  • per-view (as on-entry, per request if on-render) synchroniser token - marginally safer than per-session or conversation etc. but more expensive. Although with the IdP only typically having one view a few views per flow, the efficiency/safety tradeoff is probably less of an issue.
  • the token only needs to be stored for the lifetime it is required e.g. in the viewscopeof the view state.
  • the token is only generated on view states, and is not generated when not needed e.g. when using a previous AuthenticationResult.

...

  • A CsrfToken API interface . This defines token implementations that return token values and HTTP parameter names.
    • packaged inside idp-session-api. Although this maybe better inside of java-support, or idp-ui?
  • A default implementation of CsrfToken, namely SimpleCsrfToken . Encapsulating both token value and HTTP parameter name as a non-empty Strings. Has no business logic.
    • packaged inside idp-session-api. Although this maybe better inside of java-support, or idp-ui?
  • A CsrfTokenManager to provide helper methods for generating and validating anti-csrf tokens .
    • packaged inside idp-session-impl. Although this maybe better inside of java-support, or idp-ui?
    • uses a configurable SecureRandomIdentifierGenerationStrategy to generate anti-csrf tokens - even though suitable, is generating a token and not an identifier.
    • currently fixed to a single implementation.contains predicate logic for token validation, but is not a Predicate type.
  • A ValidateCsrfToken action class. Extracts the CsrfToken from the requestContext viewScope and the CSRF token String value from the HTTP request. Delegates to the CsrfTokenManager to compare them, if equal (String comparison) signals a ‘success’ event, if different signals a ‘failure’ event. Note here, as this action is (see later sections) nested within a transaction, any event with ID other than ‘success’, ‘yes’, or ‘true’ will prevent the transaction from executing.
    •  is-a AbstractProfileAction, is not an AbstractValidationAction - it does not produce an AuthenticationResult.

...

The anti-csrf token is generated on-entry to a view state, and placed inside the SWF viewScope:. This could be added on-render if required.

Code Block
<on-entry>   		
   <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CsrfTokenManager').generateCsrfToken()" result="viewScope.csrfToken" /> 
</on-entry>

...

the anti-csrf token stored in the viewScope is then compared to that returned as a HTTP parameter from the view. This needs to happen (because the token is bound to the viewScope) inside the view-state before the proceed transition is executed and the state exited. Hence, a ValidateCsrfToken action is nested inside the proceed transition:

...

  • system wide enforcement of a synchroniser token based CSRF defence for SWF view-states.
    • For internal views and any custom views created as part of IdP flow extensions.
    • View-states can be excluded by configuration.
  • CSRF defence could be turned  easily be controlled (turned on/off as ) by a property in idp.properties - not implemented.
  • can, if configured correctly (e.g. catching invalid token exceptions in the flow), be used to show the default (or other) IdP error page with a custom message. Otherwise the generic uncaught exception message will be shown.
  • CSRF tokens are refreshed per view render. Arguably slightly stronger than, for example, per-session tokens, as they could be used along with the session ID in a session fixation type attack.

...

  • A CsrfToken API interface . This defines token implementations that return token values and HTTP parameter names.
    • packaged inside idp-session-api. Although this maybe better inside of java-support, or idp-ui?
  • A default implementation of CsrfToken, namely SimpleCsrfToken . Encapsulating both token value and HTTP parameter name as a non-empty Strings. Has no business logic.
    • packaged inside idp-session-api. Although this maybe better inside of java-support, or idp-ui?
  • A CsrfTokenManager to provide helper methods for generating and validating anti-csrf CSRF tokens .
    • packaged inside idp-session-impl. Although this maybe better inside of java-support, or idp-ui?
    • uses a configurable SecureRandomIdentifierGenerationStrategy to generate anti-csrf tokens - even though suitable, maybe an abuse of its definitionis generating a token and not an identifier..
    • currently fixed to a single implementation.
    • contains predicate logic for token validation, but is not a Predicate type.
  • A CsrfTokenFlowExecutionListener which reacts to SWF lifecycle events.
    • adds CSRF tokens to the viewScope when views are rendering.
    • checks the CSRF token in the request matches that stored in the view scope when a ‘proceed’ event occurs.
    • Can be configured to ignore or exclude certain view-states by ID.
  • An InvalidCsrfTokenException, subtype of FlowExecutionException, thrown when an invalid CSRF token is found.

...

To correctly transition the IdPEventIds.INVALID_CSRF_TOKEN eventID event ID to an error page, a transition needs to be placed in the action-state where the validation profile actions action is evaluated (see next section), and a global transition needs to be defined that maps to an end-state.

...

Changes to password authn flow

The anti-csrf CSRF token is taken from the CsrfUIContext and placed inside the SWF viewScope on-entry to render of the DisplayUsernamePasswordPage view-state (or any view-state as required):

...

Note, as the profile request context is already passed into the view, the CsrfUIContext and then token could be extracted by the view templating engine e.g. as is the case with the RelyingPartyContext in the login view.

...