diff --git a/src/Core/Content/Media/File/FileUrlValidator.php b/src/Core/Content/Media/File/FileUrlValidator.php index ef6c955c926..30ea43e6147 100644 --- a/src/Core/Content/Media/File/FileUrlValidator.php +++ b/src/Core/Content/Media/File/FileUrlValidator.php @@ -17,6 +17,11 @@ public function isValid(string $source): bool // Potentially IPv6 $ip = trim($ip, '[]'); + return $this->validateIp($ip); + } + + private function validateIp(string $ip): bool + { $ip = filter_var( $ip, \FILTER_VALIDATE_IP, @@ -27,6 +32,27 @@ public function isValid(string $source): bool return false; } + if (!filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + return true; + } + + // Convert IPv6 to packed format and back so we can check if there is a IPv4 representation of the IP + $packedIp = inet_pton($ip); + if (!$packedIp) { + return false; + } + $convertedIp = inet_ntop($packedIp); + if (!$convertedIp) { + return false; + } + $convertedIp = explode(':', $convertedIp); + $ipv4 = array_pop($convertedIp); + + // Additionally filter IPv4 representation of the IP + if (filter_var($ipv4, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { + return $this->validateIp($ipv4); + } + return true; } } diff --git a/src/Core/Content/Test/Media/File/FileUrlValidatorTest.php b/src/Core/Content/Test/Media/File/FileUrlValidatorTest.php new file mode 100644 index 00000000000..b1995f973fb --- /dev/null +++ b/src/Core/Content/Test/Media/File/FileUrlValidatorTest.php @@ -0,0 +1,37 @@ +isValid($source)); + } + + public function fileSourceProvider(): array + { + return [ + 'reserved IPv4' => ['https://127.0.0.1', false], + 'converted reserved IPv4' => ['https://0:0:0:0:0:FFFF:7F00:0001', false], + 'reserved IPv4 mapped to IPv6' => ['https://[0:0:0:0:0:FFFF:127.0.0.1]', false], + 'reserved IPv6' => ['https://FE80::', false], + 'private IPv4' => ['https://192.168.0.0', false], + 'converted private IPv4' => ['https://0:0:0:0:0:FFFF:C0A8:0000', false], + 'private IPv4 mapped to IPv6' => ['https://[0:0:0:0:0:FFFF:192.168.0.0]', false], + 'private IPv6' => ['https://FC00::', false], + 'invalid IPv4' => ['https://378.0.0.1', false], + 'valid IPv4' => ['https://8.8.8.8', true], + 'valid IPv6' => ['https://2001:db8::8a2e:370:7334', true], + 'valid IPv6 URL' => ['https://[2001:db8::8a2e:370:7334]', true], + ]; + } +}