more rework on path/url validation for domains/subdomains documentroot, fixes #1325

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2025-04-29 19:57:07 +02:00
parent ce4f64e73a
commit 46a46816b0
4 changed files with 46 additions and 26 deletions

View File

@@ -595,12 +595,20 @@ class Domains extends ApiCommand implements ResourceEntity
$ssl_redirect = 2;
}
if (!preg_match('/^https?\:\/\//', $documentroot)) {
if (strstr($documentroot, ":") !== false) {
// Check if given documentroot is either a valid URL or a valid path
if (preg_match('/^https?\:\/\//', $documentroot)) {
$encoded = $idna_convert->encode($documentroot);
if (!Validate::validateUrl($encoded, true)) {
Response::standardError('invaliddocumentrooturl', '', true);
}
$documentroot = $encoded;
} else {
if (strpos($documentroot, ':') !== false) {
Response::standardError('pathmaynotcontaincolon', '', true);
} else {
$documentroot = FileDir::makeCorrectDir($documentroot);
}
$documentroot = FileDir::makeCorrectDir($documentroot);
}
$domain_check_stmt = Database::prepare("
@@ -1414,8 +1422,18 @@ class Domains extends ApiCommand implements ResourceEntity
}
}
if (!preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
Response::standardError('pathmaynotcontaincolon', '', true);
$idna_convert = new IdnaWrapper();
if (preg_match('/^https?\:\/\//', $documentroot)) {
$encoded = $idna_convert->encode($documentroot);
if (!Validate::validateUrl($encoded, true)) {
Response::standardError('invaliddocumentrooturl', '', true);
}
$documentroot = $encoded;
} else {
if (strpos($documentroot, ':') !== false) {
Response::standardError('pathmaynotcontaincolon', '', true);
}
$documentroot = FileDir::makeCorrectDir($documentroot);
}
if ($this->getUserDetail('change_serversettings') == '1') {
@@ -2099,7 +2117,6 @@ class Domains extends ApiCommand implements ResourceEntity
}
}
$idna_convert = new IdnaWrapper();
$this->logger()->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated domain '" . $idna_convert->decode($result['domain']) . "'");
$result = $this->apiCall('Domains.get', [
'domainname' => $result['domain']

View File

@@ -549,32 +549,33 @@ class SubDomains extends ApiCommand implements ResourceEntity
*/
private function validateDomainDocumentRoot($path = null, $url = null, $customer = null, $completedomain = null, &$_doredirect = false)
{
// check whether an URL was specified
$_doredirect = false;
if (!empty($url) && Validate::validateUrl($url, true)) {
$path = $url;
$idna = new IdnaWrapper();
// url mode: either $url or $path begins with http:// or https://
$maybeUrl = !empty($url) ? $url : (preg_match('/^https?\:\/\//', $path) ? $path : '');
if ($maybeUrl !== '') {
$encoded = $idna->encode($maybeUrl);
if (!Validate::validateUrl($encoded, true)) {
Response::standardError('invaliddocumentrooturl', '', true);
}
$_doredirect = true;
} else {
$path = Validate::validate($path, 'path', '', '', [], true);
return $encoded;
}
// check whether path is a real path
if (!preg_match('/^https?\:\/\//', $path) || !Validate::validateUrl($path, true)) {
if (strstr($path, ":") !== false) {
Response::standardError('pathmaynotcontaincolon', '', true);
}
// If path is empty or '/' and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
// set default path to subdomain or domain name
if ((($path == '') || ($path == '/')) && Settings::Get('system.documentroot_use_default_value') == 1) {
$path = FileDir::makeCorrectDir($customer['documentroot'] . '/' . $completedomain, $customer['documentroot']);
} else {
$path = FileDir::makeCorrectDir($customer['documentroot'] . '/' . $path, $customer['documentroot']);
}
} else {
// no it's not, create a redirect
$_doredirect = true;
// path mode: regular directory path
$path = Validate::validate($path, 'path', Validate::REGEX_DIR, '', [], true);
// default path if empty and setting active
if (($path === '' || $path === '/') && Settings::Get('system.documentroot_use_default_value') == 1) {
return FileDir::makeCorrectDir($customer['documentroot'] . '/' . $completedomain, $customer['documentroot']);
}
return $path;
// check if path does not contain a colon
if (strpos($path, ':') !== false) {
Response::standardError('pathmaynotcontaincolon', '', true);
}
return FileDir::makeCorrectDir($customer['documentroot'] . '/' . $path, $customer['documentroot']);
}
/**

View File

@@ -878,6 +878,7 @@ return [
'plausibilitychecknotunderstood' => 'Die Antwort des Plausibilitätschecks wurde nicht verstanden',
'errorwhensaving' => 'Bei dem Speichern des Feldes "%s" trat ein Fehler auf',
'pathmaynotcontaincolon' => 'Der eingegebene Pfad sollte keinen Doppelpunkt (":") enthalten. Bitte geben Sie einen korrekten Wert für den Pfad ein.',
'invaliddocumentrooturl' => 'Die URL, die Sie für den Pfad eingegeben haben, ist ungültig. Bitte geben Sie eine korrekte URL oder einen Unix-Pfad ein.',
'notrequiredpasswordcomplexity' => 'Die vorgegebene Passwort-Komplexität wurde nicht erfüllt.<br />Bitte kontaktieren Sie Ihren Administrator, wenn Sie Fragen zur Komplexitäts-Vorgabe haben.',
'stringerrordocumentnotvalidforlighty' => 'Ein Text als Fehlerdokument funktioniert leider in LigHTTPd nicht, bitte geben Sie einen Pfad zu einer Datei an',
'urlerrordocumentnotvalidforlighty' => 'Eine URL als Fehlerdokument funktioniert leider in LigHTTPd nicht, bitte geben Sie einen Pfad zu einer Datei an',

View File

@@ -951,6 +951,7 @@ return [
'notrequiredpasswordlength' => 'The given password is too short. Please enter at least %s characters.',
'overviewsettingoptionisnotavalidfield' => 'Whoops, a field that should be displayed as an option in the settings-overview is not an excepted type. You can blame the developers for this. This should not happen!',
'pathmaynotcontaincolon' => 'The path you have entered should not contain a colon (":"). Please enter a correct path value.',
'invaliddocumentrooturl' => 'The URL you have entered for the documentroot is not valid. Please enter a correct URL or a unix-path.',
'exception' => '%s',
'notrequiredpasswordcomplexity' => 'The specified password-complexity was not satisfied.<br />Please contact your administrator if you have any questions about the complexity-specification',
'stringerrordocumentnotvalidforlighty' => 'A string as ErrorDocument does not work in lighttpd, please specify a path to a file',