--- title: CORS Support description: Enable and configure CORS headers in MockServer for control-plane and mocked responses, with examples for permissive and restrictive policies. layout: page pageOrder: 3 section: 'Security' subsection: true sitemap: priority: 0.7 changefreq: 'monthly' lastmod: 2019-11-10T08:00:00+01:00 ---

MockServer and the proxy has support for CORS. By default, CORS support is not enabled for the Control Plane API and or for mocked response, such as, when expectations are matched, or proxied requests.

When CORS support is enabled, and the corsAllowMethods / corsAllowHeaders / corsAllowOrigin properties are left at their defaults (blank), MockServer emits sensible defaults so the Control Plane API and dashboard are usable cross-origin out of the box:

Access-Control-Allow-Origin: <request Origin>   # the requesting Origin is reflected; "*" when there is no Origin
Access-Control-Allow-Methods: "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE"
Access-Control-Allow-Headers: "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization"
Access-Control-Expose-Headers: "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization"
Access-Control-Allow-Credentials: "false"
Access-Control-Max-Age: "0"

NOTE: by default the requesting Origin is reflected, so cross-site requests are allowed out of the box. Set an explicit corsAllowOrigin (for example an allow-list) to restrict which origins are permitted.

To reduce the security risk from cross-site requests, CORS headers should be configured to the minimum required values for your use case, using the CORS configuration properties, as below.

A more permission approach that enables most use cases would configure the CORS headers, as follows:

Access-Control-Allow-Origin: "*"
Access-Control-Allow-Methods: "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE"
Access-Control-Allow-Headers: "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization"
Access-Control-Expose-Headers: "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization"
Access-Control-Max-Age: "300"

For example to enable a more permission approach for cross-site requests use ConfigurationProperties class as follows:

ConfigurationProperties.enableCORSForAllResponses(true);
ConfigurationProperties.corsAllowOrigin("*");
ConfigurationProperties.corsAllowMethods("CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE");
ConfigurationProperties.corsAllowHeaders("Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization");
ConfigurationProperties.corsMaxAgeInSeconds(300);
{% include_subpage _includes/cors_configuration.html %}  

Examples:

CORS is a server-startup configuration, so it is applied when MockServer starts rather than per-expectation. The examples below launch (or configure) the server with the same CORS settings in each language. The detailed corsAllow* / corsMaxAgeInSeconds values are read once at startup, so set them when the server is launched (the REST API tab can toggle the enable flag at runtime, but does not re-apply the detailed values).

ConfigurationProperties.enableCORSForAllResponses(true);
ConfigurationProperties.corsAllowMethods("CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE");
ConfigurationProperties.corsAllowHeaders("Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization");
ConfigurationProperties.corsAllowCredentials(true);
ConfigurationProperties.corsMaxAgeInSeconds(300);
var mockserver = require('mockserver-node');
mockserver.start_mockserver({
    serverPort: 1080,
    systemProperties: "-Dmockserver.enableCORSForAllResponses=true " +
        "-Dmockserver.corsAllowMethods=\"CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE\" " +
        "-Dmockserver.corsAllowHeaders=\"Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization\" " +
        "-Dmockserver.corsAllowCredentials=\"true\" " +
        "-Dmockserver.corsMaxAgeInSeconds=\"300\""
});
from mockserver import start_server

# the launcher passes these JVM system properties straight through to the server
server = start_server(port=1080, extra_args=[
    "-Dmockserver.enableCORSForAllResponses=true",
    "-Dmockserver.corsAllowMethods=CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE",
    "-Dmockserver.corsAllowHeaders=Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization",
    "-Dmockserver.corsAllowCredentials=true",
    "-Dmockserver.corsMaxAgeInSeconds=300",
])
require 'mockserver-client'

# the launcher passes these JVM system properties straight through to the server
server = MockServer::BinaryLauncher.start(port: 1080, extra_args: [
    '-Dmockserver.enableCORSForAllResponses=true',
    '-Dmockserver.corsAllowMethods=CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE',
    '-Dmockserver.corsAllowHeaders=Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization',
    '-Dmockserver.corsAllowCredentials=true',
    '-Dmockserver.corsMaxAgeInSeconds=300'
])
import (
    "os"

    mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
)

