CVE-2022-4864: Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection') (CWE-74)
value: Argument Injection in GitHub repository froxlor/froxlor prior to 2.0.0-beta1.
CWE description: The product constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component.
CVSS v3 base score: 5.4
Published: 2022-12-30T23:15Z
Repository: https://github.com/froxlor/froxlor
Language: PHP
Files changed: admin_admins.php, admin_configfiles.php, admin_cronjobs.php, admin_customers.php, admin_domains.php, admin_index.php, admin_ipsandports.php, admin_message.php, admin_mysqlserver.php, admin_phpsettings.php, admin_plans.php, admin_settings.php, admin_templates.php, admin_traffic.php, api_keys.php, customer_domains.php, customer_email.php, customer_extras.php, customer_ftp.php, customer_mysql.php, customer_traffic.php, dns_editor.php, error_report.php, lib/Froxlor/Ajax/Ajax.php, lib/Froxlor/Install/Install.php, lib/Froxlor/UI/Request.php, lib/ajax.php, lib/functions.php, lib/init.php, logfiles_viewer.php, ssl_certificates.php
Commit date: 2022-12-30 21:43:27 +0100
Commit message: adjust Request-class methods to be more flexible

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>

Diff: diff --git a/admin_admins.php b/admin_admins.php
index 50be2147..13b38bab 100644
--- a/admin_admins.php
+++ b/admin_admins.php
@@ -37,11 +37,11 @@ use Froxlor\UI\HTML;
 use Froxlor\UI\Listing;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if (($page == 'admins' || $page == 'overview') && $userinfo['change_serversettings'] == '1') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_admins");
 
diff --git a/admin_configfiles.php b/admin_configfiles.php
index 4f0c5432..c3e3f0dd 100644
--- a/admin_configfiles.php
+++ b/admin_configfiles.php
@@ -39,12 +39,12 @@ if ($userinfo['change_serversettings'] == '1') {
 		Settings::Set('panel.is_configured', '1', true);
 		Response::redirectTo('admin_configfiles.php');
 	}
 
 	// get distro from URL param
-	$distribution = Request::get('distribution');
-	$reselect = Request::get('reselect', 0);
+	$distribution = Request::any('distribution');
+	$reselect = Request::any('reselect', 0);
 
 	// check for possible setting
 	if (empty($distribution)) {
 		$distribution = Settings::Get('system.distribution') ?? "";
 	}
diff --git a/admin_cronjobs.php b/admin_cronjobs.php
index 9ad6e27d..e23ce0c0 100644
--- a/admin_cronjobs.php
+++ b/admin_cronjobs.php
@@ -32,11 +32,11 @@ use Froxlor\UI\Collection;
 use Froxlor\UI\Listing;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'cronjobs' || $page == 'overview') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed admin_cronjobs');
 
diff --git a/admin_customers.php b/admin_customers.php
index 0dfabb04..4a403a79 100644
--- a/admin_customers.php
+++ b/admin_customers.php
@@ -40,11 +40,11 @@ use Froxlor\UI\HTML;
 use Froxlor\UI\Listing;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if (($page == 'customers' || $page == 'overview') && $userinfo['customers'] != '0') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_customers");
 
diff --git a/admin_domains.php b/admin_domains.php
index bec95378..77dd9c65 100644
--- a/admin_domains.php
+++ b/admin_domains.php
@@ -45,11 +45,11 @@ use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 use Froxlor\User;
 use Froxlor\Validate\Validate;
 use Froxlor\CurrentUser;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'domains' || $page == 'overview') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_domains");
 
diff --git a/admin_index.php b/admin_index.php
index 8038c7fb..f5479e4e 100644
--- a/admin_index.php
+++ b/admin_index.php
@@ -38,11 +38,11 @@ use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 use Froxlor\Validate\Validate;
 use Froxlor\Language;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($action == 'logout') {
 	$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "logged out");
 	unset($_SESSION['userinfo']);
 	CurrentUser::setData();
