Fixed bug where CSRF-tokens are not replaced in cached forms.
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

- A bug was discovered where cached forms always would contain the same CSRF-token. This would prevent the hidden token from being replaced, resulting in CSRF-errors in WebComponent on every POST-request.
This commit is contained in:
Abel Hoogeveen 2023-03-06 21:23:27 +01:00
parent c134339526
commit a2f3165e24
Signed by: abelhooge
GPG Key ID: D4F7FB321E3868B7
2 changed files with 45 additions and 1 deletions

View File

@ -43,6 +43,7 @@ use FuzeWorks\Logger;
use FuzeWorks\ObjectStorage\ObjectStorageCache;
use FuzeWorks\ObjectStorage\ObjectStorageComponent;
use FuzeWorks\Priority;
use FuzeWorks\Security;
class Forms implements iLibrary
{
@ -98,7 +99,19 @@ class Forms implements iLibrary
if ($cache->has($key))
{
Logger::log("Returning cached Form '".$name."'");
return $cache->get($key);
/** @var Form $form */
$form = $cache->get($key);
$csrf = $form->getCsrfField();
if (!is_null($csrf))
{
/** @var Security $security */
$security = Factory::getInstance("security");
$hash = $security->get_csrf_hash();
$csrf->setValue($hash);
}
return $form;
}
// Otherwise, create the form

View File

@ -34,6 +34,7 @@
* @version Version 1.3.0
*/
use FuzeWorks\Forms\Fields\HiddenField;
use FuzeWorks\Forms\Form;
use FuzeWorks\Forms\Forms;
use PHPUnit\Framework\TestCase;
@ -84,4 +85,34 @@ class LibraryTest extends TestCase
$this->assertSame($form, $form2);
}
/**
* @depends testGetCachedForm
*/
public function testGetCachedFormCsrfChange()
{
/** @var \FuzeWorks\Security $security */
$security = \FuzeWorks\Factory::getInstance("security");
$hash = $security->get_csrf_hash();
$form = $this->forms->getCachedForm(function (Form $form) {
return $form;
}, 'testGetCachedFormCsrfChange', 'testLabel');
$csrfField = $form->getCsrfField();
$this->assertInstanceOf(HiddenField::class, $csrfField);
$this->assertEquals($hash, $csrfField->getValue());
// Now change the hash
$security->csrf_regenerate();
$newHash = $security->get_csrf_hash();
$this->assertNotEquals($hash, $newHash);
// Regenerate the form
$newForm = $this->forms->getCachedForm(function (Form $form) {
return $form;
}, 'testGetCachedFormCsrfChange', 'testLabel');
$csrfField = $newForm->getCsrfField();
$this->assertEquals($newHash, $csrfField->getValue());
}
}