{"id":16064448,"url":"https://github.com/j0lvera/next-csrf","last_synced_at":"2025-08-17T05:05:16.734Z","repository":{"id":40745471,"uuid":"274302783","full_name":"j0lvera/next-csrf","owner":"j0lvera","description":"CSRF mitigation for Next.js","archived":false,"fork":false,"pushed_at":"2023-04-25T16:03:02.000Z","size":976,"stargazers_count":142,"open_issues_count":30,"forks_count":21,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-08-17T05:02:51.927Z","etag":null,"topics":["csrf","csrf-protection","next","nextjs","node","security"],"latest_commit_sha":null,"homepage":"https://npm.im/next-csrf","language":"TypeScript","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/j0lvera.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","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},"funding":{"github":["jOlv3r4"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2020-06-23T03:48:45.000Z","updated_at":"2025-07-11T13:33:04.000Z","dependencies_parsed_at":"2024-04-28T03:19:00.748Z","dependency_job_id":"cae691f4-670c-4ddf-a6b3-8f12c803b02c","html_url":"https://github.com/j0lvera/next-csrf","commit_stats":{"total_commits":33,"total_committers":7,"mean_commits":4.714285714285714,"dds":"0.24242424242424243","last_synced_commit":"91774aca0b271512f69976fce1fbc8681a7ca229"},"previous_names":["zbnauj/next-csrf","j0lv3r4/next-csrf","juanbzpy/next-csrf"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/j0lvera/next-csrf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j0lvera%2Fnext-csrf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j0lvera%2Fnext-csrf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j0lvera%2Fnext-csrf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j0lvera%2Fnext-csrf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/j0lvera","download_url":"https://codeload.github.com/j0lvera/next-csrf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j0lvera%2Fnext-csrf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270807934,"owners_count":24649346,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["csrf","csrf-protection","next","nextjs","node","security"],"created_at":"2024-10-09T05:07:55.427Z","updated_at":"2025-08-17T05:05:16.675Z","avatar_url":"https://github.com/j0lvera.png","language":"TypeScript","funding_links":["https://github.com/sponsors/jOlv3r4"],"categories":["TypeScript"],"sub_categories":[],"readme":"# next-csrf\n\n![Discord](https://discord.com/api/guilds/967474884378763314/widget.png)\n\nCSRF mitigation for Next.js.\n\n## Features\n\nMitigation patterns that `next-csrf` implements:\n\n* [Synchronizer Token Pattern](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern) using [`csrf`](https://github.com/pillarjs/csrf) (Also [read Understanding CSRF](https://github.com/pillarjs/understanding-csrf#csrf-tokens))\n\n## Installation\n\nWith yarn:\n\n```bash\nyarn add next-csrf\n```\n\nWith npm:\n\n```bash\nnpm i next-csrf --save\n```\n\n## Usage\n\nCreate an initialization file to add options:\n\n```js\n// file: lib/csrf.js\n\nimport { nextCsrf } from \"next-csrf\";\n\nconst { csrf, setup } = nextCsrf({\n    // eslint-disable-next-line no-undef\n    secret: process.env.CSRF_SECRET,\n});\n\nexport { csrf, setup };\n\n```\n\nProtect an API endpoint:\n\n```js\n// file: pages/api/protected.js\n\nimport { csrf } from '../lib/csrf';\n\nconst handler = (req, res) =\u003e {\n    return res.status(200).json({ message: \"This API route is protected.\"})\n}\n\nexport default csrf(handler);\n```\n\nTest the protected API route by sending a POST request from your terminal. Since this request doesn't have the proper token setup, it wil fail.\n\n```shell\ncurl -X POST http://localhost:3000/api/protected\n\u003e\u003e {\"message\": \"Invalid CSRF token\"}\n```\n\nUse an [SSG page](https://nextjs.org/docs/basic-features/pages#server-side-rendering) to set up the token. Usually, you use CSRF mitigation to harden your requests from authenticated users, if this is the case then you should use the login page.\n\n```js\n// file: pages/login.js\n\nimport { setup } from '../lib/csrf';\n\nfunction Login() {\n    const loginRequest = async (event) =\u003e {\n        event.preventDefault();\n        \n        // The secret and token are sent with the request by default, so no extra\n        // configuration is needed in the request.\n        const response = await fetch('/api/protected', {\n            method: 'post'\n        });\n        \n        if (response.ok) {\n            console.log('protected response ok');\n        }\n    }\n    \n    return (\n        \u003cform onSubmit={loginRequest}\u003e\n            \u003clabel\u003e\n                Username\n                \u003cinput type=\"text\" required /\u003e\n            \u003c/label\u003e\n            \n            \u003clabel\u003e\n                Password\n                \u003cinput type=\"password\" required /\u003e\n            \u003c/label\u003e\n            \n            \u003cbutton\u003eSubmit\u003c/button\u003e\n        \u003c/form\u003e\n    )\n}\n\n// Here's the important part. `setup` saves the necesary secret and token.\nexport const getServerSideProps = setup(async ({req, res}) =\u003e {\n    return { props: {}}\n});\n\nexport default Login;\n```\n\n## API\n\n### `nextCsrf(options);`\n\nReturns two functions: \n\n* `setup` Setups two cookies, one for the secret and other one for the token. Only works on SSG pages.\n* `csrf` Protects API routes from requests without the token. Validates and verify signatures on the cookies.\n\n#### `options`\n\n* `tokenKey` (`string`) The name of the cookie to store the CSRF token. Default is `\"XSRF-TOKEN\"`.\n* `csrfErrorMessage` (`string`) Error message to return for unauthorized requests. Default is `\"Invalid CSRF token\"`.\n* `ignoredMethods`: (`string[]`) Methods to ignore, i.e. let pass all requests with these methods. Default is `[\"GET\", \"HEAD\", \"OPTIONS\"]`.\n* `cookieOptions`: Same options as https://www.npmjs.com/package/cookie\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj0lvera%2Fnext-csrf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fj0lvera%2Fnext-csrf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj0lvera%2Fnext-csrf/lists"}