Skip to content
Open
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
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ app.listen(80, function () {
## Configuration Options

* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
- `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
- `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS. **Avoid combining `origin: true` with `credentials: true`** (see the `credentials` option below).
- `String` - set `origin` to a specific origin. For example, if you set it to
- `"http://example.com"` only requests from "http://example.com" will be allowed.
- `"*"` for all domains to be allowed.
Expand All @@ -230,6 +230,22 @@ app.listen(80, function () {
* `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
* `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
* `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.

> **Security note:** Do not combine `credentials: true` with `origin: true`. When `origin` is `true`, this package reflects whatever origin the browser sends back in `Access-Control-Allow-Origin`. Paired with `Access-Control-Allow-Credentials: true`, this means *any* website can make credentialed (cookie-bearing) requests to your server and read the responses — equivalent to opening your API to the entire web with full session access. Use an explicit allowlist (`origin: ['https://app.example.com']`) instead, or a function for dynamic lists (env-specific, tenant-specific, etc.):

```js
app.use(cors({
origin: function (origin, callback) {
const allowlist = process.env.ALLOWED_ORIGINS.split(',');
if (!origin || allowlist.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true
}));
```
* `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
* `preflightContinue`: Pass the CORS preflight response to the next handler.
* `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
Expand Down