Closed
Description
Description
Peer verification [ext/openssl/xp_ssl.c -> php_openssl_matches_san_list()] via an IP address in the SAN list is incomplete
- IPv4 Addresses are validated on all IP ranges including including reserve IP addresses which is deprecated
- IPv6 Addresses validation is not implemented at all with the follow comment
No, we aren't bothering to check IPv6 addresses. Why?
Because IP SAN names are officially deprecated and are
not allowed by CAs starting in 2015. Deal with it.
IPv6 addresses not in reserved IP range can be included in SAN lists per https://www.digicert.com/kb/advisories/internal-names.htm and is used by Google and CloudFlare for their DNS over HTTPS services
Connecting to a HTTPS server via IPv6 is useful for DNS over HTTPS clients, not verifying peer removes the security gained.
The following code:
<?php
$dns = '2001:4860:4860::8888'; //dns.google IPv6
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'verify_host', true);
stream_context_set_option($context, 'ssl', 'verify_peer_name', true);
stream_context_set_option($context, 'ssl', 'SNI_server_name', $dns);
stream_context_set_option($context, 'ssl', 'peer_name', $dns);
$socket = stream_socket_client("tls://[$dns]:443", $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $context);
if($socket == FALSE)
{
echo "error: $errstr ($errno)\n";
exit(1);
}
echo 'connected';
Resulted in this output:
Warning: stream_socket_client(): Peer certificate CN=`dns.google' did not match expected CN=`2001:4860:4860:0000:0000:0000:0000:8888'
PHP Warning: stream_socket_client(): Failed to enable crypto
But I expected this output instead:
connected
PHP Version
PHP 8.1.9
Operating System
No response