diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index b089054b74..a9267da138 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -23,7 +23,7 @@ use Utopia\Registry\Registry; use Appwrite\Extend\Exception; use Utopia\Validator\ArrayList; use Utopia\Validator\Boolean; -use Utopia\Validator\Integer; +use Utopia\Validator\Hostname; use Utopia\Validator\Range; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; @@ -972,6 +972,14 @@ App::post('/v1/projects/:projectId/platforms') ->inject('dbForConsole') ->action(function (string $projectId, string $type, string $name, string $key, string $store, string $hostname, Response $response, Database $dbForConsole) { + // Ensure hostname has proper structure (no port, protocol..) + if(!empty($hostname)) { + $validator = new Hostname(); + if (!is_null($hostname) && !$validator->isValid($hostname)) { + throw new Exception($validator->getDescription(), 400, Exception::ATTRIBUTE_VALUE_INVALID); + } + } + $project = $dbForConsole->getDocument('projects', $projectId); if ($project->isEmpty()) { @@ -1085,6 +1093,14 @@ App::put('/v1/projects/:projectId/platforms/:platformId') ->inject('dbForConsole') ->action(function (string $projectId, string $platformId, string $name, string $key, string $store, string $hostname, Response $response, Database $dbForConsole) { + // Ensure hostname has proper structure (no port, protocol..) + if(!empty($hostname)) { + $validator = new Hostname(); + if (!is_null($hostname) && !$validator->isValid($hostname)) { + throw new Exception($validator->getDescription(), 400, Exception::ATTRIBUTE_VALUE_INVALID); + } + } + $project = $dbForConsole->getDocument('projects', $projectId); if ($project->isEmpty()) { diff --git a/app/controllers/general.php b/app/controllers/general.php index 9bc1d789ee..c58e2bd64a 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -20,6 +20,7 @@ use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Validator\Hostname; use Appwrite\Utopia\Request\Filters\V12 as RequestV12; use Appwrite\Utopia\Request\Filters\V13 as RequestV13; use Utopia\Validator\Text; @@ -132,8 +133,13 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons $protocol = \parse_url($request->getOrigin($referrer), PHP_URL_SCHEME); $port = \parse_url($request->getOrigin($referrer), PHP_URL_PORT); - $refDomain = (!empty($protocol) ? $protocol : $request->getProtocol()).'://'.((\in_array($origin, $clients)) - ? $origin : 'localhost').(!empty($port) ? ':'.$port : ''); + $refDomainOrigin = 'localhost'; + $validator = new Hostname($clients); + if ($validator->isValid($origin)) { + $refDomainOrigin = $origin; + } + + $refDomain = (!empty($protocol) ? $protocol : $request->getProtocol()) . '://' . $refDomainOrigin . (!empty($port) ? ':' . $port : ''); $refDomain = (!$route->getLabel('origin', false)) // This route is publicly accessible ? $refDomain diff --git a/app/views/console/home/index.phtml b/app/views/console/home/index.phtml index 028e7f3b79..82be016b61 100644 --- a/app/views/console/home/index.phtml +++ b/app/views/console/home/index.phtml @@ -299,8 +299,9 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); - - + + +
You can use * to allow wildcard hostnames or subdomains.
Next Steps
@@ -329,7 +330,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); data-success="alert,trigger" data-success-param-alert-text="Updated platform successfully" data-success-param-trigger-events="projects.updatePlatform" - data-failure="alert" + data-failure="alert,trigger" + data-failure-param-trigger-events="projects.updatePlatform" data-failure-param-alert-text="Failed to update platform" data-failure-param-alert-classname="error"> @@ -340,7 +342,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); - + +
You can use * to allow wildcard hostnames or subdomains.

@@ -714,7 +717,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); data-success="alert,trigger" data-success-param-alert-text="Updated platform successfully" data-success-param-trigger-events="projects.updatePlatform" - data-failure="alert" + data-failure="alert,trigger" + data-failure-param-trigger-events="projects.updatePlatform" data-failure-param-alert-text="Failed to update platform" data-failure-param-alert-classname="error"> @@ -746,7 +750,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); data-success="alert,trigger" data-success-param-alert-text="Updated platform successfully" data-success-param-trigger-events="projects.updatePlatform" - data-failure="alert" + data-failure="alert,trigger" + data-failure-param-trigger-events="projects.updatePlatform" data-failure-param-alert-text="Failed to update platform" data-failure-param-alert-classname="error"> @@ -777,7 +782,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); data-success="alert,trigger" data-success-param-alert-text="Updated platform successfully" data-success-param-trigger-events="projects.updatePlatform" - data-failure="alert" + data-failure="alert,trigger" + data-failure-param-trigger-events="projects.updatePlatform" data-failure-param-alert-text="Failed to update platform" data-failure-param-alert-classname="error"> @@ -808,7 +814,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); data-success="alert,trigger" data-success-param-alert-text="Updated platform successfully" data-success-param-trigger-events="projects.updatePlatform" - data-failure="alert" + data-failure="alert,trigger" + data-failure-param-trigger-events="projects.updatePlatform" data-failure-param-alert-text="Failed to update platform" data-failure-param-alert-classname="error"> @@ -841,7 +848,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); data-success="alert,trigger" data-success-param-alert-text="Updated platform successfully" data-success-param-trigger-events="projects.updatePlatform" - data-failure="alert" + data-failure="alert,trigger" + data-failure-param-trigger-events="projects.updatePlatform" data-failure-param-alert-text="Failed to update platform" data-failure-param-alert-classname="error"> @@ -873,7 +881,8 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true); data-success="alert,trigger" data-success-param-alert-text="Updated platform successfully" data-success-param-trigger-events="projects.updatePlatform" - data-failure="alert" + data-failure="alert,trigger" + data-failure-param-trigger-events="projects.updatePlatform" data-failure-param-alert-text="Failed to update platform" data-failure-param-alert-classname="error"> diff --git a/src/Appwrite/Network/Validator/Host.php b/src/Appwrite/Network/Validator/Host.php index 703907c3d3..c81a931f37 100644 --- a/src/Appwrite/Network/Validator/Host.php +++ b/src/Appwrite/Network/Validator/Host.php @@ -2,6 +2,7 @@ namespace Appwrite\Network\Validator; +use Utopia\Validator\Hostname; use Utopia\Validator; /** @@ -45,17 +46,16 @@ class Host extends Validator */ public function isValid($value): bool { + // Check if value is valid URL $urlValidator = new URL(); if (!$urlValidator->isValid($value)) { return false; } - if (\in_array(\parse_url($value, PHP_URL_HOST), $this->whitelist)) { - return true; - } - - return false; + $hostname = \parse_url($value, PHP_URL_HOST); + $hostnameValidator = new Hostname($this->whitelist); + return $hostnameValidator->isValid($hostname); } /** diff --git a/src/Appwrite/Network/Validator/Origin.php b/src/Appwrite/Network/Validator/Origin.php index 8831707cef..30efe50c4c 100644 --- a/src/Appwrite/Network/Validator/Origin.php +++ b/src/Appwrite/Network/Validator/Origin.php @@ -2,6 +2,7 @@ namespace Appwrite\Network\Validator; +use Utopia\Validator\Hostname; use Utopia\Validator; class Origin extends Validator @@ -122,11 +123,9 @@ class Origin extends Validator return true; } - if (\in_array($host, $this->clients)) { - return true; - } - - return false; + $validator = new Hostname($this->clients); + + return $validator->isValid($host); } /**