22
33namespace Icinga \Module \Director \Web \Form ;
44
5- use Icinga \ Web \ Session ;
5+ use ipl \ Html \ Contract \ FormElement ;
66use ipl \Html \Form ;
7+ use ipl \Html \FormElement \HiddenElement ;
78use ipl \Html \ValidHtml ;
8- use ipl \Web \Common \CsrfCounterMeasure ;
99
1010class PropertyTableSortForm extends Form
1111{
12- use CsrfCounterMeasure;
13-
1412 protected $ method = 'POST ' ;
1513
1614 /** @var string Name of the form */
@@ -28,7 +26,38 @@ public function __construct(string $name, ValidHtml $table)
2826 protected function assemble ()
2927 {
3028 $ this ->addElement ('hidden ' , '__FORM_NAME ' , ['value ' => $ this ->name ]);
31- $ this ->addElement ($ this ->createCsrfCounterMeasure (Session:: getSession ()-> getId () ));
29+ $ this ->addElement ($ this ->createCsrfCounterMeasure ());
3230 $ this ->addHtml ($ this ->table );
3331 }
32+
33+ /**
34+ * Create a form element to countermeasure CSRF attacks
35+ *
36+ * @return FormElement
37+ */
38+ protected function createCsrfCounterMeasure (): FormElement
39+ {
40+ $ token = CsrfToken::generate ();
41+
42+ $ options = [
43+ 'ignore ' => true ,
44+ 'required ' => true ,
45+ 'validators ' => ['Callback ' => function ($ token ) {
46+ return CsrfToken::isValid ($ token );
47+ }]
48+ ];
49+
50+ $ element = new class (QuickForm::CSRF , $ options ) extends HiddenElement {
51+ public function hasValue (): bool
52+ {
53+ return true ; // The validator must run even if the value is empty
54+ }
55+ };
56+
57+ $ element ->getAttributes ()->registerAttributeCallback ('value ' , function () use ($ token ) {
58+ return $ token ;
59+ });
60+
61+ return $ element ;
62+ }
3463}
0 commit comments