Allowing insecure connections in PHP Mailer - php

I encountered the same problem mentioned here, and allowing insecure connections solved it, while nothing else did. Can you please inform me about what security issues I might face if i kept allowing these insecure connections?

I suggest this link:
PhpMailer not sending mails - TLS error?
if you have insecure connection troubles, let add this lines:
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
It prevent certifies checking and so on.

TLS fulfils two roles: authenticating who you're connecting to, and protecting data in transit. Disabling verification drops the former, but data is still encrypted in transit in exactly the same way as with a verified cert, so it is still substantially better than having no encryption.
The most obvious problem with disabling verification is that you lose the ability to detect interception of your connection. It's very common for ISPs to have a firewall config that redirects outbound SMTP connections to their own mail servers without telling you. If you don't verify the certificate, your script will not notice that it's connected to the wrong server, and will continue and submit your credentials (which will probably fail, since it's the wrong server) - but you've just submitted your ID and password to a man-in-the-middle, and you can't tell if it's your ISP or someone else intercepting your connection.

A better option if you're having these issues and you know the certificate name that it's being translated to... instead of disabling this checking, you can explicitly add what names are acceptable.
$mail->SMTPOptions = array(
'ssl' => array(
'peer_name' => <acceptable peer name>
));
So looking at the referenced example which through this error:
PHP Warning: stream_socket_enable_crypto(): Peer certificate
CN=*.mail.dreamhost.com' did not match expected
CN=mx1.sub4.homie.mail.dreamhost.com' in
/home/ikbb/domains/dev.ikbb.com/public_html/includes/phpmailer/5.2.10/class.smtp.php
You could set *.mail.dreamhost.com as an allowed name.

Related

Sending an email with SMTP in php using PHPMailer [duplicate]

I am using PHPMailer on PHP 5.6, the increased security around certificated in PHP 5.6 is certainly fun.
I am trying to send a test message to a domain hosted on dreamhost, the error that comes back from PHPMailer is: Could not connect to SMTP host.
That error is not right though, I have logging enabled and here is what is actually going on.
Connection: opening to mx1.sub4.homie.mail.dreamhost.com:25,
timeout=30, options=array ( ) Connection: opened S: 220
homiemail-mx32.g.dreamhost.com ESMTP
C: EHLO s81a.ikbb.com
S: 250-homiemail-mx32.g.dreamhost.com 250-PIPELINING 250-SIZE 40960000
250-ETRN 250-STARTTLS 250-ENHANCEDSTATUSCODES 250 8BITMIME
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
C: QUIT
S: SMTP ERROR: QUIT command failed: Connection: closed
I could not understand why PHPMailer just gives up, issuing a QUIT command when it should start sending the message. I got another clue from another log:
PHP Warning: stream_socket_enable_crypto(): Peer certificate CN=*.mail.dreamhost.com' did not match expected CN=mx1.sub4.homie.mail.dreamhost.com' in /home/ikbb/domains/dev.ikbb.com/public_html/includes/phpmailer/5.2.10/class.smtp.php
If I use some custom options to prevent validation of the cert they are using I can get it to continue. Here is what I have:
$mail->SMTPOptions = array (
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true));
If I put the SMTPOptions in there and skip the peer verification, message goes OK - with no warning in PHP at all.
How can I trap that error, so I know there is an issue but still send the message?
I had the same problem and I found the answer in the PHPMailer documentation.
PHP 5.6 certificate verification failure
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:
Warning: stream_socket_enable_crypto(): SSL operation failed with code 1.
OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
The correct fix for this is to replace the invalid, misconfigured or self-signed certificate with a good one. Failing that, you can allow insecure connections via the SMTPOptions property introduced in PHPMailer 5.2.10 (it's possible to do this by subclassing the SMTP class in earlier versions), though this is not recommended:
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
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.
Sometimes this behaviour is not quite so apparent; sometimes encryption failures may appear as the client issuing a QUIT immediately after trying to do a STARTTLS. If you see that happen, you should check the state of your certificates or verification settings.
Solution for WHM/cPanel(s) : Disable SMTP Restriction by following below process:
a) Open WHM and search for SMTP restriction, make sure it's disable.(You can go through Home »Security Center »SMTP Restrictions directly as well)
b) Or Same thing can be done via Tweak Settings (Directly go for Home »Server Configuration »Tweak Settings or you can click on tweak setting link shown in upper image)
For those of you using cPanel, I tried the SMTP check code from the examples folder in PHPMailer and I got this same error:
PHP Warning: stream_socket_enable_crypto(): Peer certificate CN=*.mail.dreamhost.com' did not match expected CN=mx1.sub4.homie.mail.dreamhost.com' in /home/ikbb/domains/dev.ikbb.com/public_html/includes/phpmailer/5.2.10/class.smtp.php
I realized that it was not an error related to PHPMailer, so I searched for similar errors related to CentOS and I found this link that shed some light: Issue sending mails through 3rd party. You have to take a look at "SMTP Restrictions" in cPanel.
For PHP 5.6 use the following. Adding "tls://" is the key.
$mail->Host = gethostbyname('tls://smtp.gmail.com');
See: http://php.net/manual/en/context.ssl.php
Disable SMTP Restriction in WHM
As somebody mentioned here, the issue is an invalid SSL certificate.
Your website might have a valid SSL certificate, but it might not apply to the mail.website.net or smtp.website.net subdomains. If your hosting provider has an interface for generating SSL certificates for your website, try to search if there isn't a possibility to select subdomains for which the certificate will generate.
I had a similar problem after I've upgraded to PHP 5.6 on my WordPress machine. The WP Mail SMTP by WPForms (wp-mail-smtp) plugin were configured to use localhost as SMTP Host. I've changed it to the FQHN (Fully Qualified Host Name) as it is defined in the SSL cert.
After this change it is working fine.
If you just migrated to a different server, most likely you can fix this by disabling SMTP restriction from WHM :

