Add CSRF check
This commit is contained in:
49
inc/Main.php
49
inc/Main.php
@@ -6,7 +6,7 @@ use \Settings;
|
|||||||
/**
|
/**
|
||||||
* Main Class
|
* Main Class
|
||||||
* @author franzz
|
* @author franzz
|
||||||
* @version 2.3
|
* @version 2.4
|
||||||
*/
|
*/
|
||||||
abstract class Main extends PhpObject
|
abstract class Main extends PhpObject
|
||||||
{
|
{
|
||||||
@@ -38,6 +38,7 @@ abstract class Main extends PhpObject
|
|||||||
//Variables
|
//Variables
|
||||||
protected $asMasks;
|
protected $asMasks;
|
||||||
protected $asContext;
|
protected $asContext;
|
||||||
|
protected string $sCsrfToken = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Language Translator
|
* Language Translator
|
||||||
@@ -89,7 +90,7 @@ abstract class Main extends PhpObject
|
|||||||
$this->asContext['process_page'] = basename($sProcessPage);
|
$this->asContext['process_page'] = basename($sProcessPage);
|
||||||
|
|
||||||
$sServerName = array_key_exists('SERVER_NAME', $_SERVER)?$_SERVER['SERVER_NAME']:$_SERVER['PWD'];
|
$sServerName = array_key_exists('SERVER_NAME', $_SERVER)?$_SERVER['SERVER_NAME']:$_SERVER['PWD'];
|
||||||
$sScheme = array_key_exists('HTTP_X_FORWARDED_PROTO', $_SERVER)?$_SERVER['HTTP_X_FORWARDED_PROTO']:$_SERVER['REQUEST_SCHEME'];
|
$sScheme = $_SERVER['HTTP_X_FORWARDED_PROTO'] ?? $_SERVER['REQUEST_SCHEME'] ?? 'https';
|
||||||
$sAppPath = $sScheme.'://'.str_replace(array('http://', 'https://'), '', $sServerName.dirname($_SERVER['SCRIPT_NAME']));
|
$sAppPath = $sScheme.'://'.str_replace(array('http://', 'https://'), '', $sServerName.dirname($_SERVER['SCRIPT_NAME']));
|
||||||
$this->asContext['serv_name'] = $sAppPath.(mb_substr($sAppPath, -1)!='/'?'/':'');
|
$this->asContext['serv_name'] = $sAppPath.(mb_substr($sAppPath, -1)!='/'?'/':'');
|
||||||
|
|
||||||
@@ -105,6 +106,46 @@ abstract class Main extends PhpObject
|
|||||||
return file_exists($sCleanedFilePath)?$sCleanedFilePath.'?'.date("YmdHis", filemtime($sCleanedFilePath)):$sFilePath;
|
return file_exists($sCleanedFilePath)?$sCleanedFilePath.'?'.date("YmdHis", filemtime($sCleanedFilePath)):$sFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getCsrfToken() {
|
||||||
|
if($this->sCsrfToken === '') $this->initCsrfToken();
|
||||||
|
return $this->sCsrfToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setCsrfToken() {
|
||||||
|
if(empty($_SESSION['csrf_token'])) $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||||
|
$this->sCsrfToken = $_SESSION['csrf_token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function initCsrfToken() {
|
||||||
|
if(PHP_SAPI === 'cli') return;
|
||||||
|
|
||||||
|
$bCloseSession = false;
|
||||||
|
if(session_status() !== PHP_SESSION_ACTIVE) {
|
||||||
|
$bSecure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https');
|
||||||
|
session_set_cookie_params(array('httponly' => true, 'secure' => $bSecure, 'samesite' => 'Lax'));
|
||||||
|
session_start();
|
||||||
|
$bCloseSession = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setCsrfToken();
|
||||||
|
if($bCloseSession) session_write_close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkCsrfToken(string $sClientToken) {
|
||||||
|
$sServerToken = $this->getCsrfToken();
|
||||||
|
return PHP_SAPI === 'cli' || ($sServerToken !== '' && is_string($sClientToken) && hash_equals($sServerToken, $sClientToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateMutationRequest($sAction, $sCsrfToken='') {
|
||||||
|
return
|
||||||
|
PHP_SAPI === 'cli' //Ignore internal cron job
|
||||||
|
||
|
||||||
|
!in_array($sAction, static::MUTATING_ACTIONS, true) //Ignore non-sensitive requests
|
||||||
|
||
|
||||||
|
($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && $this->checkCsrfToken($sCsrfToken) //Only accept POST requests and valid CSRF token
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
public function addUncaughtError($sError)
|
public function addUncaughtError($sError)
|
||||||
{
|
{
|
||||||
$this->addError('Uncaught errors:'."\n".$sError);
|
$this->addError('Uncaught errors:'."\n".$sError);
|
||||||
@@ -196,4 +237,8 @@ abstract class Main extends PhpObject
|
|||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function validatePositiveInt($oValue=0) {
|
||||||
|
return filter_var($oValue, FILTER_VALIDATE_INT, array('options' => array('default' => 0, 'min_range' => 0)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user