PHPackages                             joefallon/phpcsrf - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. joefallon/phpcsrf

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

joefallon/phpcsrf
=================

PhpCsrf is a simple library for cross-site request forgery prevention.

v2.0.1(7mo ago)021MITPHPPHP &gt;=7.4.0

Since Jan 13Pushed 7mo ago1 watchersCompare

[ Source](https://github.com/joefallon/phpcsrf)[ Packagist](https://packagist.org/packages/joefallon/phpcsrf)[ Docs](https://github.com/joefallon/phpcsrf)[ RSS](/packages/joefallon-phpcsrf/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (2)Versions (11)Used By (0)

PhpCsrf
=======

[](#phpcsrf)

Simple, secure, well-tested CSRF protection for PHP applications.

PhpCsrf provides a tiny, easy-to-audit API for generating and validating anti-CSRF tokens on a per-form basis. Tokens are cryptographically secure, single-use, and intentionally minimal so you can understand and integrate quickly.

Why use PhpCsrf?

- Small, dependency-light library (works with the included Session helper).
- Cryptographically secure tokens (uses PHP's CSPRNG via random\_bytes()).
- Tokens are single-use to prevent replay attacks.
- Clear, well-documented API — easy to review and maintain.
- Includes unit tests so you can trust the behaviour.

Quick facts

- Token entropy: 256 bits (32 random bytes, hex-encoded to 64 chars).
- PHP: supports PHP &gt;= 7.4 (see composer.json).
- Session backend: relies on the included `JoeFallon\PhpSession\Session` helper (or any compatible helper exposing `read`, `write`, and `unsetSessionValue`).

Installation
------------

[](#installation)

Install with Composer:

```
composer require joefallon/phpcsrf
```

This package declares `joefallon/phpsession` as a dependency. Make sure your project also meets the PHP version requirement (&gt;= 7.4).

Basic usage (quick start)
-------------------------

[](#basic-usage-quick-start)

1. Create a session helper and CSRF guard:

```
use JoeFallon\PhpSession\Session;
use JoeFallon\PhpCsrf\CsrfGuard;

$session = new Session();
$guard = new CsrfGuard('contact_form', $session);
```

2. When rendering the form, generate a token and include it in the markup:

```
$token = $guard->generateToken();
// Print in a hidden input (escape for HTML)
echo "";
```

3. When processing the form submission, validate the token:

```
$submitted = $_POST['csrf_token'] ?? '';
try {
    if ($guard->isValidToken((string)$submitted)) {
        // Token valid — process the form
    } else {
        // Token invalid — reject the request
        http_response_code(403);
        echo 'Invalid CSRF token.';
    }
} catch (InvalidArgumentException $e) {
    // Token was empty or invalid input
    http_response_code(400);
    echo 'Bad request.';
} catch (RuntimeException $e) {
    // Failure generating secure randomness (rare) — treat as server error
    http_response_code(500);
    echo 'Server error.';
}
```

Important behaviour and notes
-----------------------------

[](#important-behaviour-and-notes)

- Single-use tokens: `isValidToken()` removes the token from the session when called. A token that validates once will not validate again. This defends against replay attacks but means you must regenerate a token for each form render.
- One token per form name: each `CsrfGuard` instance is tied to a form name (string). If you have multiple forms on a page, use distinct names: `new CsrfGuard('login_form', $session)` and `new CsrfGuard('comment_form', $session)`.
- `generateToken()` overwrites any previously stored token for that form name. If you call it multiple times, only the most recent token is valid until consumed.
- Tokens are hex strings (64 chars) and safe to store in session data.

AJAX / Single Page Apps
-----------------------

[](#ajax--single-page-apps)

For XHR/fetch requests you can expose a token via a small endpoint and send the value in a custom header (e.g. `X-CSRF-Token`) or in the request body.

Example: endpoint that returns a token as JSON

```
// token-endpoint.php
$session = new \JoeFallon\PhpSession\Session();
$guard = new \JoeFallon\PhpCsrf\CsrfGuard('ajax_form', $session);
$token = $guard->generateToken();
header('Content-Type: application/json');
echo json_encode(['csrf_token' => $token]);
```

Client-side (fetch):

```
fetch('/token-endpoint.php')
  .then(r => r.json())
  .then(data => {
    // include data.csrf_token as a header or in the request body for subsequent requests
    fetch('/submit', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': data.csrf_token
      },
      body: JSON.stringify({ /* payload */ })
    });
  });
```

Security guidance (do this in your app)
---------------------------------------

[](#security-guidance-do-this-in-your-app)

- Use HTTPS for your site always. Session cookies and tokens should only be transmitted over TLS.
- Configure session cookies with secure flags. Example (set before session start):

```
session_set_cookie_params([
    'secure' => true,      // send only over HTTPS
    'httponly' => true,    // deny access from JavaScript (mitigates XSS token theft)
    'samesite' => 'Lax',   // consider 'Strict' if appropriate for your UX
]);
session_start();
```

- Prevent XSS. If an attacker can run JavaScript in a user's page they can read tokens and session identifiers, which defeats CSRF protection. Use content security policies, proper escaping, and input validation.
- Protect session IDs: avoid exposing session identifiers in URLs, logs, or referrers. Use `session_regenerate_id(true)` on privilege changes (e.g. after login) and follow secure session management practices.

API reference
-------------

[](#api-reference)

- class: `\JoeFallon\PhpCsrf\CsrfGuard`

    - \_\_construct(string $formName, \\JoeFallon\\PhpSession\\Session $session)

        - $formName: non-empty unique name for the form/intent.
        - $session: session helper (must implement `read`, `write`, `unsetSessionValue`).
        - Throws `InvalidArgumentException` for empty names.
    - generateToken(): string

        - Generates a new token, stores it in the session, and returns the hex-encoded token string (64 chars when built with current defaults).
        - Throws `RuntimeException` if secure randomness cannot be obtained.
    - isValidToken(string $token): bool

        - Validates the supplied token against the session-stored value.
        - Throws `InvalidArgumentException` if the provided token is empty.
        - Returns true if the token matches; false otherwise.
        - Removes the token from the session when called (single-use behaviour).

Compatibility
-------------

[](#compatibility)

- PHP 7.4 or later (see composer.json `php` requirement).
- Depends on `joefallon/phpsession` for session helper functionality.

Testing
-------

[](#testing)

This repository includes unit tests. The project was migrated from the legacy `joefallon/kisstest` runner to PHPUnit 9.6 (the last PHPUnit version that supports PHP 7.4). The migration checklist and notes are stored in `MIGRATION_CHECKLIST.md`.

Use the following steps to run the test suite locally.

1. Install dependencies (including dev dependencies):

```
composer install
```

2. Run the tests using the PHPUnit binary installed by Composer. Examples:

On Windows (cmd.exe):

```
vendor\bin\phpunit.bat -c phpunit.xml.dist
```

or (PowerShell / generic):

```
.\vendor\bin\phpunit -c phpunit.xml.dist
```

On Unix-like shells:

```
./vendor/bin/phpunit -c phpunit.xml.dist
```

Notes

- The project uses `phpunit/phpunit` ^9.6 in `require-dev` to remain compatible with PHP 7.4.
- A `phpunit.xml.dist` file is included at the project root and bootstraps `vendor/autoload.php`.
- If you previously ran `php tests/index.php` (the old KissTest runner), that file has been kept as a benign reference but no longer executes a test runner.

Contributing
------------

[](#contributing)

Contributions are welcome. Please follow these guidelines:

- Keep changes small and focused.
- Add unit tests for new behaviour or bug fixes.
- Follow PSR-12 / project coding style.
- Open an issue describing the change before large refactors.

License
-------

[](#license)

This project is licensed under the MIT License. See the LICENSE file for details.

Contact and links
-----------------

[](#contact-and-links)

- Project:
- Author: Joe Fallon ()

Acknowledgements
----------------

[](#acknowledgements)

This project uses the `joefallon/phpsession` helper for session management. Tests are now executed with `phpunit/phpunit` (9.6) after migration from the project's former KissTest-based runner.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance64

Regular maintenance activity

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~490 days

Recently: every ~975 days

Total

9

Last Release

218d ago

Major Versions

v1.0.6 → v2.0.02025-10-12

PHP version history (2 changes)v1.0.0PHP &gt;=5.3.0

v2.0.0PHP &gt;=7.4.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/97cecfa80ffec8e9e7b5d0ff6df026b636e31a15fe0c2155baba402b5d4f0819?d=identicon)[joefallon](/maintainers/joefallon)

---

Top Contributors

[![joefallon](https://avatars.githubusercontent.com/u/4212989?v=4)](https://github.com/joefallon "joefallon (11 commits)")

---

Tags

Authentication

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/joefallon-phpcsrf/health.svg)

```
[![Health](https://phpackages.com/badges/joefallon-phpcsrf/health.svg)](https://phpackages.com/packages/joefallon-phpcsrf)
```

###  Alternatives

[tymon/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

11.5k49.1M350](/packages/tymon-jwt-auth)[league/oauth2-server

A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.

6.6k136.0M248](/packages/league-oauth2-server)[league/oauth2-client

OAuth 2.0 Client Library

3.8k118.6M1.2k](/packages/league-oauth2-client)[google/auth

Google Auth Library for PHP

1.4k272.7M162](/packages/google-auth)[pragmarx/google2fa

A One Time Password Authentication package, compatible with Google Authenticator.

2.0k82.4M164](/packages/pragmarx-google2fa)[paragonie/sodium_compat

Pure PHP implementation of libsodium; uses the PHP extension if it exists

930131.6M155](/packages/paragonie-sodium-compat)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
