Using ModHeader to test CORS

What is CORS?

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which browsers make a "preflight" request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.

An example of a cross-origin request: the front-end JavaScript code served from https://domain-a.com uses XMLHttpRequest to make a request for https://domain-b.com/data.json.

For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the right CORS headers.

The CORS mechanism supports secure cross-origin requests and data transfers between browsers and servers. Modern browsers use CORS in APIs such as XMLHttpRequest or Fetch to mitigate the risks of cross-origin HTTP requests.

The HTTP response headers

Access-Control-Allow-Origin

A returned resource may have one Access-Control-Allow-Origin header with the following syntax:

Access-Control-Allow-Origin: <origin> | *

Access-Control-Allow-Origin specifies either a single origin which tells browsers to allow that origin to access the resource; or else — for requests without credentials — the * wildcard tells browsers to allow any origin to access the resource.

For example, to allow code from the origin https://mozilla.org to access the resource, you can specify:

Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin

If the server specifies a single origin (that may dynamically change based on the requesting origin as part of an allowlist) rather than the "*" wildcard, then the server should also include Origin in the Vary response header to indicate to clients that server responses will differ based on the value of the Origin request header.

Access-Control-Expose-Headers

The Access-Control-Expose-Headers header adds the specified headers to the allowlist that JavaScript in browsers is allowed to access.

Access-Control-Expose-Headers: <header-name>[, <header-name>]*

For example, the following:

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

...would allow the X-My-Custom-Header and X-Another-Custom-Header headers to be exposed to the browser.

Access-Control-Max-Age

The Access-Control-Max-Age header indicates how long the results of a preflight request can be cached. For an example of a preflight request, see the above examples.

Access-Control-Max-Age: <delta-seconds>

The delta-seconds parameter indicates the number of seconds the results can be cached.

Access-Control-Allow-Credentials

The Access-Control-Allow-Credentials header indicates whether or not the response to the request can be exposed when the credentials flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note that simple GET requests are not preflighted, and so if a request is made for a resource with credentials, if this header is not returned with the resource, the response is ignored by the browser and not returned to web content.

Access-Control-Allow-Credentials: true

Access-Control-Allow-Methods

The Access-Control-Allow-Methods header specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.

Access-Control-Allow-Methods: <method>[, <method>]*

Access-Control-Allow-Headers

The Access-Control-Allow-Headers header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. This header is the server side response to the browser's Access-Control-Request-Headers header.

Access-Control-Allow-Headers: <header-name>[, <header-name>]*

The HTTP request headers

This section lists headers that clients may use when issuing HTTP requests in order to make use of the cross-origin sharing feature. Note that these headers are set for you when making invocations to servers. Developers using cross-origin XMLHttpRequest capability do not have to set any cross-origin sharing request headers programmatically.

Origin

The Origin header indicates the origin of the cross-origin access request or preflight request.

Origin: <origin>

The origin is a URL indicating the server from which the request is initiated. It does not include any path information, only the server name.

Access-Control-Request-Method

The Access-Control-Request-Method is used when issuing a preflight request to let the server know what HTTP method will be used when the actual request is made.

Access-Control-Request-Method: <method>

Access-Control-Request-Headers

The Access-Control-Request-Headers header is used when issuing a preflight request to let the server know what HTTP headers will be used when the actual request is made. This browser-side header will be answered by the complementary server-side header of Access-Control-Allow-Headers.

Access-Control-Request-Headers: <field-name>[, <field-name>]*

Testing CORS

As you can see, setting up CORS requires setting up a number of HTTP request and response headers. If incorrectly set, the enforcement might be too loose, allowing other domains to gain cross origin access into your resources. Or the enforcement might be too strict, potentially breaking your website.

Using ModHeader, you can add CORS response headers to your server without modifying any code. This allows you to confirm whether your websites will behave correctly when CORS is enabled. For example, to setup Access-Control-Allow-Origin header:

  • Click on , and select Response header
  • Add the Access-Control-Allow-Origin header, with the value set to your desired domain. >
  • Going one step further, you can click on , and select URL filter to enable the response header only on the selected domain.
  • Now visit/refresh your website to check if the website is still behaving well with CORS enabled.

Using the steps above, you can also add other CORS response headers such as Access-Control-Expose-Headers, Access-Control-Expose-Headers, Access-Control-Allow-Credentials, etc.

References