Skip to content

Commit 143f457

Browse files
authored
2026-tidy (#214)
* build: upgrade dependencies and test frameworks * tidy: pass existing tests * ci: upgrade test runners * tidy: Gt->GT * build: php8.1 compat * tweak: kill scrutinizer * tweak: use ulid
1 parent f7d6772 commit 143f457

5 files changed

Lines changed: 92 additions & 19 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ This library handles [CSRF protection](https://www.owasp.org/index.php/Cross-Sit
88
<a href="https://github.com/PhpGt/Csrf/actions" target="_blank">
99
<img src="https://badge.status.php.gt/csrf-build.svg" alt="Build status" />
1010
</a>
11-
<a href="https://scrutinizer-ci.com/g/PhpGt/Csrf" target="_blank">
11+
<a href="https://app.codacy.com/gh/PhpGt/Csrf" target="_blank">
1212
<img src="https://badge.status.php.gt/csrf-quality.svg" alt="Code quality" />
1313
</a>
14-
<a href="https://scrutinizer-ci.com/g/PhpGt/Csrf" target="_blank">
14+
<a href="https://app.codecov.io/gh/PhpGt/Csrf" target="_blank">
1515
<img src="https://badge.status.php.gt/csrf-coverage.svg" alt="Code coverage" />
1616
</a>
1717
<a href="https://packagist.org/packages/PhpGt/Csrf" target="_blank">
@@ -85,7 +85,7 @@ echo $protector->getHTMLDocument();
8585
Using tokens of a different lengths
8686
-----------------------------------
8787

88-
By 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()`.
88+
By default, tokens are generated as ULIDs with the prefix `CSRF_`. The configured token length refers to the ULID portion, which is 32 characters long by default in this package. The full token string length is therefore the configured token length plus the length of the prefix `CSRF_`.
8989

9090
Special note about client-side requests
9191
---------------------------------------

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
"require": {
88
"php": ">=8.1",
9-
"phpgt/dom": "^v4.0",
10-
"phpgt/session": "^v1.1"
9+
"phpgt/dom": "^4.0",
10+
"phpgt/session": "^1.1",
11+
"phpgt/ulid": "^1.2"
1112
},
1213
"require-dev": {
1314
"phpstan/phpstan": "^1.10",

composer.lock

Lines changed: 56 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/TokenStore.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use GT\Csrf\Exception\CsrfTokenInvalidException;
55
use GT\Csrf\Exception\CsrfTokenMissingException;
66
use GT\Csrf\Exception\CsrfTokenSpentException;
7+
use GT\Ulid\Ulid;
78

89
/**
910
* Extend this base class to create a store for CSRF tokens. The core functionality of generating
@@ -14,11 +15,9 @@ abstract class TokenStore {
1415
protected int $tokenLength = 32;
1516

1617
/**
17-
* An optional limit of the number of valid tokens the TokenStore will retain may be passed.
18-
* If not specified, an unlimited number of tokens will be retained (which is probably
19-
* fine unless you have a very, very busy site with long-running sessions).
18+
* Optionally configure how many valid tokens the store will retain.
2019
*
21-
* @see static::DEFAULT_MAX_TOKENS
20+
* If not specified, the default limit is 1000 tokens.
2221
*/
2322
public function __construct(?int $maxTokens = null) {
2423
if(!is_null($maxTokens)) {
@@ -31,22 +30,25 @@ public function getMaxTokens():int {
3130
}
3231

3332
/**
34-
* Specify that tokens of a different length should be generated.
33+
* Specify the length of the ULID portion of generated tokens.
3534
*
36-
* @see static::DEFAULT_MAX_TOKENS
35+
* The full token string will also include the "CSRF_" prefix.
3736
*/
3837
public function setTokenLength(int $newTokenLength):void {
3938
$this->tokenLength = $newTokenLength;
4039
}
4140

4241
/**
4342
* Generate a new token. NOTE: This method does NOT store the token.
43+
*
44+
* The generated token is a prefixed ULID, so the full string length is
45+
* the configured token length plus the length of "CSRF_".
4446
*/
4547
public function generateNewToken():string {
46-
// This function uses PHP 7.2's inbuilt random_bytes function, which generates
47-
// raw bytes. When converted to hex, each byte is represented by two
48-
// characters, hence why we divide the token length by two.
49-
return bin2hex(random_bytes($this->tokenLength / 2));
48+
return new Ulid(
49+
prefix: "CSRF",
50+
length: $this->tokenLength,
51+
);
5052
}
5153

5254
/**

test/phpunit/TokenStoreTest.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,17 @@ public function testGenerateNewToken_codesAreUnique():void {
148148

149149
public function testSaveToken_tokenLengthChange():void {
150150
$sut = new ArrayTokenStore();
151-
$sut->setTokenLength(6);
151+
$tokenLength = 16;
152+
$sut->setTokenLength($tokenLength);
152153

153154
$token = $sut->generateNewToken();
154-
self::assertEquals(6, strlen($token));
155+
self::assertStringStartsWith("CSRF_", $token);
156+
self::assertEquals(
157+
strlen("CSRF_") + $tokenLength,
158+
strlen($token)
159+
);
155160

156-
// now make sure the shorter token is successfully stored
161+
// now make sure the custom-length token is successfully stored
157162
$sut->saveToken($token);
158163

159164
$exception = null;
@@ -165,4 +170,14 @@ public function testSaveToken_tokenLengthChange():void {
165170

166171
self::assertNull($exception);
167172
}
173+
174+
public function testGenerateNewToken_usesCsrfUlidPrefix():void {
175+
$sut = new ArrayTokenStore();
176+
$token = $sut->generateNewToken();
177+
self::assertStringStartsWith("CSRF_", $token);
178+
self::assertSame(
179+
strlen("CSRF_") + 32,
180+
strlen($token)
181+
);
182+
}
168183
}

0 commit comments

Comments
 (0)