Lets make something clear from the very start: JUST BECAUSE THERE IS https:// IN THE URL OF THE REMOTE SERVICE IT DOES NOT MEAN THE CONNECTION IS SECURE!
I am sorry for the tone of this post but i am enraged by how popular this issue is online. If you ask why i suggest a little experiment.
Steps to follow
- Change your host file settings to point something like www.somedomain.com to your development server
- Create a self signed certificate for this domain and setup a https virtual host to serve it on local IP or alias
- Put a test file on that URL
- Create a PHP script that accesses that file on that fake service over https. Use Zend HTTP client or CURL or whatever like file_get_contents or what you prefer.
- Run script and check the result.
Well so what has happened? Did you get a big fat error like below?
Error in cURL request: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
No you did not?
Result of the experiment and interpretation
It is almost certain that your script has downloaded the test file and it all worked. That is a huge problem. What it means is that the way you accessed the file did not enforce SSL certificate verification. What does it mean? Well it means that anyone who can foll your DNS client or mess with IP routing, Ethernet, has access to your local network, controls some of the routers on the path etc can hijack your communication without you knowing it. All the attacker has to do is find a way to make your web server connect to his fake service instead of the real one. There are many many attack types that can let hacker do that and it is difficult to prevent all of them at once.
So if you are sending credit cards data, passwords, personal data, emails or whatever you better watch your back. Attacker can easily create a proxy to intercept all the transferred data and save the details without you ever finding out.
So why am i so angry and write with all-caps all the time?
Because there are dozens of libraries and code samples online that are wrong! and they are not written by some poor students, they are on corporate websites of biggest payment services. How could this ever happen? how could they be so reckless to show people the WRONG way to integrate? I really do not know.
This is how you should not be doing it:
// Set the curl parameters. $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $API_Endpoint); curl_setopt($ch, CURLOPT_VERBOSE, 1); // Turn off the server and peer verification (TrustManager Concept). curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1);
THERE IS NO SUCH THING AS TrustManager Concept THAT CAN PROTECT YOU FROM MAN IN THE MIDDLE ATTACKS! THIS SAMPLE IS SIMPLY WRONG!
All the samples below are wrong (i just spent like 15 mins googling there are tons of examples like this):
This sample can potentially be dangerous as well as by default path to certificates is empty - meaning we have same issue unless we dig deep enough to set it to something meaningful:
How to protect yourself from man in the middle attacks in PHP?
All you have to do is make sure you verify the SSL certificate when you connect to the remote service. Make a test, point host file to your fake service and you should get SSL certificate verification error. If you do not get the error your client code is not secure. There are samples that do it right so have a look for example here Smashing Magazine integration sample.
60 CURLOPT_SSL_VERIFYPEER => true, 61 CURLOPT_SSL_VERIFYHOST => 2, 62 CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem', //CA cert file
The article does not explain exactly what are the risks but it shows how to do it. The cert.pem is a bundle of SSL certificate authorities that are trusted and can be used to safely verify authenticity of a website's certificate. It does not contain certificates of all websites in the world just certificates of authorities like verisign who sign certificates sold to clients.
You can generate the bundle by downloading
This should last for years but it is a good idea to put an update automation to get latest bundles from time to time.
Spread the word!
About the author
Hi, my name is Artur Ejsmont,
welcome to my blog. I am a passionate software engineer living in Sydney and working for Yahoo!
If you are into technology, you can order my book Web Scalability for Startup Engineers on Amazon. I would love to hear what are your thoughts so please feel free to drop me a line or leave a comment.