// the launched server inherits these environment variables
os.Setenv("MOCKSERVER_ENABLE_CORS_FOR_ALL_RESPONSES", "true")
os.Setenv("MOCKSERVER_CORS_ALLOW_METHODS", "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE")
os.Setenv("MOCKSERVER_CORS_ALLOW_HEADERS", "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization")
os.Setenv("MOCKSERVER_CORS_ALLOW_CREDENTIALS", "true")
os.Setenv("MOCKSERVER_CORS_MAX_AGE_IN_SECONDS", "300")

server, _ := mockserver.StartServer(1080, "", nil)
using System;
using MockServer.Client;

// the launched server inherits these environment variables
Environment.SetEnvironmentVariable("MOCKSERVER_ENABLE_CORS_FOR_ALL_RESPONSES", "true");
Environment.SetEnvironmentVariable("MOCKSERVER_CORS_ALLOW_METHODS", "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE");
Environment.SetEnvironmentVariable("MOCKSERVER_CORS_ALLOW_HEADERS", "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization");
Environment.SetEnvironmentVariable("MOCKSERVER_CORS_ALLOW_CREDENTIALS", "true");
Environment.SetEnvironmentVariable("MOCKSERVER_CORS_MAX_AGE_IN_SECONDS", "300");

var server = MockServerBinaryLauncher.Start(port: 1080);
use mockserver_client::launcher;

// the launched server inherits these environment variables
std::env::set_var("MOCKSERVER_ENABLE_CORS_FOR_ALL_RESPONSES", "true");
std::env::set_var("MOCKSERVER_CORS_ALLOW_METHODS", "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE");
std::env::set_var("MOCKSERVER_CORS_ALLOW_HEADERS", "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization");
std::env::set_var("MOCKSERVER_CORS_ALLOW_CREDENTIALS", "true");
std::env::set_var("MOCKSERVER_CORS_MAX_AGE_IN_SECONDS", "300");

let server = launcher::start(1080).unwrap();
use MockServer\BinaryLauncher;

// the launcher passes these JVM system properties straight through to the server
$server = (new BinaryLauncher())->start(1080, [
    '-Dmockserver.enableCORSForAllResponses=true',
    '-Dmockserver.corsAllowMethods=CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE',
    '-Dmockserver.corsAllowHeaders=Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization',
    '-Dmockserver.corsAllowCredentials=true',
    '-Dmockserver.corsMaxAgeInSeconds=300',
]);
curl -v -X PUT "http://localhost:1080/mockserver/configuration" -d '{
    "enableCORSForAllResponses": true,
    "corsAllowMethods": "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE",
    "corsAllowHeaders": "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization",
    "corsAllowCredentials": true,
    "corsMaxAgeInSeconds": 300
}'

The enableCORSForAllResponses flag takes effect at runtime; the detailed corsAllow* / corsMaxAgeInSeconds values are only applied when the server starts, so set those at launch (see the other tabs).

java -Dmockserver.enableCORSForAllResponses=true \
-Dmockserver.corsAllowMethods="CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE" \
-Dmockserver.corsAllowHeaders="Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization" \
-Dmockserver.corsAllowCredentials="true" \
-Dmockserver.corsMaxAgeInSeconds="300" \
-jar "~/Downloads/mockserver-netty-{{ site.mockserver_version }}-no-dependencies.jar" -serverPort 1080
ConfigurationProperties.enableCORSForAPI(true);
ConfigurationProperties.corsAllowMethods("CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE");
ConfigurationProperties.corsAllowHeaders("Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization");
ConfigurationProperties.corsAllowCredentials(true);
ConfigurationProperties.corsMaxAgeInSeconds(300);
var mockserver = require('mockserver-node');
mockserver.start_mockserver({
    serverPort: 1080,
    systemProperties: "-Dmockserver.enableCORSForAPI=true " +
        "-Dmockserver.corsAllowMethods=\"CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE\" " +
        "-Dmockserver.corsAllowHeaders=\"Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization\" " +
        "-Dmockserver.corsAllowCredentials=\"true\" " +
        "-Dmockserver.corsMaxAgeInSeconds=\"300\""
});
from mockserver import start_server

