summaryrefslogtreecommitdiffstats
path: root/vendor/ipl/web/src/Common/CsrfCounterMeasure.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/ipl/web/src/Common/CsrfCounterMeasure.php')
-rw-r--r--vendor/ipl/web/src/Common/CsrfCounterMeasure.php48
1 files changed, 48 insertions, 0 deletions
diff --git a/vendor/ipl/web/src/Common/CsrfCounterMeasure.php b/vendor/ipl/web/src/Common/CsrfCounterMeasure.php
new file mode 100644
index 0000000..348c4ee
--- /dev/null
+++ b/vendor/ipl/web/src/Common/CsrfCounterMeasure.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace ipl\Web\Common;
+
+use ipl\Html\Contract\FormElement;
+use ipl\Html\Form;
+
+trait CsrfCounterMeasure
+{
+ /**
+ * Create a form element to counter measure CSRF attacks
+ *
+ * @param string $uniqueId A unique ID that persists through different requests
+ *
+ * @return FormElement
+ */
+ protected function createCsrfCounterMeasure($uniqueId)
+ {
+ $hashAlgo = in_array('sha3-256', hash_algos(), true) ? 'sha3-256' : 'sha256';
+
+ $seed = random_bytes(16);
+ $token = base64_encode($seed) . '|' . hash($hashAlgo, $uniqueId . $seed);
+
+ /** @var Form $this */
+ return $this->createElement(
+ 'hidden',
+ 'CSRFToken',
+ [
+ 'ignore' => true,
+ 'required' => true,
+ 'value' => $token,
+ 'validators' => ['Callback' => function ($token) use ($uniqueId, $hashAlgo) {
+ if (strpos($token, '|') === false) {
+ die('Invalid CSRF token provided');
+ }
+
+ list($seed, $hash) = explode('|', $token);
+
+ if ($hash !== hash($hashAlgo, $uniqueId . base64_decode($seed))) {
+ die('Invalid CSRF token provided');
+ }
+
+ return true;
+ }]
+ ]
+ );
+ }
+}