CORS Filter

Versioned Documentation Transition

Repose is currently transitioning to a new versioned documentation system accessible from the Repose home page. This transition is planned for completion in Repose 9.

This page is valid for Repose versions: 7.2.0.0 – 8.2.0.0

The first versioned documentation for this filter is: 8.3.0.1

For future versions, refer to the Repose home page and select the desired version of Repose in the drop down menu in the top right corner.  You can also look at the latest version of this filter's documentation.

Purpose

The Cross-Origin Resource Sharing (CORS) filter enables Repose to respond to and facilitate CORS requests without the origin service needing to understand CORS.  For an introduction to CORS, see the CORS Overview below.

General filter information

Filter name: cors

Filter configuration: cors.cfg.xml

Release: 7.2.0.0 

Prerequisites

Headers:

  • Non-CORS requests
    • None required
  • Preflight CORS requests
    • Origin (supplied by the client)
    • Access-Control-Request-Method (supplied by the client)
  • Actual CORS requests
    • Origin (supplied by the client)

Preceding filters

The CORS filters should be one of the first filters (if not the first filter) in the filter chain in order to properly handle Preflight CORS requests.  If you want to rate limit Preflight requests, you can add these filters before the CORS filter:

The Rate Limiting filter would be in addition to any Rate Limiting filter you already have in your filter chain.  The first Rate Limiting filter would just filter by IP address, and the second Rate Limiting filter would rate limit on other attributes (e.g. user name, group info, etc.).  Preflight requests do not contain credentials which is why it needs to be one of the first filters.

Basic configuration

  1. To enable CORS, add the CORS filter to the system model.
    1. Add <filter name="cors"/> to the list of filters in system-model.cfg.xml
  2. Create a cors.cfg.xml file in /etc/repose with the desired configuration

Examples

The most basic CORS configuration would allow all origins to use any standard HTTP method on any resource.  This could expose vulnerabilities and is not recommended.


A more security conscious configuration would only allow specific origins to perform limited types of requests.

Optional configuration

Resource-specific Allowed Methods

If certain resources support additional methods, you can configure this per-resource using regex to specify the path or paths.  The resource configuration is processed in the configured order, so the first path regex to match the request URI will be used in conjunction with the global allowed-methods configuration when determining the complete list of allowed methods to return in response to a Preflight request.

Using this configuration, you would see the following responses for the specified requests:

Requested PathMatched PathAccess-Control-Allow-Methods
/v1/status/servers/v1/status.*GET, HEAD
/v1/status?status=destroyed/v1/status.*GET, HEAD
/v1/servers/v1/.*GET, HEAD, POST, PUT
/v2/servers/.*GET, HEAD, POST, PUT, PATCH, DELETE
/index.html/.*GET, HEAD, POST, PUT, PATCH, DELETE

Configurable parameters

XML schema definition

Example configuration

The cors.cfg.xml file contains the following elements and attributes. Add the filter to your Repose deployment through the system model configuration.

ElementsAttributes

Required /

Optional

Description
<cross-origin-resource-sharing>-RequiredSpecifies the sub-elements and attributes to define your CORS configuration.
<allowed-origins>-RequiredAllows you to specify which origins are allowed to request resources from this server.
<origin>-RequiredAn origin that is allowed to request resources from this server
regexOptionalAllows you to indicate that the value should be used as a regular expression.
Valid values: true | false (default) 
<allowed-methods>-OptionalAllows you to specify which HTTP methods are allowed for all resources (when specified under <cross-origin-resource-sharing>).
<method>-Optional (Required if
allowed-methods is provided)
An HTTP method that is allowed for all resources.
<resources>-OptionalAllows you to specify additional attributes on a per-resource basis.
<resource>-Optional (Required if
resources is provided)
Specifies configuration for a resource
pathOptional (Required if
resource is provided)
Indicates the regular expression to use when determining if a Request URI should use the configured values of this resource.
<allowed-methods>-OptionalAllows you to specify which HTTP methods are allowed for the matching resources in addition to the global list of allowed methods
(when specified under <resource>). 
<method>-Optional (Required if
allowed-methods is provided)
An HTTP method that is allowed under the specified resource.

Return codes and conditions

These are the scenarios in which the CORS filter will return a response without further processing the filter chain and hitting the origin service:

Response CodeRequest TypeReason
200Preflight RequestOrigin is allowed
403Preflight RequestOrigin not allowed
403Preflight RequestMethod not allowed
403Actual RequestOrigin not allowed
403Actual RequestMethod not allowed

Request headers created

This filter does not create any request headers.

CORS Overview

For security purposes, web browsers follow the Same-Origin policy.  If a user were to visit a website containing malicious code, the web browser would prevent the malicious code from trying to send requests to different websites on the user's behalf.  This is especially useful when the user is authenticated on those other websites.  However, sometimes we need to be able to get data and perform actions on different websites than the originating one.  This is where CORS comes in.

Instead of the web browser immediately denying any request intended for a different server, it will send the request with additional CORS headers.  One of these headers is the "Origin" header which indicates which website is responsible for sending the web browser to a different server.  If the response from the second server does not contain the appropriate CORS headers (i.e. the server is not CORS-aware) or if the CORS headers indicate the Origin is not allowed to send requests to it, the browser will drop the response (i.e. the client-side code will never get to see the contents of the response).

Even though the web browser prevents the client code from seeing the response, the request was still sent and potentially processed by the secondary server.  To mitigate potential server-side issues, the web browser will send a Preflight Request to first verify that the Origin and HTTP method are allowed (among a few other things) before sending the Actual Request.  If the response to the Preflight Request indicates the Actual Request wouldn't include the appropriate CORS headers that would allow the client code to process the response, the web browser will not proceed with sending the Actual Request.

A request is considered a Preflight Request if it meets the following:

  • HTTP method is "OPTIONS"
  • Header exists for "Origin"
  • Header exists for "Access-Control-Request-Method"

NOTE: Preflight Requests are completely handled by the CORS filter.  No other filters after the CORS filter will process them, and they won't reach the origin service.

A request will be considered an Actual Request if it meets the following:

  • Header exists for "Origin"
  • Header does not exist for "Access-Control-Request-Method"


Preflight Requests may be skipped for the following types of requests:

  • HTTP method is GET, HEAD, or POST
  • Headers do not include anything other than "Accept", "Accept-Language", "Content-Language", and "Content-Type" (assuming the values are "application/x-www-form-urlencoded", "multipart/form-data", or "text/plain").

NOTE: If your origin service requires a special header (e.g. X-Auth-Token), a Preflight Request will always be sent for CORS requests.