From 2dd226c96c14e024b104a8cd9beab212eae24b46 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Tue, 20 Dec 2022 17:20:40 +0100 Subject: [PATCH] allow domain-redirect to internal-ipaddress Signed-off-by: Michael Kaufmann --- lib/Froxlor/Api/Commands/SubDomains.php | 4 ++-- lib/Froxlor/Validate/Validate.php | 10 ++++++++-- lib/configfiles/focal.xml | 11 +++++++++++ tests/Froxlor/ValidateTest.php | 10 ++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/Froxlor/Api/Commands/SubDomains.php b/lib/Froxlor/Api/Commands/SubDomains.php index 1da11937..a9547941 100644 --- a/lib/Froxlor/Api/Commands/SubDomains.php +++ b/lib/Froxlor/Api/Commands/SubDomains.php @@ -538,7 +538,7 @@ class SubDomains extends ApiCommand implements ResourceEntity { // check whether an URL was specified $_doredirect = false; - if (!empty($url) && Validate::validateUrl($url)) { + if (!empty($url) && Validate::validateUrl($url, true)) { $path = $url; $_doredirect = true; } else { @@ -546,7 +546,7 @@ class SubDomains extends ApiCommand implements ResourceEntity } // check whether path is a real path - if (!preg_match('/^https?\:\/\//', $path) || !Validate::validateUrl($path)) { + if (!preg_match('/^https?\:\/\//', $path) || !Validate::validateUrl($path, true)) { if (strstr($path, ":") !== false) { Response::standardError('pathmaynotcontaincolon', '', true); } diff --git a/lib/Froxlor/Validate/Validate.php b/lib/Froxlor/Validate/Validate.php index 70d588e6..99d544ad 100644 --- a/lib/Froxlor/Validate/Validate.php +++ b/lib/Froxlor/Validate/Validate.php @@ -181,10 +181,12 @@ class Validate * * @param string $url * URL to be tested + * @param bool $allow_private_ip + * optional, default is false * * @return bool */ - public static function validateUrl($url) + public static function validateUrl(string $url, bool $allow_private_ip = false) { if (strtolower(substr($url, 0, 7)) != "http://" && strtolower(substr($url, 0, 8)) != "https://") { $url = 'http://' . $url; @@ -198,7 +200,11 @@ class Validate return false; } - $pattern = '%^(?:(?:https?)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$%iuS'; + if ($allow_private_ip) { + $pattern = '%^(?:(?:https?):\/\/)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$%iuS'; + } else { + $pattern = '%^(?:(?:https?):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$%iuS'; + } if (preg_match($pattern, $url)) { return true; } diff --git a/lib/configfiles/focal.xml b/lib/configfiles/focal.xml index 4ddd2a39..fd6f4e64 100644 --- a/lib/configfiles/focal.xml +++ b/lib/configfiles/focal.xml @@ -2824,6 +2824,17 @@ service dict { #group = } } + +service stats { + unix_listener stats-reader { + group = vmail + mode = 0666 + } + unix_listener stats-writer { + group = vmail + mode = 0666 + } +} ]]> diff --git a/tests/Froxlor/ValidateTest.php b/tests/Froxlor/ValidateTest.php index be4cd1e3..f29dfb42 100644 --- a/tests/Froxlor/ValidateTest.php +++ b/tests/Froxlor/ValidateTest.php @@ -120,18 +120,28 @@ class ValidateTest extends TestCase { $result = Validate::validateUrl("https://froxlor.org/"); $this->assertTrue($result); + $result = Validate::validateUrl("https://froxlor.org/", true); + $this->assertTrue($result); $result = Validate::validateUrl("http://forum.froxlor.org/"); $this->assertTrue($result); $result = Validate::validateUrl("https://api.froxlor.org/doc/0.10.0/index.php"); $this->assertTrue($result); + $result = Validate::validateUrl("https://api.froxlor.org/doc/0.10.0/index.php", true); + $this->assertTrue($result); $result = Validate::validateUrl("#froxlor"); $this->assertFalse($result); $result = Validate::validateUrl("https://82.149.225.211/"); $this->assertTrue($result); + $result = Validate::validateUrl("https://82.149.225.211/", true); + $this->assertTrue($result); $result = Validate::validateUrl("https://82.149.225.300"); $this->assertFalse($result); $result = Validate::validateUrl("82.149.225.211:443"); $this->assertTrue($result); + $result = Validate::validateUrl("172.16.0.1:8080"); + $this->assertFalse($result); + $result = Validate::validateUrl("172.16.0.1:8080", true); + $this->assertTrue($result); } public function testValidateDomain()