PHPMailer 5.2 OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

I'm getting this error with PHPMailer on a PHP 5.6 server.
Warning: stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in class.smtp.php on line 344
The interesting thing is I'm trying to send email through the local SMTP server # localhost, and I'm not using SSL or TLS - it's plain SMTP on port 25.
$mail->SMTPSecure=''
$mail->SMTPPort //not set
The server has a valid SSL Certificate installed for the website domain.
I've read the documentation on GitHub about PHP 5.6 certificate verification failure and it doesn't seem to address this scenario.
I've added this code, but still receive the error:
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
I guess the main question is, what SSL certificate, or lack thereof is it complaining about?
PHPMailer's github page mentions this type of error:
This is covered in the troubleshooting docs. PHP 5.6 verifies SSL certificates by default, and if your cert doesn't match, it will fail with this error. The correct solution is to fix your SSL config - it's not PHP's fault!
I see that you've gone through the trouble of making the PHPMailer settings insecure as is not recommended in the troubleshooting docs. Did you notice that requires PHPMailer 5.2.10?
The correct fix for this is to replace the invalid, misconfigured or self-signed certificate with a good one. Failing that, you can allow insecure connections via the SMTPOptions property introduced in PHPMailer 5.2.10 (it's possible to do this by subclassing the SMTP class in earlier versions), though this is not recommended
There's also suggestions for enabling debug output:
$mail->SMTPDebug = 4;
If you look at the debug output, you may glean more helpful info.
EDIT: this also is not about your website's cert, it's about the cert (if any) being hosted by your SMTP mail server endpoint.

Why does my online contact form produce a Warning and Fatal Error when after sending utilising my host's relay, but not with Google's?

I have recently migrated a web form online after testing in XAMPP using a Google SMTP relay and Swiftmailer. There has been absolutely no problems with the Google relay utilising my own inbox, however, when trying to switch to my hosting provider's (Siteground) recommended relay and instructions, also utilising a domain based email, my form is hanging on send, and I receive the following:
Warning: stream_socket_enable_crypto(): Peer certificate CN=`*.sgcpanel.com' did not match expected CN=`uk2.siteground.eu' in /home/tho/public_html/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php on line 95
Fatal error: Uncaught exception 'Swift_TransportException' with message 'Unable to connect with TLS encryption' in /home/tho/public_html/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php:289 Stack trace: #0 /home/tho/public_html/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(118): Swift_Transport_EsmtpTransport->_doHeloCommand() #1 /home/tho/public_html/swiftmailer/lib/classes/Swift/Mailer.php(79): Swift_Transport_AbstractSmtpTransport->start() #2 /home/tho/public_html/sendmessage.php(30): Swift_Mailer->send(Object(Swift_Message)) #3 {main} thrown in /home/tho/public_html/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php on line 289
Note that the email account itself is working perfectly. It is set up in Mac Mail, and sends and receives with no issues at all.
My hosting provider is trying, but I don't think they can understand what issue I'm having. I've ended up narrowing it down to the transport function. See my code from the PHP below:
Google (which works as expected):
$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 587, 'tls')
->setUsername('foobar#googlemail.com')
->setPassword('APP GENERATED PASSWORD');
Hosting Provider (which does not work as expected):
$transport = Swift_SmtpTransport::newInstance('uk2.siteground.eu', 25, 'tls')
->setUsername('email#mydomain.com')
->setPassword('MY EMAIL PASSWORD');
The code seems ok to me, as it's only swapping out details. These were the settings provided by Siteground.
I've so far tried the following:
Changed the ports between 2525, 25, 587, and 465 without success;
Switched between TLS and SSL without success;
Changed my password trying various combinations without special
characters with no success;
Tried a Google search for all the permutations of 'Swiftmailer Siteground SMTP etc' but nothing has arisen.
Updated Swiftmailer to the latest version server side with no success;
I have raised further tickets, and they have updated the PHP server side for me. This now does not show an error, but just the number zero (ie. '0'). Also email is not being sent, but this is a separate issue for now.
From the error message it seems that the SSL certificate on the server uk2.siteground.eu does not include the correct hostname for the server, rather a wildcard for sgcpanel.com. The certificate on 587 it does not contain uk2.siteground.eu as a valid name for the server.
If you are using php 5.6 they changed the default to verify peer and peer names for certificates.
The proper fix would be for Siteground to add correct certificates to the server. You might override the checks with the newest version of SwiftMailer on github it seems.
The setStreamOptions added in september might solve your problems, but reduce security a bit by not checking if it is the correct server it is communicating with.
I'm not able to test it at the moment, but try:
$ssl_options = array(
'ssl' => array(
'verify_peer' => false,
'verfify_peer_name' => false,
),
);
$transport->setStreamOptions($ssl_options);
Or the array might be
$ssl_options = array(
'verify_peer' => false,
'verfify_peer_name' => false,
);
$transport->setStreamOptions($ssl_options);
More info:
http://php.net/manual/en/context.ssl.php
https://github.com/swiftmailer/swiftmailer/issues/571
The answer was provided by my host. They made some alterations to the PHP server side. At first there was no success, but after waiting an hour or so, this sorted the issue.
Well, maybe not sorted in an ideal sense, but at least as a workaround.

