1

I was using PHPMailer to send an email with SMTP. This time I used PHP 5.6. I received the following error.

Warning: stream_socket_enable_crypto(): 
Peer certificate CN=`*.example1.com' did not match expected CN=`mail.example2.com'
in /usr/share/php/libphp-phpmailer/class.smtp.php on line 344

Researching this led me to this question, that mentions the PHPMailer docs which say this:

In a change from earlier versions, PHP 5.6 verifies certificates on SSL connections. If the SSL config of the server you are connecting to is not correct, you will get an error like this:

It has this work around suggested:

$mail->SMTPOptions = array(
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true
    )
);

But it goes on to say

...this is not recommended: You can also change these settings globally in your php.ini, but that's a really bad idea; PHP 5.6 made this change for very good reasons.

What are those very good reasons?

  • 2
    If you do that it'll happily accept a certificate for evil.hacker.com when it's expecting one for example.com. – AndrolGenhald Oct 20 '17 at 15:46
  • If you do that you might as well not use a secure channel. It means any certificate would be valid, defeating the point – ISMSDEV Oct 20 '17 at 16:00
  • 1
    @h4ckNinja: "PHP5.6 is no longer maintained" - this is not fully true. According to Supported Versions PHP 5.6 is no longer actively supported (ended 2017/01/19) but security updates are still provided until 2018/12/31. – Steffen Ullrich Oct 21 '17 at 6:27
4

With PHP 5.6 the default for using TLS was finally changed to verify certificates by default and verify them properly (i.e. not only certificate chain but also hostname). About the same time similar changes where done in Python (version 2.7.9).

These changes were done because not properly checking a certificate makes the connection vulnerable to man in the middle attacks. But, relying on developers to add the functionality to properly check certificates does not work because it seems to work without too so why add additional work to make it more secure. This means that having the secure behavior enabled by default is the only acceptable option. Additionally, both Python and PHP did not even have a way to properly check certificates before, i.e. all they could in an easy way is to to check certificate chain but not the hostname.

It is probably no coincidence that these changes were made while many sites switched to HTTPS in aftermath of the Snowden affair and because the revelations of this affair showed that sniffing and hijacking of improperly protected connections was not only a theoretical thing but that government agencies actually made use of it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.