A method to bypass SSL certificate name vs. host name verification via NUL
('\0') character embedded in X509 certificate's CommonName or subjectAltName
was presented at Black Hat USA 2009:
This issue was originally reported for Firefox / NSS, but it affects PHP's
Created attachment 361656 [details]
Local copy of upstream PHP-5.2.11 php_openssl_apply_verification_policy patch
This issue affects the versions of php package, as shipped with Red Hat
Enterprise Linux 3, 4, and 5.
MITRE's CVE-2009-3291 record:
The php_openssl_apply_verification_policy function in PHP before
5.2.11 does not properly perform certificate validation, which has
unknown impact and attack vectors, probably related to an ability to
I've been digging more into this yesterday to see what may really be impacted by this flaw.
First, as all CVE-2009-2408-like issues, this affects SSL clients connecting to remote SSL servers. There are 2 major requirements on attacker:
- attacker needs a specially crafted certificate with \0 in CN, signed by a CA trusted by victim; in most cases a per-target-site certificate is required, only in very few cases "universal MITM certificate" (see Moxie's presentation for details) was usable so far
- attacker must be able to redirect victim to his malicious site while user is trying to access some valid site (MITM, DNS spoofing)
Now to the PHP specifics:
Affected code is reached when using PHP streams:
In PHP5, this may affect PHP applications implementing SSL client using e.g. stream_socket_client():
But the streams are also used by functions like fopen() or file_get_contents(), so the code may be reached when accessing https:// URLs.
However, when using SSL context for PHP streams, the default is to not perform any certificate verification at all (i.e. it is not checked whether the server certificate is signed by some trusted CA and certificate host name is not checked against the connection host name). To enable SSL checking, context has to be created first with non-default options and passed to the functions:
For SSL context, following options must be set: verify_peer, cafile / capath and CN_match, where CN_match holds the name to be used when checking against certificate CN:
(Note: it's not sufficient to only set verify_peer, host name is not automatically extracted from the URLs passed to functions as fopen() and has to be specified explicitly.)
Doing a Google CodeSearch for "CN_match lang:php", CN_match is only set explicitly in very few project (~5 unique projects, one of them, HTTP_Request2 pear module, used by few more). In general, it seems this is very rarely used. Given the attack complexity (universal MITM certificate can not be used against PHP), I'd say this is impact=low issue.
Things are little different for PHP4. stream_socket_client() is not available, fopen() and file_get_contents() do not accept context as an argument. Though context is accepted as 6th argument of fsockopen():
Note: In PHP5, you can not pass context to fsockopen() any more, only 5 arguments are accepted.
As with PHP5, there's no certificate verification by default.
http://admin.fedoraproject.org/updates/F11/FEDORA-2009-11753 jumped ahead of http://admin.fedoraproject.org/updates/F11/FEDORA-2009-11852 and this got fixed in that for PHP 5.2 on F-11
This issue has been addressed in following products:
Red Hat Enterprise Linux 5
Red Hat Enterprise Linux 4
Red Hat Enterprise Linux 3
Via RHSA-2010:0040 https://rhn.redhat.com/errata/RHSA-2010-0040.html
Related issue is CVE-2013-4248 / bug 997097, which corrects handling of subjectAltNames.