PHPMailer - SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Have encountered an issue where email should be sent from an mail server which has self signed certificate, the error which I get is :
PHP Warning: stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in class.smtp.php on line 327.
Has anyone encountered anything similar?
EDIT:
I have also tried to set the stream_context params (params: SSL context options):
$options['ssl']['verify_peer'] = false;
$options['ssl']['verify_peer_name'] = false;
$options['ssl']['allow_self_signed'] = true;
No luck, it still fails with the same error as pointed above.
Thanks.
PHP 5.6 introduces SSL certificate verification, so if your config is broken, it will fail with this error. You should fix your SSL, but you can revert to the old behaviour by setting the SMTPOptions property to not verify certificates:
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
Editing the library defeats the entire point of libraries - and if you do as Kaf's answer suggests, your code will break when you upgrade. Really, don't do that.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack. Be sure you fully understand the security issues before using this as a solution.
I have the same problem. So i changed the file class.smtp.php in line 238:
public function connect($host, $port = null, $timeout = 30, $options = array()) {
if (count($options) == 0) {
$options['ssl'] = array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true);
}
now it works fine!
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack. Be sure you fully understand the security issues before using this as a solution.
I had the same problem. It turned out that my Postfix config was missing the intermediates and root certificates setting:
smtpd_tls_CAfile=/etc/ssl/certs/intermediate-root-bundle.crt
Even though this Postfix config has worked for years with Outlook and Thunderbird, PHP was more picky and failed the SSL check.
So even though you might be tempted to hack PHPMailer, please don't, and fix the underlying problem.
Just wanted to put my 2 cents in since I've been looking for a fix for days until I tried Kaf's solution and it worked!! Thanks #Kaf
Anyways... For me, PHPMailer was working fine until I decided to upgrade PHP to PHP5.6
Changes were made to open ssl in PHP 5.6. Here is the official docs:
http://php.net/manual/en/migration56.openssl.php
From the docs it says to set verify_peer and verify_peer_name to false
So just follow Kaf's answer and see if that works for you.
Editor's note: The doc also says this is not recommended! Disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack. Be sure you fully understand the security issues before using this as a solution.