# the launcher passes these JVM system properties straight through to the server
server = start_server(port=1080, extra_args=[
    "-Dmockserver.enableCORSForAPI=true",
    "-Dmockserver.corsAllowMethods=CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE",
    "-Dmockserver.corsAllowHeaders=Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization",
    "-Dmockserver.corsAllowCredentials=true",
    "-Dmockserver.corsMaxAgeInSeconds=300",
])
require 'mockserver-client'

# the launcher passes these JVM system properties straight through to the server
server = MockServer::BinaryLauncher.start(port: 1080, extra_args: [
    '-Dmockserver.enableCORSForAPI=true',
    '-Dmockserver.corsAllowMethods=CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE',
    '-Dmockserver.corsAllowHeaders=Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization',
    '-Dmockserver.corsAllowCredentials=true',
    '-Dmockserver.corsMaxAgeInSeconds=300'
])
import (
    "os"

    mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7"
)

// the launched server inherits these environment variables
os.Setenv("MOCKSERVER_ENABLE_CORS_FOR_API", "true")
os.Setenv("MOCKSERVER_CORS_ALLOW_METHODS", "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE")
os.Setenv("MOCKSERVER_CORS_ALLOW_HEADERS", "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization")
os.Setenv("MOCKSERVER_CORS_ALLOW_CREDENTIALS", "true")
os.Setenv("MOCKSERVER_CORS_MAX_AGE_IN_SECONDS", "300")

server, _ := mockserver.StartServer(1080, "", nil)
using System;
using MockServer.Client;

// the launched server inherits these environment variables
Environment.SetEnvironmentVariable("MOCKSERVER_ENABLE_CORS_FOR_API", "true");
Environment.SetEnvironmentVariable("MOCKSERVER_CORS_ALLOW_METHODS", "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE");
Environment.SetEnvironmentVariable("MOCKSERVER_CORS_ALLOW_HEADERS", "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization");
Environment.SetEnvironmentVariable("MOCKSERVER_CORS_ALLOW_CREDENTIALS", "true");
Environment.SetEnvironmentVariable("MOCKSERVER_CORS_MAX_AGE_IN_SECONDS", "300");

var server = MockServerBinaryLauncher.Start(port: 1080);
use mockserver_client::launcher;

// the launched server inherits these environment variables
std::env::set_var("MOCKSERVER_ENABLE_CORS_FOR_API", "true");
std::env::set_var("MOCKSERVER_CORS_ALLOW_METHODS", "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE");
std::env::set_var("MOCKSERVER_CORS_ALLOW_HEADERS", "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization");
std::env::set_var("MOCKSERVER_CORS_ALLOW_CREDENTIALS", "true");
std::env::set_var("MOCKSERVER_CORS_MAX_AGE_IN_SECONDS", "300");

let server = launcher::start(1080).unwrap();
use MockServer\BinaryLauncher;

// the launcher passes these JVM system properties straight through to the server
$server = (new BinaryLauncher())->start(1080, [
    '-Dmockserver.enableCORSForAPI=true',
    '-Dmockserver.corsAllowMethods=CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE',
    '-Dmockserver.corsAllowHeaders=Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization',
    '-Dmockserver.corsAllowCredentials=true',
    '-Dmockserver.corsMaxAgeInSeconds=300',
]);
curl -v -X PUT "http://localhost:1080/mockserver/configuration" -d '{
    "enableCORSForAPI": true,
    "corsAllowMethods": "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE",
    "corsAllowHeaders": "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization",
    "corsAllowCredentials": true,
    "corsMaxAgeInSeconds": 300
}'

The enableCORSForAPI flag takes effect at runtime; the detailed corsAllow* / corsMaxAgeInSeconds values are only applied when the server starts, so set those at launch (see the other tabs).

java -Dmockserver.enableCORSForAPI=true \
-Dmockserver.corsAllowMethods="CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE" \
-Dmockserver.corsAllowHeaders="Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, Location, Server, Vary, Authorization" \
-Dmockserver.corsAllowCredentials="true" \
-Dmockserver.corsMaxAgeInSeconds="300" \
-jar "~/Downloads/mockserver-netty-{{ site.mockserver_version }}-no-dependencies.jar" -serverPort 1080

See Also