VYPR
Critical severity9.1NVD Advisory· Published Apr 23, 2026· Updated Apr 27, 2026

CVE-2026-41229

CVE-2026-41229

Description

Froxlor is open source server administration software. Prior to version 2.3.6, PhpHelper::parseArrayToString() writes string values into single-quoted PHP string literals without escaping single quotes. When an admin with change_serversettings permission adds or updates a MySQL server via the API, the privileged_user parameter (which has no input validation) is written unescaped into lib/userdata.inc.php. Since this file is required on every request via Database::getDB(), an attacker can inject arbitrary PHP code that executes as the web server user on every subsequent page load. Version 2.3.6 contains a patch.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
froxlor/froxlorPackagist
< 2.3.62.3.6

Affected products

1

Patches

1
3589ddf93ab5

fix escaping of single-quotes in generation of userdata.inc.php and validate privileged-user and mysql_ca in MysqlServer.add/update

https://github.com/froxlor/froxlorMichael KaufmannMar 29, 2026via ghsa
2 files changed · +8 1
  • lib/Froxlor/Api/Commands/MysqlServer.php+5 0 modified
    @@ -29,6 +29,7 @@
     use Froxlor\Api\ApiCommand;
     use Froxlor\Api\ResourceEntity;
     use Froxlor\Database\Database;
    +use Froxlor\FileDir;
     use Froxlor\Froxlor;
     use Froxlor\FroxlorLogger;
     use Froxlor\PhpHelper;
    @@ -103,6 +104,8 @@ public function add()
     			}
     		}
     		$mysql_port = Validate::validate($mysql_port, 'port', Validate::REGEX_PORT, '', [3306], true);
    +		$mysql_ca = !empty($mysql_ca) ? FileDir::makeCorrectFile($mysql_ca) : '';
    +		$privileged_user = Validate::validate($privileged_user, 'privileged_user', '/^[a-z][a-z0-9\-_]+$/i', '', [], true);
     		$privileged_password = Validate::validate($privileged_password, 'password', '', '', [], true);
     		$description = Validate::validate(trim($description), 'description', Validate::REGEX_DESC_TEXT, '', [], true);
     
    @@ -402,6 +405,8 @@ public function update()
     			}
     		}
     		$mysql_port = Validate::validate($mysql_port, 'port', Validate::REGEX_PORT, '', [3306], true);
    +		$mysql_ca = !empty($mysql_ca) ? FileDir::makeCorrectFile($mysql_ca) : '';
    +		$privileged_user = Validate::validate($privileged_user, 'privileged_user', '/^[a-z][a-z0-9\-_]+$/i', '', [], true);
     		$privileged_password = Validate::validate($privileged_password, 'password', '', '', [], true);
     		$description = Validate::validate(trim($description), 'description', Validate::REGEX_DESC_TEXT, '', [], true);
     
    
  • lib/Froxlor/PhpHelper.php+3 1 modified
    @@ -483,7 +483,9 @@ public static function parseArrayToString(array $array, ?string $key = null, int
     						// special case for passwords (nowdoc)
     						$str .= self::tabPrefix($depth, "'{$key}' => <<<'EOT'\n{$value}\nEOT,\n");
     					} else {
    -						$str .= self::tabPrefix($depth, "'{$key}' => '{$value}',\n");
    +						// escape backslashes first, then single quotes:
    +						$escaped = str_replace(['\\', "'"], ['\\\\', "\\'"], $value);
    +						$str .= self::tabPrefix($depth, "'{$key}' => '{$escaped}',\n");
     					}
     				}
     			} else {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.