PHP - Swiftmailer using STARTTLS and self signed certificates

I'm trying to send an email with php and swiftmailer, using STARTTLS, but I'm getting a certificate error. I have root access to the SMTP server, and the certificate used is self-signed.
I'm using Debian on both machines (web server and smtp server)
PHP message: PHP Warning: stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in [..]/lib/classes/Swift/Transport/StreamBuffer.php on line 97
PHP message: PHP Fatal error: Uncaught exception 'Swift_TransportException' with message 'Unable to connect with TLS encryption' in [..]/lib/classes/Swift/Transport/EsmtpTransport.php:294
Do I need to add my own certificate somewhere to get it accepted? Or is this some OpenSSL configuration error?
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
Swiftmailer has now been updated to include an option for this. It can now be solved using the setStreamOptions method from your Swift_SmtpTransport instance rather than editing the swift class.
$transport = Swift_SmtpTransport::newInstance('smtp.server.com', 123, 'tls')
->setUsername('username')
->setPassword('password')
->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false)));
I got the same problem using Swiftmailer in Laravel.
Looks like there is no option for this in Swiftmailer. Clean solution would be to add your own root CA to your server and sign your mail server certificate with this CA. The certificate would be valid after this. See for example this tutorial.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
Anyway, a quick dirty hack you should not use would be to edit swiftmailer\swiftmailer\lib\classes\Swift\Transport\StreamBuffer.php. In _establishSocketConnection() line 253 replace:
$options = array();
with something like this:
$options = array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false));
This will change the ssl options of stream_context_create() (a few lines below $options):
$this->_stream = #stream_socket_client($host.':'.$this->_params['port'], $errno,
$errstr, $timeout, STREAM_CLIENT_CONNECT, stream_context_create($options));
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
You do not need to edit /vendor files. You can specify (undocumented) options in your config/mail.php file:
'stream' => [
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
],
You can check it yourself in vendor/laravel/framework/src/Illuminate/Mail/TransportManager.php on line ~50:
...
if (isset($config['stream'])) {
$transport->setStreamOptions($config['stream']);
}
...
Needless to say, circumventing peer verification has huge security implications (read vulnerabilities). I imagine this solution for some dev or local environment, never in production or even in an Internet/Publicly available app.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
For me, I had to add $transport->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false, 'verify_peer_name' => false))); to the Mailer.php file, see:
/**
* Returns the SMTP transport
*
* #return \Swift_SmtpTransport
*/
protected function getSmtpInstance(): \Swift_SmtpTransport {
$transport = new \Swift_SmtpTransport();
$transport->setTimeout($this->config->getSystemValue('mail_smtptimeout', 10));
$transport->setHost($this->config->getSystemValue('mail_smtphost', '127.0.0.1'));
$transport->setPort($this->config->getSystemValue('mail_smtpport', 25));
if ($this->config->getSystemValue('mail_smtpauth', false)) {
$transport->setUsername($this->config->getSystemValue('mail_smtpname', ''));
$transport->setPassword($this->config->getSystemValue('mail_smtppassword', ''));
$transport->setAuthMode($this->config->getSystemValue('mail_smtpauthtype', 'LOGIN'));
}
$smtpSecurity = $this->config->getSystemValue('mail_smtpsecure', '');
if (!empty($smtpSecurity)) {
$transport->setEncryption($smtpSecurity);
}
$streamingOptions = $this->config->getSystemValue('mail_smtpstreamoptions', []);
if (is_array($streamingOptions) && !empty($streamingOptions)) {
$transport->setStreamOptions($streamingOptions);
}
/* EDIT - allow self-signed mail cert */
$transport->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false, 'verify_peer_name' => false)));
/* EDIT end */
return $transport;
}
I got this from another link, can't find it now.
One think that I did extra to the other answers was to specify the 'verify_peer_name' => false

Categories