{"id":13396551,"url":"https://github.com/expressjs/cors","last_synced_at":"2026-03-17T21:35:05.848Z","repository":{"id":6684448,"uuid":"7929498","full_name":"expressjs/cors","owner":"expressjs","description":"Node.js CORS middleware","archived":false,"fork":false,"pushed_at":"2026-03-02T07:31:41.000Z","size":249,"stargazers_count":6197,"open_issues_count":35,"forks_count":493,"subscribers_count":81,"default_branch":"master","last_synced_at":"2026-03-13T04:33:08.944Z","etag":null,"topics":["cors","expressjs","javascript","middleware","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/expressjs.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"open_collective":"express"}},"created_at":"2013-01-31T03:27:53.000Z","updated_at":"2026-03-12T17:50:41.000Z","dependencies_parsed_at":"2024-06-23T04:57:31.419Z","dependency_job_id":"9d8934e3-5f5c-4a2d-9725-48e385062d05","html_url":"https://github.com/expressjs/cors","commit_stats":{"total_commits":297,"total_committers":52,"mean_commits":5.711538461538462,"dds":0.5185185185185186,"last_synced_commit":"1cfb3709dec33dfa7ae95a3a554f2dd10498c7f9"},"previous_names":["troygoode/node-cors"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/expressjs/cors","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fcors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fcors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fcors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fcors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/expressjs","download_url":"https://codeload.github.com/expressjs/cors/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expressjs%2Fcors/sbom","scorecard":{"id":388440,"data":{"date":"2025-08-11T21:24:16Z","repo":{"name":"github.com/expressjs/cors","commit":"9a9a760c888433d923847ee837e95567d9a94517"},"scorecard":{"version":"v5.2.1","commit":"ab2f6e92482462fe66246d9e32f642855a691dc1"},"score":7.5,"checks":[{"name":"Code-Review","score":5,"reason":"Found 13/23 approved changesets -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#code-review"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dependency-update-tool"}},{"name":"Maintained","score":10,"reason":"14 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Warn: jobLevel 'checks' permission set to 'write': .github/workflows/ci.yml:13","Info: jobLevel 'contents' permission set to 'read': .github/workflows/ci.yml:14","Warn: jobLevel 'checks' permission set to 'write': .github/workflows/ci.yml:158","Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:31","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:32","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:8","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:24","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:19"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":6,"reason":"dependency not pinned by hash detected -- score normalized to 6","details":["Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:109","Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:125","Info:   7 out of   7 GitHub-owned GitHubAction dependencies pinned","Info:   3 out of   3 third-party GitHubAction dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#vulnerabilities"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#cii-best-practices"}},{"name":"SAST","score":8,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 11 commits out of 21 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#sast"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/expressjs/.github/SECURITY.md:1","Info: Found linked content: github.com/expressjs/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/expressjs/.github/SECURITY.md:1","Info: Found text in security policy: github.com/expressjs/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#security-policy"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":6,"reason":"14 out of 21 merged PRs checked by a CI test -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#ci-tests"}},{"name":"Contributors","score":10,"reason":"project has 8 contributing companies or organizations","details":["Info: found contributions from: ExpressGateway, crypto-utils, expressjs, founder @trycourier, mysqljs, nodejs, repo-utils, stream-utils"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#contributors"}}]},"last_synced_at":"2025-08-18T17:14:13.657Z","repository_id":6684448,"created_at":"2025-08-18T17:14:13.657Z","updated_at":"2025-08-18T17:14:13.657Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30632030,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T17:32:55.572Z","status":"ssl_error","status_checked_at":"2026-03-17T17:32:38.732Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cors","expressjs","javascript","middleware","nodejs"],"created_at":"2024-07-30T18:00:56.680Z","updated_at":"2026-03-17T21:35:05.822Z","avatar_url":"https://github.com/expressjs.png","language":"JavaScript","readme":"# cors\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Build Status][github-actions-ci-image]][github-actions-ci-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nCORS is a [Node.js](https://nodejs.org/en/) middleware for [Express](https://expressjs.com/)/[Connect](https://github.com/senchalabs/connect) that sets [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) response headers. These headers tell browsers which origins can read responses from your server.\n\n\u003e [!IMPORTANT]\n\u003e **How CORS Works:** This package sets response headers—it doesn't block requests. CORS is enforced by browsers: they check the headers and decide if JavaScript can read the response. Non-browser clients (curl, Postman, other servers) ignore CORS entirely. See the [MDN CORS guide](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) for details.\n\n* [Installation](#installation)\n* [Usage](#usage)\n  * [Simple Usage](#simple-usage-enable-all-cors-requests)\n  * [Enable CORS for a Single Route](#enable-cors-for-a-single-route)\n  * [Configuring CORS](#configuring-cors)\n  * [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)\n  * [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)\n  * [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)\n* [Configuration Options](#configuration-options)\n* [Common Misconceptions](#common-misconceptions)\n* [License](#license)\n* [Original Author](#original-author)\n\n## Installation\n\nThis is a [Node.js](https://nodejs.org/en/) module available through the\n[npm registry](https://www.npmjs.com/). Installation is done using the\n[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):\n\n```sh\n$ npm install cors\n```\n\n## Usage\n\n### Simple Usage (Enable *All* CORS Requests)\n\n```javascript\nvar express = require('express')\nvar cors = require('cors')\nvar app = express()\n\n// Adds headers: Access-Control-Allow-Origin: *\napp.use(cors())\n\napp.get('/products/:id', function (req, res, next) {\n  res.json({msg: 'Hello'})\n})\n\napp.listen(80, function () {\n  console.log('web server listening on port 80')\n})\n```\n\n### Enable CORS for a Single Route\n\n```javascript\nvar express = require('express')\nvar cors = require('cors')\nvar app = express()\n\n// Adds headers: Access-Control-Allow-Origin: *\napp.get('/products/:id', cors(), function (req, res, next) {\n  res.json({msg: 'Hello'})\n})\n\napp.listen(80, function () {\n  console.log('web server listening on port 80')\n})\n```\n\n### Configuring CORS\n\nSee the [configuration options](#configuration-options) for details.\n\n```javascript\nvar express = require('express')\nvar cors = require('cors')\nvar app = express()\n\nvar corsOptions = {\n  origin: 'http://example.com',\n  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204\n}\n\n// Adds headers: Access-Control-Allow-Origin: http://example.com, Vary: Origin\napp.get('/products/:id', cors(corsOptions), function (req, res, next) {\n  res.json({msg: 'Hello'})\n})\n\napp.listen(80, function () {\n  console.log('web server listening on port 80')\n})\n```\n\n### Configuring CORS w/ Dynamic Origin\n\nThis module supports validating the origin dynamically using a function provided\nto the `origin` option. This function will be passed a string that is the origin\n(or `undefined` if the request has no origin), and a `callback` with the signature\n`callback(error, origin)`.\n\nThe `origin` argument to the callback can be any value allowed for the `origin`\noption of the middleware, except a function. See the\n[configuration options](#configuration-options) section for more information on all\nthe possible value types.\n\nThis function is designed to allow the dynamic loading of allowed origin(s) from\na backing datasource, like a database.\n\n```javascript\nvar express = require('express')\nvar cors = require('cors')\nvar app = express()\n\nvar corsOptions = {\n  origin: function (origin, callback) {\n    // db.loadOrigins is an example call to load\n    // a list of origins from a backing database\n    db.loadOrigins(function (error, origins) {\n      callback(error, origins)\n    })\n  }\n}\n\n// Adds headers: Access-Control-Allow-Origin: \u003cmatched origin\u003e, Vary: Origin\napp.get('/products/:id', cors(corsOptions), function (req, res, next) {\n  res.json({msg: 'Hello'})\n})\n\napp.listen(80, function () {\n  console.log('web server listening on port 80')\n})\n```\n\n### Enabling CORS Pre-Flight\n\nCertain CORS requests are considered 'complex' and require an initial\n`OPTIONS` request (called the \"pre-flight request\"). An example of a\n'complex' CORS request is one that uses an HTTP verb other than\nGET/HEAD/POST (such as DELETE) or that uses custom headers. To enable\npre-flighting, you must add a new OPTIONS handler for the route you want\nto support:\n\n```javascript\nvar express = require('express')\nvar cors = require('cors')\nvar app = express()\n\napp.options('/products/:id', cors()) // preflight for DELETE\napp.del('/products/:id', cors(), function (req, res, next) {\n  res.json({msg: 'Hello'})\n})\n\napp.listen(80, function () {\n  console.log('web server listening on port 80')\n})\n```\n\nYou can also enable pre-flight across-the-board like so:\n\n```javascript\napp.options('*', cors()) // include before other routes\n```\n\nNOTE: When using this middleware as an application level middleware (for\nexample, `app.use(cors())`), pre-flight requests are already handled for all\nroutes.\n\n### Customizing CORS Settings Dynamically per Request\n\nFor APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.\n\nThe function accepts:\n1. **`req`**: \n   - The incoming request object.\n\n2. **`callback(error, corsOptions)`**: \n   - A function used to return the computed CORS options.\n   - **Arguments**:\n     - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.\n     - **`corsOptions`**: An object specifying the CORS policy for the current request.\n\nHere’s an example that handles both public routes and restricted, credential-sensitive routes:\n\n```javascript\nvar dynamicCorsOptions = function(req, callback) {\n  var corsOptions;\n  if (req.path.startsWith('/auth/connect/')) {\n    // Access-Control-Allow-Origin: http://mydomain.com, Access-Control-Allow-Credentials: true, Vary: Origin\n    corsOptions = {\n      origin: 'http://mydomain.com',\n      credentials: true\n    };\n  } else {\n    // Access-Control-Allow-Origin: *\n    corsOptions = { origin: '*' };\n  }\n  callback(null, corsOptions);\n};\n\napp.use(cors(dynamicCorsOptions));\n\napp.get('/auth/connect/twitter', function (req, res) {\n  res.send('Hello');\n});\n\napp.get('/public', function (req, res) {\n  res.send('Hello');\n});\n\napp.listen(80, function () {\n  console.log('web server listening on port 80')\n})\n```\n\n## Configuration Options\n\n* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:\n  - `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.\n  - `String` - set `origin` to a specific origin. For example, if you set it to\n    - `\"http://example.com\"` only requests from \"http://example.com\" will be allowed.\n    - `\"*\"` for all domains to be allowed. \n  - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\\.com$/` will reflect any request that is coming from an origin ending with \"example.com\".\n  - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `[\"http://example1.com\", /\\.example2\\.com$/]` will accept any request from \"http://example1.com\" or from a subdomain of \"example2.com\".\n  - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.\n* `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).\n* `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.\n* `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.\n* `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.\n* `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.\n* `preflightContinue`: Pass the CORS preflight response to the next handler.\n* `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.\n\nThe default configuration is the equivalent of:\n\n```json\n{\n  \"origin\": \"*\",\n  \"methods\": \"GET,HEAD,PUT,PATCH,POST,DELETE\",\n  \"preflightContinue\": false,\n  \"optionsSuccessStatus\": 204\n}\n```\n\n## Common Misconceptions\n\n### \"CORS blocks requests from disallowed origins\"\n\n**No.** Your server receives and processes every request. CORS headers tell the browser whether JavaScript can read the response—not whether the request is allowed.\n\n### \"CORS protects my API from unauthorized access\"\n\n**No.** CORS is not access control. Any HTTP client (curl, Postman, another server) can call your API regardless of CORS settings. Use authentication and authorization to protect your API.\n\n### \"Setting `origin: 'http://example.com'` means only that domain can access my server\"\n\n**No.** It means browsers will only let JavaScript from that origin read responses. The server still responds to all requests.\n\n## License\n\n[MIT License](http://www.opensource.org/licenses/mit-license.php)\n\n## Original Author\n\n[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))\n\n[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg\n[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/cors.svg\n[downloads-url]: https://npmjs.com/package/cors\n[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master\u0026label=ci\n[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci\n[npm-image]: https://img.shields.io/npm/v/cors.svg\n[npm-url]: https://npmjs.com/package/cors\n","funding_links":["https://opencollective.com/express"],"categories":["express","JavaScript","Npm","Uncategorized","Node.js","中间件","Middleware"],"sub_categories":["Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpressjs%2Fcors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexpressjs%2Fcors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpressjs%2Fcors/lists"}