CVE-2022-4864 (PHP, published 2022-12-30T23:15Z)
Description: value: Argument Injection in GitHub repository froxlor/froxlor prior to 2.0.0-beta1.
Severity: nan (CVSS v3 base score: 5.4)
Weakness: CWE-74 \u2014 Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')
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.
Repository: https://github.com/froxlor/froxlor
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 message: adjust Request-class methods to be more flexible

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


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');