{"id":18929391,"url":"https://github.com/thecodingmachine/csrf-header-check-middleware","last_synced_at":"2025-07-23T23:34:35.936Z","repository":{"id":57067855,"uuid":"93768755","full_name":"thecodingmachine/csrf-header-check-middleware","owner":"thecodingmachine","description":"A PHP PSR-15 (http-interop) compliant middleware that defends your application against CSRF attacks.","archived":false,"fork":false,"pushed_at":"2018-09-13T09:54:18.000Z","size":26,"stargazers_count":7,"open_issues_count":0,"forks_count":3,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-07-17T21:18:55.183Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thecodingmachine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-08T16:10:17.000Z","updated_at":"2022-05-19T16:21:27.000Z","dependencies_parsed_at":"2022-08-24T14:54:08.071Z","dependency_job_id":null,"html_url":"https://github.com/thecodingmachine/csrf-header-check-middleware","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/thecodingmachine/csrf-header-check-middleware","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodingmachine%2Fcsrf-header-check-middleware","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodingmachine%2Fcsrf-header-check-middleware/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodingmachine%2Fcsrf-header-check-middleware/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodingmachine%2Fcsrf-header-check-middleware/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thecodingmachine","download_url":"https://codeload.github.com/thecodingmachine/csrf-header-check-middleware/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodingmachine%2Fcsrf-header-check-middleware/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266768406,"owners_count":23981355,"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-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":[],"created_at":"2024-11-08T11:32:20.397Z","updated_at":"2025-07-23T23:34:35.914Z","avatar_url":"https://github.com/thecodingmachine.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Latest Stable Version](https://poser.pugx.org/thecodingmachine/csrf-header-check-middleware/v/stable)](https://packagist.org/packages/thecodingmachine/csrf-header-check-middleware)\n[![Total Downloads](https://poser.pugx.org/thecodingmachine/csrf-header-check-middleware/downloads)](https://packagist.org/packages/thecodingmachine/csrf-header-check-middleware)\n[![Latest Unstable Version](https://poser.pugx.org/thecodingmachine/csrf-header-check-middleware/v/unstable)](https://packagist.org/packages/thecodingmachine/csrf-header-check-middleware)\n[![License](https://poser.pugx.org/thecodingmachine/csrf-header-check-middleware/license)](https://packagist.org/packages/thecodingmachine/csrf-header-check-middleware)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/thecodingmachine/csrf-header-check-middleware/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/thecodingmachine/csrf-header-check-middleware/?branch=master)\n[![Build Status](https://travis-ci.org/thecodingmachine/csrf-header-check-middleware.svg?branch=master)](https://travis-ci.org/thecodingmachine/csrf-header-check-middleware)\n[![Coverage Status](https://coveralls.io/repos/thecodingmachine/csrf-header-check-middleware/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/thecodingmachine/csrf-header-check-middleware?branch=master)\n\n# CSRF header checking middleware\n\nThis package contains a PHP PSR-15 compliant middleware that checks for CSRF attacks.\n\nIt implements the [first OWASP general recommendation for guarding your site against cross-site request forgery (Verifying Same Origin with Standard Headers)](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet).\n\nNote that OWASP recommends also using a CSRF token. This requires some changes in your application and this middleware does not provide any help regarding CSRF token generation.\nOther packages (like [Slim-CSRF](https://github.com/slimphp/Slim-Csrf)) can help you with CSRF token validation.\n\nWhat is it doing?\n-----------------\n\nThe `CsrfHeaderCheckMiddleware` will look at all POST/PUT/DELETE requests (actually all requests that are not GET/HEAD/OPTIONS).\nIt will verify that the \"Origin\" of the request is your own website.\n\nIt does so by comparing the \"Origin\" (or the \"Referrer\" header as a fallback) to your website's domain name.\nIf the headers do not match (or if the headers are not found), it will trigger an exception.\n\nWhy does it work?\n-----------------\n\nIn a CSRF attack, the victim (Alice) is logged in your application.\nThe attacker (Eve) sends Alice a malicious link to her malicious website. The malicious website contains some Javascript that performs a POST on a form of your website. Since Alice is logged into your website, the POST succeeds, allowing Eve to perform actions on the behalf of Alice.\n\nThe query is therefore executed by Alice's computer. We can expect Alice's browser to behave as a \"normal\" browsers.\n\nNormal browsers [do not allow Javascript code to modify the \"Origin\" or \"Referer\" header](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name).\n\nHow does it compare to other solutions\n--------------------------------------\n\nWhen fighting CSRF attacks, the most common solution used it to generate a token in each form, store this token in session, and check that the user sends back the token.\nIf you are looking for a CSRF token based middleware using PSR-7/PSR-15, have a look at [Ocramius/PSR7Csrf](https://github.com/Ocramius/PSR7Csrf/)\n\n### Advantages over token based implementations\n\nChecking for HTTP headers can be done in the middleware alone.\nWith token-based middlewares, you have to modify your application to generate a token and send the token with any form. In contrast, checking headers requires no work besides adding the middleware. So it's really fast to deploy.\n\n### Limits\n\n- This middleware completely bypasses GET requests. If your application modifies state on GET requests, you are screwed. Of course, modification of state should only happen in POST requests (but please check twice that your routes changing state do ONLY works with POST/DELETE/PUT requests).\n- This middleware expects \"Origin\" or \"Referer\" headers to be filled. This will often be true unless you are in a corporate environment with proxies that are fiddling with your request. For instance, some proxies are known to strip headers in order to make the request anonymous.\n- Will block CORS requests. You cannot use this middleware if you are expecting requests to come from another origin than your website.\n- If your website is accessed from a third party application (like a phone app), you cannot use this middleware as the Origin and Referer will be empty.\n\nIf you are in one of those situations, use a token-based middleware instead.\n\nInstallation\n------------\n\n```php\ncomposer require thecodingmachine/csrf-header-check-middleware\n```\n\nUsage\n-----\n\nThe simplest usage is based on defaults. It assumes that you have\na configured PSR-7 compatible application that supports piping\nmiddlewares.\n\nIn a [`zendframework/zend-expressive`](https://github.com/zendframework/zend-expressive)\napplication, the setup would look like the following:\n\n```php\n$app = \\Zend\\Expressive\\AppFactory::create();\n\n$app-\u003epipe(\\TheCodingMachine\\Middlewares\\CsrfHeaderCheckMiddlewareFactory::createDefault();\n```\n\nGuessing your domain name\n-------------------------\n\nThis middleware will do its best to \"guess\" the domain name of your website. To do so, it will check the \"Host\" header of the HTTP request.\n\nYou need to know this:\n\n- Normal browsers always send the \"Host\" header (at least in HTTP 1.1).\n- In a normal browser, the \"Host\" header cannot be modified by Javascript code.\n\nHowever:\n\n- The \"Host\" header can be modified by proxies\n- Proxies will generally put the previous \"Host\" header in the \"X-Forwarded-Host\" header\n- The \"X-Forwarded-Host\" header CANNOT be trusted because it can be changed from the client side (in Javascript)\n\nTherefore, if you run your application behind a proxy, or if you deal for some reason with HTTP/1.0, you will have to manually specify the domain name of your application.\n\n```php\n// The first argument of the factory is a list of domain name for your application.\n$app-\u003epipe(\\TheCodingMachine\\Middlewares\\CsrfHeaderCheckMiddlewareFactory::createDefault([\n    'alice.com',\n    'www.alice.com'\n]);\n```\n\nDisabling CSRF checks\n---------------------\n\nYou can disable CSRF checks on a per-route basis:\n\n```php\n// The second argument of the factory is a list of regular expressions that will be matched on the path.\n// Here, we disable CSRF checks on /api/*\n$app-\u003epipe(\\TheCodingMachine\\Middlewares\\CsrfHeaderCheckMiddlewareFactory::createDefault([], [\n    '#^/api/#'\n]);\n```\n\nThis can be useful for APIs that are only used when communicating from server to server. Please note that if you decide to disable CSRF for some routes, you need to have some other forms of protection for this route.\n\nAlternatively, any request passed to the middleware that has the 'TheCodingMachine\\BypassCsrf' attribute set will be ignored:\n\n```php\n// Put this in a middleware placed before the `CsrfHeaderCheckMiddleware` to disable it.\n$request = $request-\u003ewithAttribute('TheCodingMachine\\\\BypassCsrf', true);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthecodingmachine%2Fcsrf-header-check-middleware","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthecodingmachine%2Fcsrf-header-check-middleware","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthecodingmachine%2Fcsrf-header-check-middleware/lists"}