Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

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:

  • Key management is not easy:
    • Keys are not automatically rotated, they are manually managed in the IdP config. This would also require communication with those whom the keys are shared.
    • Keys are likely to be very long lived, widening the attack window.
    • Revoking keys requires config changes and a restart of the IdP.
    • The key does not carry fine grained role information - only the admin role. This single role, for the same key, can not be adjusted during its lifetime.
  • Keys are sent in clear text, are not signed or encrypted, and so require SSL/TLS everywhere they are communicated.
  • High key entropy needs to be enforced so they are not guessable - this can be validated when set.
  • The API key always carries the same authentication and authorization authority - even though they should strictly be used for authentication, and authorization determine by another means.e.g. some form of access management.
  • As with any pre-shared secret, clients must be trusted to manage the key appropriately i.e. not to disclose the key.
  • The raw key is exposed in the IdP’s config file.
    • This could be pre-hashed by the deployer, but this adds complexity around algorithm usage etc. which is not currently in scope of the implementation.

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

  • should ‘help prevent’ CSRF attacks that could take advantage of IP address authentication.
  • is simple for the deployer to configure.
  • is assumed most actors using the IdP’s admin endpoints would be ‘internal’ users or systems, and not uncontrollable end-users.
    • and probably a very limited number, thus simplifying key management.

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:

  • APIKeyAccessControl - an implementation of the AccessControl interface.
    • Extracts the API key from either the HTTP Authorization header (using the Authentication Framework [rfc7235] with custom scheme), or the URL query string parameters.
      • Defaults to HTTP Header extraction. This is arguably safer than URL extraction, as URLs are saved in browser histories, server logs, and can be cut and paste into emails etc.
      • The custom authorization scheme should be defined, is not currently.
      • The HTTP Authorization header mechanism only supports preemptive authentication / authorization. It does not support challenge response e.g. WWW-Authenticate.
    • The API Key has to be created by the deployer, and set in the access-control configuration.
      • A customisable key validation policy predicate can be injected to validate the key against a predefined policy on initialisation. A simple key length policy is configured by default.

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. 

  • No labels