1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124:
<?php
namespace MvcCore\Ext\Form;
trait Csrf {
public static function ProcessCsrfErrorHandlersQueue (\MvcCore\Ext\IForm $form, $errorMsg) {
$request = $form->GetRequest();
$response = $form->GetResponse();
foreach (static::$csrfErrorHandlers as $handlersRecord) {
list ($handler, $isClosure) = $handlersRecord;
try {
if ($isClosure) {
$handler($form, $request, $response, $errorMsg);
} else {
call_user_func($handler, $form, $request, $response, $errorMsg);
}
} catch (\Exception $e) {
$debugClass = $form->GetApplication()->GetDebugClass();
$debugClass::Log($e, \MvcCore\IDebug::CRITICAL);
} catch (\Throwable $e) {
$debugClass = $form->GetApplication()->GetDebugClass();
$debugClass::Log($e, \MvcCore\IDebug::CRITICAL);
}
}
}
public function SetEnableCsrf ($enabled = TRUE) {
$this->csrfEnabled = $enabled;
return $this;
}
public function GetCsrf () {
$session = & $this->getSession();
list($name, $value) = $session->csrf;
return (object) ['name' => $name, 'value' => $value];
}
public function SubmitCsrfTokens (array & $rawRequestParams = []) {
if (!$this->csrfEnabled) return $this;
$result = FALSE;
$session = & $this->getSession();
list($name, $value) = $session->csrf
? $session->csrf :
[NULL, NULL];
if ($name !== NULL && $value !== NULL)
if (isset($rawRequestParams[$name]) && $rawRequestParams[$name] === $value)
$result = TRUE;
if (!$result) {
$errorMsg = $this->GetDefaultErrorMsg(\MvcCore\Ext\Forms\IError::CSRF);
if ($this->translate)
$errorMsg = call_user_func($this->translator, $errorMsg);
$this->AddError($errorMsg);
static::ProcessCsrfErrorHandlersQueue($this, $errorMsg);
}
return $this;
}
public function SetUpCsrf () {
$requestUrl = $this->request->GetBaseUrl() . $this->request->GetPath();
if (function_exists('openssl_random_pseudo_bytes')) {
$randomHash = bin2hex(openssl_random_pseudo_bytes(32));
} else if (PHP_VERSION_ID >= 70000) {
$randomHash = bin2hex(random_bytes(32));
} else {
$randomHash = '';
for ($i = 0; $i < 32; $i++)
$randomHash .= str_pad(dechex(rand(0,255)),2,'0',STR_PAD_LEFT);
}
$nowTime = (string)time();
$name = '____'.sha1($this->id . $requestUrl . 'name' . $nowTime . $randomHash);
$value = sha1($this->id . $requestUrl . 'value' . $nowTime . $randomHash);
$session = & $this->getSession();
$session->csrf = [$name, $value];
return [$name, $value];
}
}