diff --git a/admin_ipsandports.php b/admin_ipsandports.php
index c469171d..6a60288b 100644
--- a/admin_ipsandports.php
+++ b/admin_ipsandports.php
@@ -34,11 +34,11 @@ use Froxlor\UI\HTML;
 use Froxlor\UI\Listing;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'ipsandports' || $page == 'overview') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_ipsandports");
 
diff --git a/admin_message.php b/admin_message.php
index 4c473df8..34343acc 100644
--- a/admin_message.php
+++ b/admin_message.php
@@ -31,11 +31,11 @@ use Froxlor\FroxlorLogger;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 use Froxlor\User;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 $note_type = null;
 $note_msg = null;
 
 if ($page == 'message') {
diff --git a/admin_mysqlserver.php b/admin_mysqlserver.php
index dac500ae..c2332d0b 100644
--- a/admin_mysqlserver.php
+++ b/admin_mysqlserver.php
@@ -34,11 +34,11 @@ use Froxlor\UI\HTML;
 use Froxlor\UI\Listing;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'mysqlserver' || $page == 'overview') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_mysqlserver");
 
diff --git a/admin_phpsettings.php b/admin_phpsettings.php
index 77cb6912..208692e2 100644
--- a/admin_phpsettings.php
+++ b/admin_phpsettings.php
@@ -35,11 +35,11 @@ use Froxlor\UI\HTML;
 use Froxlor\UI\Listing;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'overview') {
 	if ($action == '') {
 		try {
 			$phpconf_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/admin/tablelisting.phpconfigs.php';
diff --git a/admin_plans.php b/admin_plans.php
index 734f5799..f25ccd6f 100644
--- a/admin_plans.php
+++ b/admin_plans.php
@@ -37,11 +37,11 @@ use Froxlor\UI\HTML;
 use Froxlor\UI\Listing;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == '' || $page == 'overview') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_plans");
 
@@ -261,11 +261,11 @@ if ($page == '' || $page == 'overview') {
 					'editid' => $id
 				]);
 			}
 		}
 	} elseif ($action == 'jqGetPlanValues') {
-		$planid = (int)Request::get('planid', 0);
+		$planid = (int)Request::any('planid', 0);
 		try {
 			$json_result = HostingPlans::getLocal($userinfo, [
 				'id' => $planid
 			])->get();
 		} catch (Exception $e) {
diff --git a/admin_settings.php b/admin_settings.php
index 4a8f384e..d5b086a4 100644
--- a/admin_settings.php
+++ b/admin_settings.php
@@ -110,11 +110,11 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') {
 		$fields = Form::buildForm($settings_data, $_part);
 
 		if ($_part == '' || $_part == 'all') {
 			UI::view('settings/index.html.twig', ['fields' => $fields]);
 		} else {
-			$em = Request::get('em', '');
+			$em = Request::any('em', '');
 			UI::view('settings/detailpart.html.twig', ['fields' => $fields, 'em' => $em]);
 		}
 	}
 } elseif ($page == 'phpinfo' && $userinfo['change_serversettings'] == '1') {
 	ob_start();
diff --git a/admin_templates.php b/admin_templates.php
index 3aacc009..1f6e7a6c 100644
--- a/admin_templates.php
+++ b/admin_templates.php
@@ -37,13 +37,13 @@ use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 use Froxlor\Validate\Validate;
 use Froxlor\CurrentUser;
 
-$id = (int)Request::get('id');
-$subjectid = intval(Request::get('subjectid'));
-$mailbodyid = intval(Request::get('mailbodyid'));
+$id = (int)Request::any('id');
+$subjectid = intval(Request::any('subjectid'));
+$mailbodyid = intval(Request::any('mailbodyid'));
 
 $available_templates = [
 	'createcustomer',
 	'pop_success',
 	'new_database_by_customer',
diff --git a/admin_traffic.php b/admin_traffic.php
index 352bdc74..cdd46dcf 100644
--- a/admin_traffic.php
+++ b/admin_traffic.php
@@ -29,11 +29,11 @@ require __DIR__ . '/lib/init.php';
 use Froxlor\Traffic\Traffic;
 use Froxlor\UI\Panel\UI;
 use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
-$range = Request::get('range', 'currentmonth');
+$range = Request::any('range', 'currentmonth');
 
 if ($page == 'overview' || $page == 'customers') {
 	try {
 		$context = Traffic::getCustomerStats($userinfo, $range);
 	} catch (Exception $e) {
diff --git a/api_keys.php b/api_keys.php
index 8e34658c..1a566090 100644
--- a/api_keys.php
+++ b/api_keys.php
@@ -47,11 +47,11 @@ if ($userinfo['adminsession'] == 1 && $userinfo['api_allowed'] == 0) {
 
 // This file is being included in admin_index and customer_index
 // and therefore does not need to require lib/init.php
 
 $del_stmt = Database::prepare("DELETE FROM `" . TABLE_API_KEYS . "` WHERE id = :id");
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 // do the delete and then just show a success-message and the apikeys list again
 if ($action == 'delete' && $id > 0) {
 	HTML::askYesNo('apikey_reallydelete', $filename, [
 		'id' => $id,
diff --git a/customer_domains.php b/customer_domains.php
index 26cebcb8..f99f4d7a 100644
--- a/customer_domains.php
+++ b/customer_domains.php
@@ -45,17 +45,17 @@ use Froxlor\CurrentUser;
 // redirect if this customer page is hidden via settings
 if (Settings::IsInList('panel.customer_hide_options', 'domains')) {
 	Response::redirectTo('customer_index.php');
 }
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'overview' || $page == 'domains') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_domains::domains");
 
-		$parentdomain_id = (int)Request::get('pid', '0');
+		$parentdomain_id = (int)Request::any('pid', '0');
 
 		try {
 			$domain_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/customer/tablelisting.domains.php';
 			$collection = (new Collection(SubDomains::class, $userinfo))
 				->withPagination($domain_list_data['domain_list']['columns'], $domain_list_data['domain_list']['default_sorting']);
diff --git a/customer_email.php b/customer_email.php
index 8a42b5ea..0ea4daa8 100644
--- a/customer_email.php
+++ b/customer_email.php
@@ -45,11 +45,11 @@ use Froxlor\CurrentUser;
 // redirect if this customer page is hidden via settings
 if (Settings::IsInList('panel.customer_hide_options', 'email') || $userinfo['emails'] == 0) {
 	Response::redirectTo('customer_index.php');
 }
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'overview' || $page == 'emails') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email::emails");
 
diff --git a/customer_extras.php b/customer_extras.php
index f08b379d..05ee93d7 100644
--- a/customer_extras.php
+++ b/customer_extras.php
@@ -44,11 +44,11 @@ use Froxlor\UI\Response;
 // redirect if this customer page is hidden via settings
 if (Settings::IsInList('panel.customer_hide_options', 'extras')) {
 	Response::redirectTo('customer_index.php');
 }
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'overview' || $page == 'htpasswds') {
 	// redirect if this customer sub-page is hidden via settings
 	if (Settings::IsInList('panel.customer_hide_options', 'extras.directoryprotection')) {
 		Response::redirectTo('customer_index.php');
diff --git a/customer_ftp.php b/customer_ftp.php
index bdf33e97..77da795d 100644
--- a/customer_ftp.php
+++ b/customer_ftp.php
@@ -42,11 +42,11 @@ use Froxlor\CurrentUser;
 // redirect if this customer page is hidden via settings
 if (Settings::IsInList('panel.customer_hide_options', 'ftp') || $userinfo['ftps'] == 0) {
 	Response::redirectTo('customer_index.php');
 }
 
-$id = (int)Request::get('id', 0);
+$id = (int)Request::any('id', 0);
 
 if ($page == 'overview' || $page == 'accounts') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_ftp::accounts");
 		try {
diff --git a/customer_mysql.php b/customer_mysql.php
index f806d147..ceb6ff23 100644
--- a/customer_mysql.php
+++ b/customer_mysql.php
@@ -48,11 +48,11 @@ if (Settings::IsInList('panel.customer_hide_options', 'mysql') || $userinfo['mys
 Database::needRoot(true);
 Database::needSqlData();
 $sql_root = Database::getSqlData();
 Database::needRoot(false);
 
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 if ($page == 'overview' || $page == 'mysqls') {
 	if ($action == '') {
 		$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_mysql::mysqls");
 
diff --git a/customer_traffic.php b/customer_traffic.php
index b5484b6c..74da5213 100644
--- a/customer_traffic.php
+++ b/customer_traffic.php
@@ -35,11 +35,11 @@ use Froxlor\UI\Response;
 // redirect if this customer page is hidden via settings
 if (Settings::IsInList('panel.customer_hide_options', 'traffic')) {
 	Response::redirectTo('customer_index.php');
 }
 
-$range = Request::get('range', 'currentyear');
+$range = Request::any('range', 'currentyear');
 
 if ($page == 'current') {
 	$range = 'currentmonth';
 }
 
diff --git a/dns_editor.php b/dns_editor.php
index 56a86b4e..f6665d51 100644
--- a/dns_editor.php
+++ b/dns_editor.php
@@ -38,11 +38,11 @@ use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
 // This file is being included in admin_domains and customer_domains
 // and therefore does not need to require lib/init.php
 
-$domain_id = (int)Request::get('domain_id');
+$domain_id = (int)Request::any('domain_id');
 
 $record = isset($_POST['dns_record']) ? trim($_POST['dns_record']) : null;
 $type = isset($_POST['dns_type']) ? $_POST['dns_type'] : 'A';
 $prio = isset($_POST['dns_mxp']) ? (int)$_POST['dns_mxp'] : null;
 $content = isset($_POST['dns_content']) ? trim($_POST['dns_content']) : null;
diff --git a/error_report.php b/error_report.php
index 01ff2eb0..c4a8c755 100644
--- a/error_report.php
+++ b/error_report.php
@@ -35,11 +35,11 @@ use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
 // This file is being included in admin_domains and customer_domains
 // and therefore does not need to require lib/init.php
 
-$errid = Request::get('errorid');
+$errid = Request::any('errorid');
 
 if (!empty($errid)) {
 	// read error file
 	$err_dir = FileDir::makeCorrectDir(Froxlor::getInstallDir() . "/logs/");
 	$err_file = FileDir::makeCorrectFile($err_dir . "/" . $errid . "_sql-error.log");
diff --git a/lib/Froxlor/Ajax/Ajax.php b/lib/Froxlor/Ajax/Ajax.php
index d5aa8835..7aaa9d69 100644
--- a/lib/Froxlor/Ajax/Ajax.php
+++ b/lib/Froxlor/Ajax/Ajax.php
@@ -51,12 +51,12 @@ class Ajax
 	/**
 	 * @throws Exception
 	 */
 	public function __construct()
 	{
-		$this->action = $_GET['action'] ?? $_POST['action'] ?? null;
-		$this->theme = $_GET['theme'] ?? 'Froxlor';
+		$this->action = Request::any('action');
+		$this->theme = Request::any('theme', 'Froxlor');
 
 		UI::sendHeaders();
 		UI::sendSslHeaders();
 	}
 
@@ -110,11 +110,12 @@ class Ajax
 		UI::initTwig();
 
 		$feed = "https://inside.froxlor.org/news/";
 
 		// Set custom feed if provided
-		if (isset($_GET['role']) && $_GET['role'] == "customer") {
+		$role = Request::get('role');
+		if ($role == "customer") {
 			$custom_feed = Settings::Get("customer.news_feed_url");
 			if (!empty(trim($custom_feed))) {
 				$feed = $custom_feed;
 			}
 		}
@@ -138,11 +139,11 @@ class Ajax
 		$output = HttpClient::urlGet($feed);
 		$news = simplexml_load_string(trim($output));
 
 		if ($news === false) {
 			$err = [];
-			foreach(libxml_get_errors() as $error) {
+			foreach (libxml_get_errors() as $error) {
 				$err[] = $error->message;
 			}
 			return $this->errorResponse(
 				$err
 			);
@@ -203,21 +204,21 @@ class Ajax
 			$result_rendered = UI::twig()->render($this->theme . '/misc/version_top.html.twig', $result);
 			return $this->jsonResponse($result_rendered);
 		} catch (Exception $e) {
 			// don't display anything if just not allowed due to permissions
 			if ($e->getCode() != 403) {
-				Response::dynamicError($e->getMessage());
+				return $this->errorResponse($e->getMessage(), $e->getCode());
 			}
 		}
 	}
 
 	/**
 	 * search globally in various resources
 	 */
 	private function searchGlobal()
 	{
-		$searchtext = Request::get('searchtext');
+		$searchtext = Request::any('searchtext');
 
 		$result = [];
 
 		// settings
 		$result_settings = [];
@@ -234,31 +235,31 @@ class Ajax
 	}
 
 	private function updateTablelisting()
 	{
 		$columns = [];
-		foreach ((Request::get('columns') ?? []) as $value) {
+		foreach ((Request::any('columns') ?? []) as $value) {
 			$columns[] = $value;
 		}
 		if (!empty($columns)) {
-			Listing::storeColumnListingForUser([Request::get('listing') => $columns]);
+			Listing::storeColumnListingForUser([Request::any('listing') => $columns]);
 			return $this->jsonResponse($columns);
 		}
 		return $this->errorResponse('At least one column must be selected', 406);
 	}
 
 	private function resetTablelisting()
 	{
-		Listing::deleteColumnListingForUser([Request::get('listing') => []]);
+		Listing::deleteColumnListingForUser([Request::any('listing') => []]);
 		return $this->jsonResponse([]);
 	}
 
 	private function editApiKey()
 	{
-		$keyid = isset($_POST['id']) ? (int)$_POST['id'] : 0;
-		$allowed_from = isset($_POST['allowed_from']) ? $_POST['allowed_from'] : "";
-		$valid_until = isset($_POST['valid_until']) ? $_POST['valid_until'] : "";
+		$keyid = Request::post('id', 0);
+		$allowed_from = Request::post('allowed_from', "");
+		$valid_until = Request::post('valid_until', "");
 
 		if (empty($keyid)) {
 			return $this->errorResponse('Invalid call', 406);
 		}
 
@@ -316,13 +317,13 @@ class Ajax
 	 * return parsed commands/files of configuration templates
 	 */
 	private function getConfigDetails()
 	{
 		if (isset($this->userinfo['adminsession']) && $this->userinfo['adminsession'] == 1 && $this->userinfo['change_serversettings'] == 1) {
-			$distribution = isset($_POST['distro']) ? $_POST['distro'] : "";
-			$section = isset($_POST['section']) ? $_POST['section'] : "";
-			$daemon = isset($_POST['daemon']) ? $_POST['daemon'] : "";
+			$distribution = Request::post('distro', "");
+			$section = Request::post('section', "");
+			$daemon = Request::post('daemon', "");
 
 			// validate distribution config-xml exists
 			$config_dir = FileDir::makeCorrectDir(Froxlor::getInstallDir() . '/lib/configfiles/');
 			if (!file_exists($config_dir . "/" . $distribution . ".xml")) {
 				return $this->errorResponse("Unknown distribution. The configuration could not be found.");
@@ -373,11 +374,11 @@ class Ajax
 	/**
 	 * loads a given language string by its identifier
 	 */
 	private function loadLanguageString()
 	{
-		$langid = isset($_POST['langid']) ? $_POST['langid'] : "";
+		$langid = Request::post('langid', "");
 		if (preg_match('/^([a-zA-Z\.]+)$/', $langid)) {
 			return $this->jsonResponse(lng($langid));
 		}
 		return $this->errorResponse('Invalid identifier: ' . $langid, 406);
 	}
diff --git a/lib/Froxlor/Install/Install.php b/lib/Froxlor/Install/Install.php
index 7f96507b..401124a7 100644
--- a/lib/Froxlor/Install/Install.php
+++ b/lib/Froxlor/Install/Install.php
@@ -78,12 +78,12 @@ class Install
 
 		// set formfield, so we can get the fields and steps etc.
 		$this->formfield = require dirname(__DIR__, 3) . '/lib/formfields/install/formfield.install.php';
 
 		// set actual step
-		$this->currentStep = $cliData['step'] ?? Request::get('step', 0);
-		$this->extendedView = $cliData['extended'] ?? Request::get('extended', 0);
+		$this->currentStep = $cliData['step'] ?? Request::any('step', 0);
+		$this->extendedView = $cliData['extended'] ?? Request::any('extended', 0);
 		$this->maxSteps = count($this->formfield['install']['sections']);
 
 		// set actual php version and extensions
 		$this->phpVersion = phpversion();
 		$this->loadedExtensions = get_loaded_extensions();
@@ -112,11 +112,11 @@ class Install
 	 * @throws Exception
 	 */
 	public function handle(): void
 	{
 		// handle form data
-		if (!is_null(Request::get('submit')) && $this->currentStep) {
+		if (!is_null(Request::any('submit')) && $this->currentStep) {
 			try {
 				$this->handleFormData($this->formfield['install']);
 			} catch (Exception $e) {
 				$error = $e->getMessage();
 			}
@@ -264,11 +264,11 @@ class Install
 	 */
 	private function validateRequest(array $fields): array
 	{
 		$attributes = [];
 		foreach ($fields as $name => $field) {
-			$attributes[$name] = $this->validateAttribute(Request::get($name), $field);
+			$attributes[$name] = $this->validateAttribute(Request::any($name), $field);
 			if (isset($field['next_to'])) {
 				$attributes = array_merge($attributes, $this->validateRequest($field['next_to']));
 			}
 		}
 		return $attributes;
diff --git a/lib/Froxlor/UI/Request.php b/lib/Froxlor/UI/Request.php
index 6faa72eb..e053e8b1 100644
--- a/lib/Froxlor/UI/Request.php
+++ b/lib/Froxlor/UI/Request.php
@@ -29,23 +29,51 @@ use Froxlor\PhpHelper;
 use voku\helper\AntiXSS;
 
 class Request
 {
 	/**
-	 * Get key from current request.
+	 * Get key from current $_GET or $_POST request.
 	 *
 	 * @param $key
 	 * @param string|null $default
 	 * @return mixed|string|null
 	 */
-	public static function get($key, string $default = null)
+	public static function any($key, string $default = null)
 	{
 		self::cleanAll();
 
 		return $_GET[$key] ?? $_POST[$key] ?? $default;
 	}
 
+	/**
+	 * Get key from current $_GET request.
+	 *
+	 * @param $key
+	 * @param string|null $default
+	 * @return mixed|string|null
+	 */
+	public static function get($key, string $default = null)
+	{
+		self::cleanAll();
+
+		return $_GET[$key] ?? $default;
+	}
+
+	/**
+	 * Get key from current $_POST request.
+	 *
+	 * @param $key
+	 * @param string|null $default
+	 * @return mixed|string|null
+	 */
+	public static function post($key, string $default = null)
+	{
+		self::cleanAll();
+
+		return $_POST[$key] ?? $default;
+	}
+
 	/**
 	 * Check for xss attempts and clean important globals and
 	 * unsetting every variable registered in $_REQUEST and as variable itself
 	 */
 	public static function cleanAll()
diff --git a/lib/ajax.php b/lib/ajax.php
index 5c7c73a2..eaf34efc 100644
--- a/lib/ajax.php
+++ b/lib/ajax.php
@@ -40,7 +40,8 @@ require_once dirname(__DIR__) . '/lib/tables.inc.php';
 
 // Return response
 try {
 	echo (new Ajax)->handle();
 } catch (Exception $e) {
+	header("Content-Type: application/json");
 	echo \Froxlor\Api\Response::jsonErrorResponse($e->getMessage(), 500);
 }
diff --git a/lib/functions.php b/lib/functions.php
index c9fac4f8..bca5eb0e 100644
--- a/lib/functions.php
+++ b/lib/functions.php
@@ -41,7 +41,7 @@ function lng(string $identifier, array $arguments = [])
 function old(string $identifier, string $default = null, string $session = null)
 {
 	if ($session && isset($_SESSION[$session])) {
 		return $_SESSION[$session][$identifier] ?? $default;
 	}
-	return Request::get($identifier, $default);
+	return Request::any($identifier, $default);
 }
diff --git a/lib/init.php b/lib/init.php
index 33785834..c5d65163 100644
--- a/lib/init.php
+++ b/lib/init.php
@@ -293,13 +293,13 @@ if (is_array($_themeoptions) && array_key_exists('js', $_themeoptions['variants'
 UI::twig()->addGlobal('theme_js', $js);
 UI::twig()->addGlobal('theme_css', $css);
 unset($js);
 unset($css);
 
-$action = Request::get('action');
-$page = Request::get('page', 'overview');
-$gSearchText = Request::get('searchtext');
+$action = Request::any('action');
+$page = Request::any('page', 'overview');
+$gSearchText = Request::any('searchtext');
 
 // clear request data
 if (!$action && isset($_SESSION)) {
 	unset($_SESSION['requestData']);
 }
diff --git a/logfiles_viewer.php b/logfiles_viewer.php
index c4b1dede..20d00d7c 100644
--- a/logfiles_viewer.php
+++ b/logfiles_viewer.php
@@ -37,12 +37,12 @@ use Froxlor\UI\Request;
 use Froxlor\UI\Response;
 
 // This file is being included in admin_domains and customer_domains
 // and therefore does not need to require lib/init.php
 
-$domain_id = (int)Request::get('domain_id');
-$last_n = (int)Request::get('number_of_lines', 100);
+$domain_id = (int)Request::any('domain_id');
+$last_n = (int)Request::any('number_of_lines', 100);
 
 // user's with logviewenabled = false
 if (AREA != 'admin' && $userinfo['logviewenabled'] != '1') {
 	// back to domain overview
 	Response::redirectTo($filename, [
diff --git a/ssl_certificates.php b/ssl_certificates.php
index 72b1bcf7..bd917e68 100644
--- a/ssl_certificates.php
+++ b/ssl_certificates.php
@@ -41,11 +41,11 @@ use Froxlor\UI\Response;
 
 // This file is being included in admin_domains and customer_domains
 // and therefore does not need to require lib/init.php
 
 $success_message = "";
-$id = (int)Request::get('id');
+$id = (int)Request::any('id');
 
 // do the delete and then just show a success-message and the certificates list again
 if ($action == 'delete') {
 	HTML::askYesNo('certificate_reallydelete', $filename, [
 		'id' => $id,

Vulnerable code: $id = (int)Request::get('id');
	$distribution = Request::get('distribution');
	$reselect = Request::get('reselect', 0);
$id = (int)Request::get('id');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
		$planid = (int)Request::get('planid', 0);
			$em = Request::get('em', '');
$id = (int)Request::get('id');
$subjectid = intval(Request::get('subjectid'));
$mailbodyid = intval(Request::get('mailbodyid'));
$range = Request::get('range', 'currentmonth');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
		$parentdomain_id = (int)Request::get('pid', '0');
$id = (int)Request::get('id');
$id = (int)Request::get('id');
$id = (int)Request::get('id', 0);
$id = (int)Request::get('id');
$range = Request::get('range', 'currentyear');
$domain_id = (int)Request::get('domain_id');
$errid = Request::get('errorid');
		$this->action = $_GET['action'] ?? $_POST['action'] ?? null;
		$this->theme = $_GET['theme'] ?? 'Froxlor';
		if (isset($_GET['role']) && $_GET['role'] == "customer") {
			foreach(libxml_get_errors() as $error) {
				Response::dynamicError($e->getMessage());
		$searchtext = Request::get('searchtext');
		foreach ((Request::get('columns') ?? []) as $value) {
			Listing::storeColumnListingForUser([Request::get('listing') => $columns]);
		Listing::deleteColumnListingForUser([Request::get('listing') => []]);
		$keyid = isset($_POST['id']) ? (int)$_POST['id'] : 0;
		$allowed_from = isset($_POST['allowed_from']) ? $_POST['allowed_from'] : "";
		$valid_until = isset($_POST['valid_until']) ? $_POST['valid_until'] : "";
			$distribution = isset($_POST['distro']) ? $_POST['distro'] : "";
			$section = isset($_POST['section']) ? $_POST['section'] : "";
			$daemon = isset($_POST['daemon']) ? $_POST['daemon'] : "";
		$langid = isset($_POST['langid']) ? $_POST['langid'] : "";
		$this->currentStep = $cliData['step'] ?? Request::get('step', 0);
		$this->extendedView = $cliData['extended'] ?? Request::get('extended', 0);
		if (!is_null(Request::get('submit')) && $this->currentStep) {
			$attributes[$name] = $this->validateAttribute(Request::get($name), $field);
	 * Get key from current request.
	public static function get($key, string $default = null)
	return Request::get($identifier, $default);
$action = Request::get('action');
$page = Request::get('page', 'overview');
$gSearchText = Request::get('searchtext');
$domain_id = (int)Request::get('domain_id');
$last_n = (int)Request::get('number_of_lines', 100);
$id = (int)Request::get('id');
Fixed code: $id = (int)Request::any('id');
	$distribution = Request::any('distribution');
	$reselect = Request::any('reselect', 0);
$id = (int)Request::any('id');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
		$planid = (int)Request::any('planid', 0);
			$em = Request::any('em', '');
$id = (int)Request::any('id');
$subjectid = intval(Request::any('subjectid'));
$mailbodyid = intval(Request::any('mailbodyid'));
$range = Request::any('range', 'currentmonth');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
		$parentdomain_id = (int)Request::any('pid', '0');
$id = (int)Request::any('id');
$id = (int)Request::any('id');
$id = (int)Request::any('id', 0);
$id = (int)Request::any('id');
$range = Request::any('range', 'currentyear');
$domain_id = (int)Request::any('domain_id');
$errid = Request::any('errorid');
		$this->action = Request::any('action');
		$this->theme = Request::any('theme', 'Froxlor');
		$role = Request::get('role');
		if ($role == "customer") {
			foreach (libxml_get_errors() as $error) {
				return $this->errorResponse($e->getMessage(), $e->getCode());
		$searchtext = Request::any('searchtext');
		foreach ((Request::any('columns') ?? []) as $value) {
			Listing::storeColumnListingForUser([Request::any('listing') => $columns]);
		Listing::deleteColumnListingForUser([Request::any('listing') => []]);
		$keyid = Request::post('id', 0);
		$allowed_from = Request::post('allowed_from', "");
		$valid_until = Request::post('valid_until', "");
			$distribution = Request::post('distro', "");
			$section = Request::post('section', "");
			$daemon = Request::post('daemon', "");
		$langid = Request::post('langid', "");
		$this->currentStep = $cliData['step'] ?? Request::any('step', 0);
		$this->extendedView = $cliData['extended'] ?? Request::any('extended', 0);
		if (!is_null(Request::any('submit')) && $this->currentStep) {
			$attributes[$name] = $this->validateAttribute(Request::any($name), $field);
	 * Get key from current $_GET or $_POST request.
	public static function any($key, string $default = null)
	/**
	 * Get key from current $_GET request.
	 *
	 * @param $key
	 * @param string|null $default
	 * @return mixed|string|null
	 */
	public static function get($key, string $default = null)
	{
		self::cleanAll();

		return $_GET[$key] ?? $default;
	}

	/**
	 * Get key from current $_POST request.
	 *
	 * @param $key
	 * @param string|null $default
	 * @return mixed|string|null
	 */
	public static function post($key, string $default = null)
	{
		self::cleanAll();

		return $_POST[$key] ?? $default;
	}

	header("Content-Type: application/json");
	return Request::any($identifier, $default);
$action = Request::any('action');
$page = Request::any('page', 'overview');
$gSearchText = Request::any('searchtext');
$domain_id = (int)Request::any('domain_id');
$last_n = (int)Request::any('number_of_lines', 100);
$id = (int)Request::any('id');