Introduction and Context


Certain RESTful admin functions of the IdP e.g. account lockout, by default use IP authentication. Consequently, a Cross-Site Request Forgery (CSRF) attack would exploit the authorisation granted to the IP address of the users network host - from which the browser makes the request - to invoke certain admin functions cross site.

The IdP access policy implementation is highly customisable. Here, we describe a new access control mechanism based on a pre-shared secret or API key.

An API key would not be forgeable by an attacker (unless the key was exposed by other means), and would not (depending on the scheme used e.g. Basic Auth is cached by browsers) be re-sent by the browser when requesting the resource. As a result, this should prevent CSRF attacks.

Despite this, the simple API key mechanism described here may not be seen as a robust RESTful API security mechanism for the following reasons:

Despite this, an API key could still provide a stop-gap solution for the IdP’s RESTFul admin endpoints, it:

Implementation

The implementation can be found on my personal Git repository (git@git.shibboleth.net:philsmart/java-support), on the feature branch feature/access-control-apikey.

New Classes

There is only one new class and it’s associated JUnit test class:

Configuration

The APIKeyAccessControl bean is defined in the access-control-system.xml file.

<bean id="shibboleth.APIKeyAccessControl" abstract="true"
        class="net.shibboleth.utilities.java.support.security.APIKeyAccessControl" />

This can then be added to the shibboleth.AccessControlPolicies map e.g.

<entry key="AccessByApiKey">
            <bean id="AccessByApiKey" parent="shibboleth.APIKeyAccessControl" 
            p:apiKeyIn="#{T(net.shibboleth.utilities.java.support.security.APIKeyAccessControl.APIKeyIn).HEADER}"      
            p:apiKey="astrongapikey"/>
</entry>

Then configured as a policy on an appropriate admin function e.g. in general-admin.xml:

<bean parent="shibboleth.AdminFlow"
            c:id="http://shibboleth.net/ns/profiles/lockout-manager"
            p:loggingId="Lockout"
            p:policyName="AccessByApiKey" />

API Key Usage

The API Key is either placed - for every request - in the URL query string parameters, or a HTTP Authorization Header.

URL Query String Parameters

The API Key is added to the URL query parameters e.g.:

https://localhost:8443/idp/profile/admin/lockout/shibboleth.authn.Password.AccountLockoutManager/ss!127.0.0.1?shibapikey=thisisanapikey


HTTP Authorization Header with custom scheme

The HTTP Authorization header with a custom scheme is used to communicate the API key. The header syntax is:

Authorization: SHIB-API-KEY <key>

e.g.

Authorization: SHIB-API-KEY thisisanapikey

Note, a bypass for http headers could exist if the user agent was auto-injecting headers when requesting certain URLs e.g. a http header modification browser plugin.