{"id":20678890,"url":"https://github.com/phpgt/csrf","last_synced_at":"2025-10-04T16:06:48.564Z","repository":{"id":45400397,"uuid":"51778505","full_name":"phpgt/Csrf","owner":"phpgt","description":"Automatic protection from Cross-Site Request Forgery.","archived":false,"fork":false,"pushed_at":"2025-04-22T13:53:58.000Z","size":369,"stargazers_count":8,"open_issues_count":4,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-02T07:03:35.516Z","etag":null,"topics":["automatic-protection","csrf","csrf-protection","csrf-protector","csrf-tokens","php-security","phpgt","security"],"latest_commit_sha":null,"homepage":"https://www.php.gt/csrf","language":"PHP","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/phpgt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","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},"funding":{"github":["phpgt"]}},"created_at":"2016-02-15T19:08:09.000Z","updated_at":"2024-12-13T00:56:16.000Z","dependencies_parsed_at":"2024-11-16T21:25:37.410Z","dependency_job_id":"de32d541-a2be-417e-9802-04f2a2e21691","html_url":"https://github.com/phpgt/Csrf","commit_stats":{"total_commits":179,"total_committers":6,"mean_commits":"29.833333333333332","dds":"0.45810055865921784","last_synced_commit":"1718512241cdec47406ca43b968edb5a08908fb7"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/phpgt/Csrf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpgt%2FCsrf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpgt%2FCsrf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpgt%2FCsrf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpgt%2FCsrf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phpgt","download_url":"https://codeload.github.com/phpgt/Csrf/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpgt%2FCsrf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278335779,"owners_count":25970192,"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-10-04T02:00:05.491Z","response_time":63,"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":["automatic-protection","csrf","csrf-protection","csrf-protector","csrf-tokens","php-security","phpgt","security"],"created_at":"2024-11-16T21:22:58.103Z","updated_at":"2025-10-04T16:06:48.541Z","avatar_url":"https://github.com/phpgt.png","language":"PHP","funding_links":["https://github.com/sponsors/phpgt"],"categories":[],"sub_categories":[],"readme":"Automatic protection from Cross-Site Request Forgery.\n=====================================================\n\nThis library handles [CSRF protection](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)) automatically for you, including generating tokens, injecting them into all forms in the page and then verifying that a valid token is present whenever a POST request is received.\n\n***\n\n\u003ca href=\"https://github.com/PhpGt/Csrf/actions\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://badge.status.php.gt/csrf-build.svg\" alt=\"Build status\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"https://scrutinizer-ci.com/g/PhpGt/Csrf\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://badge.status.php.gt/csrf-quality.svg\" alt=\"Code quality\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"https://scrutinizer-ci.com/g/PhpGt/Csrf\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://badge.status.php.gt/csrf-coverage.svg\" alt=\"Code coverage\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/PhpGt/Csrf\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://badge.status.php.gt/csrf-version.svg\" alt=\"Current version\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"http://www.php.gt/csrf\" target=\"_blank\"\u003e\n\t\u003cimg src=\"https://badge.status.php.gt/csrf-docs.svg\" alt=\"PHP.Gt/Csrf documentation\" /\u003e\n\u003c/a\u003e\n\nUsage: Protection in Three Steps\n--------------------------------\n\nThe CSRF library does two things:\n\n  * Injects CSRF tokens into `form`s\n  * Verifies `POST` requests to make sure they contain a valid token\n\nEach is just a single method call, but you need to set up first.\n\n### Step 1: Set up\n\nStart by creating the TokenStore. There are currently two implementations — the `ArrayTokenStore` and `SessionTokenStore`.  The `ArrayTokenStore` is the most basic and does not persist in any way, but can be extended into custom integrations. The `SessionTokenStore` is an inbuilt implementation that persists tokens between requests, so that tokens generated for one page request can be checked on another. The easiest way to add CSRF protection is to use the Session:\n\n```php\nuse Gt\\Csrf\\SessionTokenStore;\n\n// $session is an object-oriented representation of $_SESSION\n// that implements the Gt\\Session\\SessionContainer Interface.\n$tokenStore = new SessionTokenStore($session);\n```\n\n### Step 2: Verify\n\nBefore running any other code (especially things that could affect data), you should check to make sure that there's a valid CSRF token in place if it's needed:\n\n```php\nuse Gt\\Csrf\\Exception\\CSRFException;\n\nif(this_is_a_post_request()) {\n\ttry {\n\t\t$tokenStore-\u003everify();\n\t}\n\tcatch(CSRFException $e) {\n// Stop processing this request and get out of there!\n\t}\n}\n```\n\nIf the request contains a POST and there is no valid CSRF token, a `CSRFException` will be thrown — so you should plan to catch it.  Remember, if that happens, the request was fraudulent, so you shouldn't process it!\n\n### Step 3: Inject for Next Time\n\nFinally, once you've finished processing your html code and it's ready to send back to the client, you should inject the CSRF tokens. If you don't, the request will fail to pass Step 2 when the page gets submitted!\n\n```php\nuse Gt\\Csrf\\HTMLDocumentProtector;\n\n// The html can come in as anything accepted by Gt\\Dom\\HTMLDocument - here it's a\n// plain string in a variable.\n$html = \"\u003chtml\u003e...\u003c/html\u003e\";\n\n// Now do the processing.\n$protector = new HTMLDocumentProtector($html, $tokenStore);\n$protector-\u003eprotect();\n\n// Output the HTML of the document - you will see the new fields have\n// been automatically injected.\necho $protector-\u003egetHTMLDocument();\n```\n\nUsing tokens of a different lengths\n-----------------------------------\n\nBy default, 32 character tokens are generated. They use characters from the set [a-zA-Z0-9], meaning a 64-bit token which would take a brute-force attacker making 100,000 requests per second around 2.93 million years to guess. If this seems either excessive or inadequate you can change the token length using `TokenStore::setTokenLength()`.\n\nSpecial note about client-side requests\n---------------------------------------\n\nNote that if there are several forms on your page, a unique token will be generated and injected into each form. When a form is submitted using a client-side request (XMLHTTPRequest or Fetch, a.k.a. AJAX), the response will contain a new token that must be refreshed in the page ready for the next submission.\n\nIf you would prefer to have one token per page, shared across all forms, this can be configured by passing in the TOKEN_PER_PAGE parameter to the projectAndInject method: `$page-\u003eprotectAndInject(HTMLDocumentProtector::TOKEN_PER_PAGE);`.\n\nStoring one token per page will reduce the amount of server resources required, but concurrent client-side requests will fail, which is why one token per form is the default.\n\nAlternatives to storing tokens on the session\n---------------------------------------------\n\nThe package includes an `ArrayTokenStore`, which can be stored on the session. You can implement alternative token stores such as a RDBMS or NoSQL by subclassing `TokenStore` and implementing the abstract methods.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpgt%2Fcsrf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphpgt%2Fcsrf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpgt%2Fcsrf/lists"}