security: faza 4 - ochrona CSRF panelu administracyjnego
- Nowa klasa \Shared\Security\CsrfToken (generate/validate/regenerate) - Token CSRF we wszystkich formularzach edycji (form-edit.php) - Walidacja CSRF w FormRequestHandler::handleSubmit() - Token CSRF w formularzu logowania i formularzach 2FA - Walidacja CSRF w App::special_actions() dla żądań POST - Regeneracja tokenu po udanym logowaniu (bezpośrednia i przez 2FA) - Fix XSS: htmlspecialchars na $alert w unlogged-layout.php - 7 nowych testów CsrfTokenTest (817 testów łącznie) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
60
tests/Unit/Shared/Security/CsrfTokenTest.php
Normal file
60
tests/Unit/Shared/Security/CsrfTokenTest.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Tests\Unit\Shared\Security;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shared\Security\CsrfToken;
|
||||
|
||||
class CsrfTokenTest extends TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
$_SESSION = [];
|
||||
}
|
||||
|
||||
public function testGetTokenReturns64CharHexString(): void
|
||||
{
|
||||
$token = CsrfToken::getToken();
|
||||
$this->assertIsString($token);
|
||||
$this->assertSame(64, strlen($token));
|
||||
$this->assertMatchesRegularExpression('/^[0-9a-f]{64}$/', $token);
|
||||
}
|
||||
|
||||
public function testGetTokenIsIdempotent(): void
|
||||
{
|
||||
$first = CsrfToken::getToken();
|
||||
$second = CsrfToken::getToken();
|
||||
$this->assertSame($first, $second);
|
||||
}
|
||||
|
||||
public function testValidateReturnsTrueForCorrectToken(): void
|
||||
{
|
||||
$token = CsrfToken::getToken();
|
||||
$this->assertTrue(CsrfToken::validate($token));
|
||||
}
|
||||
|
||||
public function testValidateReturnsFalseForEmptyString(): void
|
||||
{
|
||||
CsrfToken::getToken();
|
||||
$this->assertFalse(CsrfToken::validate(''));
|
||||
}
|
||||
|
||||
public function testValidateReturnsFalseForWrongToken(): void
|
||||
{
|
||||
CsrfToken::getToken();
|
||||
$this->assertFalse(CsrfToken::validate('aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899'));
|
||||
}
|
||||
|
||||
public function testValidateReturnsFalseWhenNoSessionToken(): void
|
||||
{
|
||||
$this->assertFalse(CsrfToken::validate('sometoken'));
|
||||
}
|
||||
|
||||
public function testRegenerateChangesToken(): void
|
||||
{
|
||||
$before = CsrfToken::getToken();
|
||||
CsrfToken::regenerate();
|
||||
$after = CsrfToken::getToken();
|
||||
$this->assertNotSame($before, $after);
|
||||
$this->assertSame(64, strlen($after));
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
|
||||
'admin\\ViewModels\\Forms\\' => __DIR__ . '/../autoload/admin/ViewModels/Forms/',
|
||||
'admin\\Validation\\' => __DIR__ . '/../autoload/admin/Validation/',
|
||||
'api\\' => __DIR__ . '/../autoload/api/',
|
||||
'Shared\\Security\\' => __DIR__ . '/../autoload/Shared/Security/',
|
||||
];
|
||||
|
||||
foreach ($prefixes as $prefix => $baseDir) {
|
||||
|
||||
Reference in New Issue
Block a user