diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 4a0cc51764..67600ee752 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -21,6 +21,7 @@ use Appwrite\Event\Usage; use Appwrite\Extend\Exception; use Appwrite\Hooks\Hooks; use Appwrite\Network\Validator\Email; +use Appwrite\Network\Validator\Redirect; use Appwrite\OpenSSL\OpenSSL; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; diff --git a/src/Appwrite/Network/Validator/Redirect.php b/src/Appwrite/Network/Validator/Redirect.php index 23a66fdfad..a84dea1ee9 100644 --- a/src/Appwrite/Network/Validator/Redirect.php +++ b/src/Appwrite/Network/Validator/Redirect.php @@ -37,30 +37,34 @@ class Redirect extends Host /** * Is valid * - * Validation will pass if scheme is not http or https or host is in whitelist + * Validation will pass when $value is a valid URL and the host is allowed * * @param mixed $value * @return bool */ public function isValid($value): bool { - // `parse_url` returns false for URL with only a scheme. - // We need to check for this case separately. + // `parse_url` returns false for URL with only a scheme + // We need to check for this case separately if (preg_match('/^([a-z][a-z0-9+\.-]*):\/+$/i', $value, $matches)) { $scheme = strtolower($matches[1]); return $scheme !== 'javascript'; } + // `parse_url` returns false for invalid URLs $url = \parse_url($value); if ($url === false || !isset($url["scheme"])) { return false; } + // If scheme is javascript, it's an XSS vector $scheme = strtolower($url["scheme"]); if ($scheme === "javascript") { return false; } + // If scheme is not http or https, we don't need to check the host + // Allow deep links to other user apps. if (!\in_array($scheme, ["http", "https"])) { return true; }