use Request-wrapper-class for every access to $_POST superglobal

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2024-05-09 15:48:23 +02:00
parent 914204b483
commit fce310049a
42 changed files with 303 additions and 254 deletions

View File

@@ -115,7 +115,7 @@ class DomainZones extends ApiCommand implements ResourceEntity
// validation
$errors = [];
if (empty($record)) {
if (empty(trim($record))) {
$record = "@";
}

View File

@@ -58,6 +58,7 @@ final class UpdateCommand extends CliCommand
if ($input->getOption('database')) {
$result = $this->validateRequirements($output, true);
if ($result == self::SUCCESS) {
require Froxlor::getInstallDir() . '/lib/functions.php';
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
$output->writeln('<info>' . lng('updates.dbupdate_required') . '</>');
if ($input->getOption('check-only')) {

View File

@@ -211,7 +211,7 @@ class ReportsCron extends FroxlorCron
$_mailerror = false;
$mailerr_msg = "";
try {
$mail->SetFrom($row['email'], $row['name']);
$mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
$mail->Subject = $mail_subject;
$mail->AltBody = $mail_body;
$mail->MsgHTML(nl2br($mail_body));
@@ -297,7 +297,7 @@ class ReportsCron extends FroxlorCron
$_mailerror = false;
$mailerr_msg = "";
try {
$mail->SetFrom($row['email'], $row['name']);
$mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
$mail->Subject = $mail_subject;
$mail->Body = $mail_body;
$mail->MsgHTML(nl2br($mail_body));
@@ -472,7 +472,7 @@ class ReportsCron extends FroxlorCron
$_mailerror = false;
$mailerr_msg = "";
try {
$mail->SetFrom($row['email'], $row['name']);
$mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
$mail->Subject = $mail_subject;
$mail->AltBody = $mail_body;
$mail->MsgHTML(nl2br($mail_body));

View File

@@ -417,6 +417,9 @@ class PhpHelper
'admin_pass',
'admin_pass_confirm',
'panel_password_special_char',
'old_password',
'new_password',
'new_password_confirm',
];
if (!empty($global)) {
$tmp = $global;

View File

@@ -36,6 +36,7 @@ use Froxlor\PhpHelper;
use Froxlor\Settings;
use Froxlor\System\Cronjob;
use Froxlor\System\IPTools;
use Froxlor\UI\Request;
use Froxlor\Validate\Validate;
use PDO;
@@ -465,7 +466,7 @@ class Store
}
// Delete file?
if ($fielddata['value'] !== "" && array_key_exists($fieldname . '_delete', $_POST) && $_POST[$fieldname . '_delete']) {
if ($fielddata['value'] !== "" && array_key_exists($fieldname . '_delete', $_POST) && Request::post($fieldname . '_delete')) {
@unlink(Froxlor::getInstallDir() . '/' . explode('?', $fielddata['value'], 2)[0]);
$save_to = '';
}

View File

@@ -30,14 +30,16 @@ use voku\helper\AntiXSS;
class Request
{
private static $cleaned = false;
/**
* Get key from current $_GET or $_POST request.
*
* @param $key
* @param string|null $default
* @param mixed|null $default
* @return mixed|string|null
*/
public static function any($key, string $default = null)
public static function any($key, $default = null)
{
self::cleanAll();
@@ -48,10 +50,10 @@ class Request
* Get key from current $_GET request.
*
* @param $key
* @param string|null $default
* @param mixed|null $default
* @return mixed|string|null
*/
public static function get($key, string $default = null)
public static function get($key, $default = null)
{
self::cleanAll();
@@ -62,37 +64,53 @@ class Request
* Get key from current $_POST request.
*
* @param $key
* @param string|null $default
* @param mixed|null $default
* @return mixed|string|null
*/
public static function post($key, string $default = null)
public static function post($key, $default = null)
{
self::cleanAll();
return $_POST[$key] ?? $default;
}
/**
* return complete $_POST array
*
* @return array
*/
public static function postAll()
{
self::cleanAll();
return $_POST ?? [];
}
/**
* Check for xss attempts and clean important globals and
* unsetting every variable registered in $_REQUEST and as variable itself
*/
public static function cleanAll()
{
foreach ($_REQUEST as $key => $value) {
if (isset($$key)) {
unset($$key);
if (!self::$cleaned) {
foreach ($_REQUEST as $key => $value) {
if (isset($$key)) {
unset($$key);
}
}
unset($value);
$antiXss = new AntiXSS();
// check $_GET
PhpHelper::cleanGlobal($_GET, $antiXss);
// check $_POST
PhpHelper::cleanGlobal($_POST, $antiXss);
// check $_COOKIE
PhpHelper::cleanGlobal($_COOKIE, $antiXss);
self::$cleaned = true;
}
unset($value);
$antiXss = new AntiXSS();
// check $_GET
PhpHelper::cleanGlobal($_GET, $antiXss);
// check $_POST
PhpHelper::cleanGlobal($_POST, $antiXss);
// check $_COOKIE
PhpHelper::cleanGlobal($_COOKIE, $antiXss);
}
/**

View File

@@ -28,6 +28,7 @@ namespace Froxlor\Validate;
use Froxlor\Database\Database;
use Froxlor\FileDir;
use Froxlor\Settings;
use Froxlor\UI\Request;
class Check
{
@@ -73,7 +74,7 @@ class Check
// interface is to be enabled
if ((int)$newfieldvalue == 1) {
// check for POST value of the other field == 1 (active)
if (isset($_POST[$check_array[$fieldname]['other_post_field']]) && (int)$_POST[$check_array[$fieldname]['other_post_field']] == 1) {
if ((int)Request::post($check_array[$fieldname]['other_post_field'], 0) == 1) {
// the other interface is activated already and STAYS activated
if ((int)Settings::Get($check_array[$fieldname]['other_enabled']) == 1) {
$returnvalue = [
@@ -83,8 +84,12 @@ class Check
} else {
// fcgid is being validated before fpm -> "ask" fpm about its state
if ($fieldname == 'system_mod_fcgid_enabled') {
$returnvalue = self::checkFcgidPhpFpm('system_phpfpm_enabled', null,
$check_array[$fieldname]['other_post_field'], null);
$returnvalue = self::checkFcgidPhpFpm(
'system_phpfpm_enabled',
null,
$check_array[$fieldname]['other_post_field'],
null
);
} else {
// not, bot are nogo
$returnvalue = $returnvalue = [
@@ -117,8 +122,16 @@ class Check
$mysql_access_host_array = array_unique(array_map('trim', explode(',', $newfieldvalue)));
foreach ($mysql_access_host_array as $host_entry) {
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true, true, true,
false) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
if (Validate::validate_ip2(
$host_entry,
true,
'invalidip',
true,
true,
true,
true,
false
) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
return [
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
'invalidmysqlhost',
@@ -204,8 +217,11 @@ class Check
}
// neither dir can be within the other nor can they be equal
if (substr($newdir, 0, strlen($cdir)) == $cdir || substr($cdir, 0,
strlen($newdir)) == $newdir || $newdir == $cdir) {
if (substr($newdir, 0, strlen($cdir)) == $cdir || substr(
$cdir,
0,
strlen($newdir)
) == $newdir || $newdir == $cdir) {
$returnvalue = [
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
'fcgidpathcannotbeincustomerdoc'
@@ -264,8 +280,11 @@ class Check
}
$returnvalue = [];
if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'),
Database::getSqlUsernameLength() - strlen($allnewfieldvalues['customer_mysqlprefix'])) === true) {
if (Validate::validateUsername(
$newfieldvalue,
Settings::Get('panel.unix_names'),
Database::getSqlUsernameLength() - strlen($allnewfieldvalues['customer_mysqlprefix'])
) === true) {
$returnvalue = [
self::FORMFIELDS_PLAUSIBILITY_CHECK_OK
];
@@ -330,7 +349,7 @@ class Check
];
}
// check if the pgp public key is a valid key
putenv('GNUPGHOME='.sys_get_temp_dir());
putenv('GNUPGHOME=' . sys_get_temp_dir());
if (gnupg_import(gnupg_init(), $newfieldvalue) === false) {
return [
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<froxlor>
<distribution name="Ubuntu" codename="noble"
<distribution name="Ubuntu" codename="Noble"
version="24.04" defaulteditor="/bin/nano">
<!-- OS defaults to be loaded on installation -->
<defaults>

View File

@@ -361,7 +361,7 @@ if (CurrentUser::hasSession()) {
UI::twig()->addGlobal('csrf_token', $csrf_token);
// check if csrf token is valid
if (in_array($_SERVER['REQUEST_METHOD'], ['POST', 'PUT', 'PATCH', 'DELETE'])) {
$current_token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null;
$current_token = Request::post('csrf_token', $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null);
if ($current_token != CurrentUser::getField('csrf_token')) {
http_response_code(403);
Response::dynamicError('CSRF validation failed');