mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Check CAA record in DNSTest
This commit is contained in:
@@ -121,4 +121,6 @@ _APP_MESSAGE_PUSH_TEST_DSN=
|
||||
_APP_WEBHOOK_MAX_FAILED_ATTEMPTS=10
|
||||
_APP_PROJECT_REGIONS=default
|
||||
_APP_FUNCTIONS_CREATION_ABUSE_LIMIT=5000
|
||||
_APP_STATS_USAGE_DUAL_WRITING_DBS=database_db_main
|
||||
_APP_STATS_USAGE_DUAL_WRITING_DBS=database_db_main
|
||||
_APP_DOMAINS_DNS=8.8.8.8
|
||||
_APP_DOMAIN_TARGET_CAA='0 issue "digicert.com"'
|
||||
@@ -151,6 +151,24 @@ return [
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET_CAA',
|
||||
'description' => 'A CAA record value that can be used to validate custom domains. Format: "0 issue \"certainly.com\""',
|
||||
'introduction' => '',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAINS_DNS',
|
||||
'description' => 'DNS server to use for domain validation. Default: 8.8.8.8',
|
||||
'introduction' => '',
|
||||
'default' => '8.8.8.8',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_CONSOLE_WHITELIST_ROOT',
|
||||
'description' => 'This option allows you to disable the creation of new users on the Appwrite console. When enabled only 1 user will be able to use the registration form. New users can be added by inviting them to your project. By default this option is enabled.',
|
||||
|
||||
@@ -71,6 +71,8 @@ App::get('/v1/console/variables')
|
||||
'_APP_DOMAIN_TARGET_CNAME' => System::getEnv('_APP_DOMAIN_TARGET_CNAME'),
|
||||
'_APP_DOMAIN_TARGET_AAAA' => System::getEnv('_APP_DOMAIN_TARGET_AAAA'),
|
||||
'_APP_DOMAIN_TARGET_A' => System::getEnv('_APP_DOMAIN_TARGET_A'),
|
||||
'_APP_DOMAIN_TARGET_CAA' => System::getEnv('_APP_DOMAIN_TARGET_CAA'),
|
||||
'_APP_DOMAINS_DNS' => System::getEnv('_APP_DOMAINS_DNS'),
|
||||
'_APP_STORAGE_LIMIT' => +System::getEnv('_APP_STORAGE_LIMIT'),
|
||||
'_APP_COMPUTE_SIZE_LIMIT' => +System::getEnv('_APP_COMPUTE_SIZE_LIMIT'),
|
||||
'_APP_USAGE_STATS' => System::getEnv('_APP_USAGE_STATS'),
|
||||
|
||||
@@ -257,6 +257,12 @@ App::patch('/v1/proxy/rules/:ruleId/verification')
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
// Add CAA validation if configured
|
||||
$caaTarget = System::getEnv('_APP_DOMAIN_TARGET_CAA', '');
|
||||
if (!empty($caaTarget)) {
|
||||
$validators[] = new DNS($caaTarget, DNS::RECORD_CAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
"utopia-php/database": "0.71.*",
|
||||
"utopia-php/detector": "0.1.*",
|
||||
"utopia-php/domains": "0.8.*",
|
||||
"utopia-php/dns": "dev-feat-add-CAA-to-client as 0.2.99",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/fetch": "0.4.*",
|
||||
|
||||
Generated
+86
-21
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "edbe5912c45e1f467f398541a75a77de",
|
||||
"content-hash": "d36ad770ee5e4ea6e3bb0206c2c584ff",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -69,16 +69,16 @@
|
||||
},
|
||||
{
|
||||
"name": "appwrite/appwrite",
|
||||
"version": "15.0.0",
|
||||
"version": "15.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-for-php.git",
|
||||
"reference": "deb97b62e0abed8a4fd5c5d48e77365cf89867cf"
|
||||
"reference": "c438b3885071ac7c0329199dce5e6f6a24dd215b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/deb97b62e0abed8a4fd5c5d48e77365cf89867cf",
|
||||
"reference": "deb97b62e0abed8a4fd5c5d48e77365cf89867cf",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/c438b3885071ac7c0329199dce5e6f6a24dd215b",
|
||||
"reference": "c438b3885071ac7c0329199dce5e6f6a24dd215b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -104,10 +104,10 @@
|
||||
"support": {
|
||||
"email": "team@appwrite.io",
|
||||
"issues": "https://github.com/appwrite/sdk-for-php/issues",
|
||||
"source": "https://github.com/appwrite/sdk-for-php/tree/15.0.0",
|
||||
"source": "https://github.com/appwrite/sdk-for-php/tree/15.1.0",
|
||||
"url": "https://appwrite.io/support"
|
||||
},
|
||||
"time": "2025-05-18T09:47:10+00:00"
|
||||
"time": "2025-08-01T04:50:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "appwrite/php-clamav",
|
||||
@@ -3596,6 +3596,62 @@
|
||||
},
|
||||
"time": "2025-05-19T11:01:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/dns",
|
||||
"version": "dev-feat-add-CAA-to-client",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/dns.git",
|
||||
"reference": "a7d45e4c5dfc7020c0467de9587ccd7e15488206"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/dns/zipball/a7d45e4c5dfc7020c0467de9587ccd7e15488206",
|
||||
"reference": "a7d45e4c5dfc7020c0467de9587ccd7e15488206",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/telemetry": "^0.1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpstan/phpstan": "1.8.*",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"rregeer/phpunit-coverage-check": "^0.3.1",
|
||||
"swoole/ide-helper": "4.6.6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\DNS\\": "src/DNS"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Eldad Fux",
|
||||
"email": "eldad@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "Lite & fast micro PHP DNS server abstraction that is **easy to use**.",
|
||||
"keywords": [
|
||||
"dns",
|
||||
"framework",
|
||||
"php",
|
||||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/dns/issues",
|
||||
"source": "https://github.com/utopia-php/dns/tree/feat-add-CAA-to-client"
|
||||
},
|
||||
"time": "2025-08-03T18:46:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
"version": "0.8.0",
|
||||
@@ -4814,16 +4870,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.41.27",
|
||||
"version": "0.41.28",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "083fd2e8163d6a4e59ee971ac6cb97277d831dd5"
|
||||
"reference": "8eace11070264c62c8da3c69498fb8dc98fcfaf7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/083fd2e8163d6a4e59ee971ac6cb97277d831dd5",
|
||||
"reference": "083fd2e8163d6a4e59ee971ac6cb97277d831dd5",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/8eace11070264c62c8da3c69498fb8dc98fcfaf7",
|
||||
"reference": "8eace11070264c62c8da3c69498fb8dc98fcfaf7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4859,9 +4915,9 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.41.27"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.41.28"
|
||||
},
|
||||
"time": "2025-07-31T10:20:46+00:00"
|
||||
"time": "2025-08-01T11:06:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@@ -5280,16 +5336,16 @@
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.13.3",
|
||||
"version": "1.13.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36"
|
||||
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/faed855a7b5f4d4637717c2b3863e277116beb36",
|
||||
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
|
||||
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5328,7 +5384,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.3"
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5336,7 +5392,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-05T12:25:42+00:00"
|
||||
"time": "2025-08-01T08:46:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
@@ -8261,9 +8317,18 @@
|
||||
"time": "2024-03-07T20:33:40+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
"aliases": [
|
||||
{
|
||||
"package": "utopia-php/dns",
|
||||
"version": "dev-feat-add-CAA-to-client",
|
||||
"alias": "0.2.99",
|
||||
"alias_normalized": "0.2.99.0"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {},
|
||||
"stability-flags": {
|
||||
"utopia-php/dns": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
||||
@@ -120,6 +120,8 @@ services:
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DOMAINS_DNS
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
@@ -535,6 +537,8 @@ services:
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DOMAINS_DNS
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
- _APP_REDIS_HOST
|
||||
@@ -704,6 +708,8 @@ services:
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DOMAINS_DNS
|
||||
- _APP_EMAIL_SECURITY
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
@@ -738,6 +744,8 @@ services:
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DOMAINS_DNS
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_REDIS_HOST
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Appwrite\Network\Validator;
|
||||
|
||||
use Utopia\DNS\Client;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator;
|
||||
|
||||
class DNS extends Validator
|
||||
@@ -9,6 +11,7 @@ class DNS extends Validator
|
||||
public const RECORD_A = 'a';
|
||||
public const RECORD_AAAA = 'aaaa';
|
||||
public const RECORD_CNAME = 'cname';
|
||||
public const RECORD_CAA = 'caa';
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
@@ -42,42 +45,31 @@ class DNS extends Validator
|
||||
* Check if DNS record value matches specific value
|
||||
*
|
||||
* @param mixed $domain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($value): bool
|
||||
{
|
||||
$typeNative = match ($this->type) {
|
||||
self::RECORD_A => DNS_A,
|
||||
self::RECORD_AAAA => DNS_AAAA,
|
||||
self::RECORD_CNAME => DNS_CNAME,
|
||||
default => throw new \Exception('Record type not supported.')
|
||||
};
|
||||
|
||||
$dnsKey = match ($this->type) {
|
||||
self::RECORD_A => 'ip',
|
||||
self::RECORD_AAAA => 'ipv6',
|
||||
self::RECORD_CNAME => 'target',
|
||||
default => throw new \Exception('Record type not supported.')
|
||||
};
|
||||
|
||||
if (!is_string($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dnsServer = System::getEnv('_APP_DOMAINS_DNS', '');
|
||||
$dns = new Client($dnsServer);
|
||||
|
||||
try {
|
||||
$records = \dns_get_record($value, $typeNative);
|
||||
$this->logs = $records;
|
||||
} catch (\Throwable $th) {
|
||||
$query = $dns->query($value, strtoupper($this->type));
|
||||
$this->logs = $query;
|
||||
} catch (\Exception $e) {
|
||||
$this->logs = ['error' => $e->getMessage()];
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$records) {
|
||||
if (empty($query)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($records as $record) {
|
||||
if (isset($record[$dnsKey]) && $record[$dnsKey] === $this->target) {
|
||||
foreach ($query as $record) {
|
||||
if ($record->getRdata() === $this->target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +314,12 @@ class Certificates extends Action
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
// Add CAA validation if configured
|
||||
$caaTarget = System::getEnv('_APP_DOMAIN_TARGET_CAA', '');
|
||||
if (!empty($caaTarget)) {
|
||||
$validators[] = new DNS($caaTarget, DNS::RECORD_CAA);
|
||||
}
|
||||
|
||||
// Validate if domain target is properly configured
|
||||
if (empty($validators)) {
|
||||
throw new Exception('At least one of domain targets environment variable must be configured.');
|
||||
|
||||
@@ -27,6 +27,18 @@ class ConsoleVariables extends Model
|
||||
'description' => 'AAAA target for your Appwrite custom domains.',
|
||||
'default' => '',
|
||||
'example' => '::1',
|
||||
])
|
||||
->addRule('_APP_DOMAIN_TARGET_CAA', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'CAA target for your Appwrite custom domains.',
|
||||
'default' => '',
|
||||
'example' => '0 issue "certainly.com"',
|
||||
])
|
||||
->addRule('_APP_DOMAINS_DNS', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'DNS server to use for domain validation.',
|
||||
'default' => '8.8.8.8',
|
||||
'example' => '8.8.8.8',
|
||||
])
|
||||
->addRule('_APP_STORAGE_LIMIT', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
|
||||
@@ -47,4 +47,27 @@ class DNSTest extends TestCase
|
||||
$this->assertEquals($validator->isValid('aaaa-unit-test.appwrite.org'), true);
|
||||
$this->assertEquals($validator->isValid('test1.appwrite.org'), false);
|
||||
}
|
||||
|
||||
public function testCAA(): void
|
||||
{
|
||||
$validator = new DNS('0 issue "pki.goog"', DNS::RECORD_CAA);
|
||||
|
||||
$this->assertEquals($validator->isValid(''), false);
|
||||
$this->assertEquals($validator->isValid(null), false);
|
||||
$this->assertEquals($validator->isValid(false), false);
|
||||
|
||||
$result = $validator->isValid('google.com');
|
||||
if ($result === false) {
|
||||
$logs = $validator->getLogs();
|
||||
if (isset($logs['error']) && strpos($logs['error'], 'Failed to receive data') !== false) {
|
||||
$this->markTestSkipped('DNS resolution not available in test environment: ' . $logs['error']);
|
||||
}
|
||||
}
|
||||
$this->assertEquals($result, true);
|
||||
|
||||
$this->assertEquals($validator->isValid('test1.appwrite.org'), false);
|
||||
|
||||
$validator2 = new DNS('0 issue "letsencrypt.org"', DNS::RECORD_CAA);
|
||||
$this->assertEquals($validator2->isValid('test2.appwrite.org'), false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user