mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 00:49:02 +00:00
Merge pull request #10374 from appwrite/fix-domain-validator
Fix: Domain validator
This commit is contained in:
commit
c34f9cb0e1
8 changed files with 149 additions and 35 deletions
14
composer.lock
generated
14
composer.lock
generated
|
|
@ -3856,16 +3856,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.33.21",
|
||||
"version": "0.33.22",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/http.git",
|
||||
"reference": "eb0e82e90b8fa493f99b8d131bdd25173422c493"
|
||||
"reference": "c01a815cb976c9255e045fc3bcc3f5fcf477e0bc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/eb0e82e90b8fa493f99b8d131bdd25173422c493",
|
||||
"reference": "eb0e82e90b8fa493f99b8d131bdd25173422c493",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/c01a815cb976c9255e045fc3bcc3f5fcf477e0bc",
|
||||
"reference": "c01a815cb976c9255e045fc3bcc3f5fcf477e0bc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3897,9 +3897,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/http/issues",
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.21"
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.22"
|
||||
},
|
||||
"time": "2025-08-19T10:52:15+00:00"
|
||||
"time": "2025-08-26T10:29:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
|
|
@ -8446,5 +8446,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@ use Appwrite\Utopia\Response;
|
|||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Domains\Domain as Domain;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Domain;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\Domain as DomainValidator;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
|
|
@ -67,10 +69,57 @@ class Get extends Action
|
|||
Database $dbForPlatform
|
||||
) {
|
||||
if ($type === 'rules') {
|
||||
$validator = new Domain($value);
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
|
||||
$restrictions = [];
|
||||
if (!empty($sitesDomain)) {
|
||||
$domainLevel = \count(\explode('.', $sitesDomain));
|
||||
$restrictions[] = DomainValidator::createRestriction($sitesDomain, $domainLevel + 1, ['commit-', 'branch-']);
|
||||
}
|
||||
if (!empty($functionsDomain)) {
|
||||
$domainLevel = \count(\explode('.', $functionsDomain));
|
||||
$restrictions[] = DomainValidator::createRestriction($functionsDomain, $domainLevel + 1);
|
||||
}
|
||||
$validator = new DomainValidator($restrictions);
|
||||
|
||||
if (!$validator->isValid($value)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $validator->getDescription());
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
$deniedDomains = [
|
||||
'localhost',
|
||||
APP_HOSTNAME_INTERNAL
|
||||
];
|
||||
|
||||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
$deniedDomains[] = $mainDomain;
|
||||
|
||||
if (!empty($sitesDomain)) {
|
||||
$deniedDomains[] = $sitesDomain;
|
||||
}
|
||||
|
||||
if (!empty($functionsDomain)) {
|
||||
$deniedDomains[] = $functionsDomain;
|
||||
}
|
||||
|
||||
$denyListDomains = System::getEnv('_APP_CUSTOM_DOMAIN_DENY_LIST', '');
|
||||
$denyListDomains = \array_map('trim', explode(',', $denyListDomains));
|
||||
foreach ($denyListDomains as $denyListDomain) {
|
||||
if (empty($denyListDomain)) {
|
||||
continue;
|
||||
}
|
||||
$deniedDomains[] = $denyListDomain;
|
||||
}
|
||||
|
||||
if (\in_array($value, $deniedDomains)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
try {
|
||||
$domain = new Domain($value);
|
||||
} catch (\Throwable) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
$document = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
|
||||
|
|
|
|||
|
|
@ -71,6 +71,24 @@ class Create extends Action
|
|||
|
||||
public function action(string $domain, Response $response, Document $project, Certificate $queueForCertificates, Event $queueForEvents, Database $dbForPlatform)
|
||||
{
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
|
||||
$restrictions = [];
|
||||
if (!empty($sitesDomain)) {
|
||||
$domainLevel = \count(\explode('.', $sitesDomain));
|
||||
$restrictions[] = ValidatorDomain::createRestriction($sitesDomain, $domainLevel + 1, ['commit-', 'branch-']);
|
||||
}
|
||||
if (!empty($functionsDomain)) {
|
||||
$domainLevel = \count(\explode('.', $functionsDomain));
|
||||
$restrictions[] = ValidatorDomain::createRestriction($functionsDomain, $domainLevel + 1);
|
||||
}
|
||||
$validator = new ValidatorDomain($restrictions);
|
||||
|
||||
if (!$validator->isValid($domain)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
$deniedDomains = [
|
||||
'localhost',
|
||||
APP_HOSTNAME_INTERNAL
|
||||
|
|
@ -79,12 +97,10 @@ class Create extends Action
|
|||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
$deniedDomains[] = $mainDomain;
|
||||
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
if (!empty($sitesDomain)) {
|
||||
$deniedDomains[] = $sitesDomain;
|
||||
}
|
||||
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
if (!empty($functionsDomain)) {
|
||||
$deniedDomains[] = $functionsDomain;
|
||||
}
|
||||
|
|
@ -102,10 +118,6 @@ class Create extends Action
|
|||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
if (\str_starts_with($domain, 'commit-') || \str_starts_with($domain, 'branch-')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
try {
|
||||
$domain = new Domain($domain);
|
||||
} catch (\Throwable) {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,24 @@ class Create extends Action
|
|||
|
||||
public function action(string $domain, string $functionId, string $branch, Response $response, Document $project, Certificate $queueForCertificates, Event $queueForEvents, Database $dbForPlatform, Database $dbForProject)
|
||||
{
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
|
||||
$restrictions = [];
|
||||
if (!empty($sitesDomain)) {
|
||||
$domainLevel = \count(\explode('.', $sitesDomain));
|
||||
$restrictions[] = ValidatorDomain::createRestriction($sitesDomain, $domainLevel + 1, ['commit-', 'branch-']);
|
||||
}
|
||||
if (!empty($functionsDomain)) {
|
||||
$domainLevel = \count(\explode('.', $functionsDomain));
|
||||
$restrictions[] = ValidatorDomain::createRestriction($functionsDomain, $domainLevel + 1);
|
||||
}
|
||||
$validator = new ValidatorDomain($restrictions);
|
||||
|
||||
if (!$validator->isValid($domain)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
$deniedDomains = [
|
||||
'localhost',
|
||||
APP_HOSTNAME_INTERNAL
|
||||
|
|
@ -84,12 +102,10 @@ class Create extends Action
|
|||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
$deniedDomains[] = $mainDomain;
|
||||
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
if (!empty($sitesDomain)) {
|
||||
$deniedDomains[] = $sitesDomain;
|
||||
}
|
||||
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
if (!empty($functionsDomain)) {
|
||||
$deniedDomains[] = $functionsDomain;
|
||||
}
|
||||
|
|
@ -107,10 +123,6 @@ class Create extends Action
|
|||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
if (\str_starts_with($domain, 'commit-') || \str_starts_with($domain, 'branch-')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
try {
|
||||
$domain = new Domain($domain);
|
||||
} catch (\Throwable) {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,24 @@ class Create extends Action
|
|||
|
||||
public function action(string $domain, string $url, int $statusCode, string $resourceId, string $resourceType, Response $response, Document $project, Certificate $queueForCertificates, Event $queueForEvents, Database $dbForPlatform, Database $dbForProject)
|
||||
{
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
|
||||
$restrictions = [];
|
||||
if (!empty($sitesDomain)) {
|
||||
$domainLevel = \count(\explode('.', $sitesDomain));
|
||||
$restrictions[] = ValidatorDomain::createRestriction($sitesDomain, $domainLevel + 1, ['commit-', 'branch-']);
|
||||
}
|
||||
if (!empty($functionsDomain)) {
|
||||
$domainLevel = \count(\explode('.', $functionsDomain));
|
||||
$restrictions[] = ValidatorDomain::createRestriction($functionsDomain, $domainLevel + 1);
|
||||
}
|
||||
$validator = new ValidatorDomain($restrictions);
|
||||
|
||||
if (!$validator->isValid($domain)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
$deniedDomains = [
|
||||
'localhost',
|
||||
APP_HOSTNAME_INTERNAL
|
||||
|
|
@ -87,12 +105,10 @@ class Create extends Action
|
|||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
$deniedDomains[] = $mainDomain;
|
||||
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
if (!empty($sitesDomain)) {
|
||||
$deniedDomains[] = $sitesDomain;
|
||||
}
|
||||
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
if (!empty($functionsDomain)) {
|
||||
$deniedDomains[] = $functionsDomain;
|
||||
}
|
||||
|
|
@ -110,10 +126,6 @@ class Create extends Action
|
|||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
if (\str_starts_with($domain, 'commit-') || \str_starts_with($domain, 'branch-')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
try {
|
||||
$domain = new Domain($domain);
|
||||
} catch (\Throwable) {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,24 @@ class Create extends Action
|
|||
|
||||
public function action(string $domain, string $siteId, string $branch, Response $response, Document $project, Certificate $queueForCertificates, Event $queueForEvents, Database $dbForPlatform, Database $dbForProject)
|
||||
{
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
|
||||
$restrictions = [];
|
||||
if (!empty($sitesDomain)) {
|
||||
$domainLevel = \count(\explode('.', $sitesDomain));
|
||||
$restrictions[] = ValidatorDomain::createRestriction($sitesDomain, $domainLevel + 1, ['commit-', 'branch-']);
|
||||
}
|
||||
if (!empty($functionsDomain)) {
|
||||
$domainLevel = \count(\explode('.', $functionsDomain));
|
||||
$restrictions[] = ValidatorDomain::createRestriction($functionsDomain, $domainLevel + 1);
|
||||
}
|
||||
$validator = new ValidatorDomain($restrictions);
|
||||
|
||||
if (!$validator->isValid($domain)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
$deniedDomains = [
|
||||
'localhost',
|
||||
APP_HOSTNAME_INTERNAL
|
||||
|
|
@ -84,12 +102,10 @@ class Create extends Action
|
|||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
$deniedDomains[] = $mainDomain;
|
||||
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
if (!empty($sitesDomain)) {
|
||||
$deniedDomains[] = $sitesDomain;
|
||||
}
|
||||
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
if (!empty($functionsDomain)) {
|
||||
$deniedDomains[] = $functionsDomain;
|
||||
}
|
||||
|
|
@ -107,10 +123,6 @@ class Create extends Action
|
|||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
if (\str_starts_with($domain, 'commit-') || \str_starts_with($domain, 'branch-')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
try {
|
||||
$domain = new Domain($domain);
|
||||
} catch (\Throwable) {
|
||||
|
|
|
|||
|
|
@ -1040,7 +1040,7 @@ class UsageTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()),
|
||||
[
|
||||
'domain' => 'test-' . ID::unique() . System::getEnv('_APP_DOMAIN_FUNCTIONS'),
|
||||
'domain' => 'test-' . ID::unique() . '.' . System::getEnv('_APP_DOMAIN_FUNCTIONS'),
|
||||
'functionId' => $functionId,
|
||||
],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -70,12 +70,29 @@ class ProxyCustomServerTest extends Scope
|
|||
$this->assertNotEmpty($siteId);
|
||||
$this->assertNotEmpty($deploymentId);
|
||||
|
||||
$rule = $this->createSiteRule('commit-' . $domain, $siteId);
|
||||
$this->assertEquals(201, $rule['headers']['status-code']);
|
||||
$this->cleanupRule($rule['body']['$id']);
|
||||
|
||||
$rule = $this->createSiteRule('branch-' . $domain, $siteId);
|
||||
$this->assertEquals(201, $rule['headers']['status-code']);
|
||||
$this->cleanupRule($rule['body']['$id']);
|
||||
|
||||
$rule = $this->createSiteRule('anything-' . $domain, $siteId);
|
||||
$this->assertEquals(201, $rule['headers']['status-code']);
|
||||
$this->cleanupRule($rule['body']['$id']);
|
||||
|
||||
$domain = \uniqid() . '-vcs.' . System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
|
||||
$rule = $this->createSiteRule('commit-' . $domain, $siteId);
|
||||
$this->assertEquals(400, $rule['headers']['status-code']);
|
||||
|
||||
$rule = $this->createSiteRule('branch-' . $domain, $siteId);
|
||||
$this->assertEquals(400, $rule['headers']['status-code']);
|
||||
|
||||
$rule = $this->createSiteRule('subdomain.anything-' . $domain, $siteId);
|
||||
$this->assertEquals(400, $rule['headers']['status-code']);
|
||||
|
||||
$rule = $this->createSiteRule('anything-' . $domain, $siteId);
|
||||
$this->assertEquals(201, $rule['headers']['status-code']);
|
||||
$this->cleanupRule($rule['body']['$id']);
|
||||
|
|
|
|||
Loading…
Reference in a new issue