Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions docs/src/handling-requests-with-controllers/cors-requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,20 @@ Wheels can often act as the "backend" in a modern web application, serving data

When we separate our systems in such a manner, we need to consider CORS (Cross Origin Resource Sharing) and how to properly serve requests which modern browsers will allow.

### The "Quick and Dirty" approach
### Getting Started

If you just need to satisfy your CORS requirement quickly, you can do so with a simple configuration switch in your `/config/settings.cfm` file: `set(allowCorsRequests=true);`.
To enable CORS, add `set(allowCorsRequests=true);` to your `/config/settings.cfm` file. You must also configure your allowed origins explicitly — by default, no origins are permitted:

By default, this will enable the following CORS headers:
```javascript
set(allowCorsRequests=true);
set(accessControlAllowOrigin="https://app.domain.com");
```

This will enable the following CORS headers for matching requests:

```
Access-Control-Allow-Origin
*
https://app.domain.com

Access-Control-Allow-Methods
GET, POST, PATCH, PUT, DELETE, OPTIONS
Expand All @@ -25,7 +30,9 @@ Access-Control-Allow-Headers
Origin, Content-Type, X-Auth-Token, X-Requested-By, X-Requested-With
```

This will satisfy most requirements to get going quickly, but is more of a blanket "catch all" configuration which doesn't really restrict anything, or provide much information to the API consumer about your available resources.
{% hint style="warning" %}
Setting `accessControlAllowOrigin` to `"*"` (wildcard) allows any website to make cross-origin requests to your application. Only use this in development or when you explicitly intend to provide a public API.
{% endhint %}

### Custom CORS Headers

Expand All @@ -35,7 +42,7 @@ We can be more specific. We still need to specify `set(allowCorsRequests=true);`

The Access Control Allow Origin header tells the browser whether the domain they are connecting from can access the requested resource.

By default, this header is set to a wildcard allowing connection from any domain. But it might be your VueJS app lives at `app.domain.com` and we only want to allow access from that domain to our API.
By default, this header is not set (empty string), meaning no cross-origin requests are allowed. You must explicitly configure your allowed origins. For example, if your VueJS app lives at `app.domain.com`:

```javascript
// Wildcard
Expand Down
7 changes: 6 additions & 1 deletion vendor/wheels/Global.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -3319,7 +3319,7 @@ component output="false" {
* Set CORS Headers: only triggered if application.wheels.allowCorsRequests = true
*/
public void function $setCORSHeaders(
string allowOrigin = "*",
string allowOrigin = "",
string allowCredentials = false,
string allowHeaders = "Origin, Content-Type, X-Auth-Token, X-Requested-By, X-Requested-With",
string allowMethods = "GET, POST, PATCH, PUT, DELETE, OPTIONS",
Expand All @@ -3329,6 +3329,11 @@ component output="false" {
) {
local.incomingOrigin = StructKeyExists(request.wheels.httprequestdata.headers, "origin") ? request.wheels.httprequestdata.headers.origin : false;

// No origins configured — skip all CORS headers (deny all by default)
if (!Len(arguments.allowOrigin)) {
return;
}

// Either a wildcard, or if a specific domain is set, we need to ensure the incoming request matches it
if (arguments.allowOrigin == "*") {
$header(name = "Access-Control-Allow-Origin", value = arguments.allowOrigin);
Expand Down
2 changes: 1 addition & 1 deletion vendor/wheels/events/init/security.cfm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

// CORS (Cross-Origin Resource Sharing) settings.
application.$wheels.allowCorsRequests = false;
application.$wheels.accessControlAllowOrigin = "*";
application.$wheels.accessControlAllowOrigin = "";
application.$wheels.accessControlAllowMethods = "GET, POST, PATCH, PUT, DELETE, OPTIONS";
application.$wheels.accessControlAllowMethodsByRoute = false;
application.$wheels.accessControlAllowCredentials = false;
Expand Down
22 changes: 22 additions & 0 deletions vendor/wheels/tests/specs/dispatch/corsSecurityDefaultsSpec.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Tests that CORS security defaults are safe (deny-all, not wildcard).
*/
component extends="wheels.WheelsTest" {

function run() {

describe("CORS security defaults", () => {

it("defaults accessControlAllowOrigin to empty string not wildcard", () => {
expect(application.$wheels.accessControlAllowOrigin).toBe("");
});

it("defaults allowCorsRequests to false", () => {
expect(application.$wheels.allowCorsRequests).toBeFalse();
});

});

}

}
Loading