Fixed potential hostname validation issues

This commit is contained in:
Pinga 2025-03-07 12:13:41 +02:00
parent 1e9db418f9
commit 813dd16e82
2 changed files with 52 additions and 45 deletions

View file

@ -44,8 +44,8 @@ class HostsController extends Controller
$hostName = $convertedDomain;
}
}
if (preg_match('/^([A-Z0-9]([A-Z0-9-]{0,61}[A-Z0-9]){0,1}\.){1,125}[A-Z0-9]([A-Z0-9-]{0,61}[A-Z0-9])$/i', $hostName) && strlen($hostName) < 254) {
if (isValidHostname($hostName)) {
$host_id_already_exist = $hostModel->getHostByNom($hostName);
if ($host_id_already_exist) {
$this->container->get('flash')->addMessage('error', 'Error creating host: host name ' . $hostName . ' already exists');
@ -55,7 +55,7 @@ class HostsController extends Controller
$this->container->get('flash')->addMessage('error', 'Error creating host: Invalid host name');
return $response->withHeader('Location', '/host/create')->withStatus(302);
}
$result = $db->selectRow('SELECT registrar_id FROM registrar_users WHERE user_id = ?', [$_SESSION['auth_user_id']]);
if ($_SESSION["auth_roles"] != 0) {
@ -244,20 +244,6 @@ class HostsController extends Controller
// Get the current URI
$uri = $request->getUri()->getPath();
function isValidHostname($hostname) {
$hostname = trim($hostname);
// Check for IDN and convert to ASCII if necessary
if (mb_detect_encoding($hostname, 'ASCII', true) === false) {
$hostname = idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
}
// Regular expression for validating a hostname
$pattern = '/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.){2,}(xn--[a-zA-Z0-9-]{2,63}|[a-zA-Z]{2,63})$/';
return preg_match($pattern, $hostname);
}
if ($args && isValidHostname($args)) {
$host = $db->selectRow('SELECT id, name, clid, crdate FROM host WHERE name = ?',
[ $args ]);
@ -318,21 +304,16 @@ class HostsController extends Controller
// Get the current URI
$uri = $request->getUri()->getPath();
function isValidHostname($hostname) {
$hostname = trim($hostname);
// Check for IDN and convert to ASCII if necessary
if (mb_detect_encoding($hostname, 'ASCII', true) === false) {
$hostname = idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
}
// Regular expression for validating a hostname
$pattern = '/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.){2,}(xn--[a-zA-Z0-9-]{2,63}|[a-zA-Z]{2,63})$/';
return preg_match($pattern, $hostname);
}
if ($args && isValidHostname($args)) {
$args = trim($args);
if (mb_detect_encoding($args, 'ASCII', true) === false) {
$args = idn_to_ascii($args, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
if ($args === false) {
// Redirect to the hosts view
return $response->withHeader('Location', '/hosts')->withStatus(302);
}
}
$internal_host = false;
$query = "SELECT tld FROM domain_tld";
@ -565,20 +546,6 @@ class HostsController extends Controller
// Get the current URI
$uri = $request->getUri()->getPath();
function isValidHostname($hostname) {
$hostname = trim($hostname);
// Check for IDN and convert to ASCII if necessary
if (mb_detect_encoding($hostname, 'ASCII', true) === false) {
$hostname = idn_to_ascii($hostname, 0, INTL_IDNA_VARIANT_UTS46);
}
// Regular expression for validating a hostname
$pattern = '/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.){2,}(xn--[a-zA-Z0-9-]{2,63}|[a-zA-Z]{2,63})$/';
return preg_match($pattern, $hostname);
}
if ($args && isValidHostname($args)) {
$host = $db->selectRow('SELECT id, clid FROM host WHERE name = ?',
[ $args ]);

View file

@ -1086,4 +1086,44 @@ function generateIanaIdnTable(string $regex, array $metadata): string {
$output .= "{$hex} # {$name}\n";
}
return $output;
}
function isValidHostname($hostname) {
$hostname = trim($hostname);
// Convert IDN (Unicode) to ASCII if necessary
if (mb_detect_encoding($hostname, 'ASCII', true) === false) {
$hostname = idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
if ($hostname === false) {
return false; // Invalid IDN conversion
}
}
// Ensure there is at least **one dot** (to prevent single-segment hostnames)
if (substr_count($hostname, '.') < 1) {
return false;
}
// Regular expression for validating a hostname
$pattern = '/^((xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.)*([a-zA-Z0-9-]{1,63}|xn--[a-zA-Z0-9-]{2,63})$/';
// Ensure it matches the hostname pattern
if (!preg_match($pattern, $hostname)) {
return false;
}
// Ensure no label exceeds 63 characters
$labels = explode('.', $hostname);
foreach ($labels as $label) {
if (strlen($label) > 63) {
return false;
}
}
// Ensure full hostname is not longer than 255 characters
if (strlen($hostname) > 255) {
return false;
}
return true;
}