CURLOPT_SSL_VERIFYPEER = false? - php

In my plugin I sending request with curl, and it's works fine for a long time.
Sudden on my test server stop works, then I added this line:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
and now it works fine.
Can anyone explain to me way it's stop working and is safe to disable CURLOPT_SSL_VERIFYPEER?

It probably stopped because your client can no longer verify the remote certificate. You could figure out for sure by checking the return/error code curl returns for you.
Why can't it verify that? Probably because your CA cert bundle isn't featuring the correct (set of) certs.
Is it safe to disable remote cert verification? No. You then allow man-in-the-middle attacks as you can no longer be sure you're actually talking to the correct server and not an impostor.

Related

CURL PHP not working on WAMP and XAMPP

I have this simple php script:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.instagram.com/zuck/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo htmlspecialchars($output);
I have Apache 2.4.17, PHP : 5.6.16 (I also tried with PHP 7)
I have tried running it on a remote host server and it works just as expected. However it doesn't work at all on my PC.
I tried WAMP, XAMPP, disabled firewall, connected directly to my modem (without router), checked the php.ini and c_url is uncomented. I also tried downloading a fix from http://www.anindya.com/. Doesn't work as well. When i try curl_version it works (so i guess c_url is loaded) but this script doesn't. And the strange thing is there are no errors just a blank page.
I really don't have any more troubleshooting ideas
After some testing I found the problem:
First I checked for erros in the script itself with:
echo curl_error($ch)
which returned this:
SSL certificate problem: unable to get local issuer certificate
Turns out I had to disable SSL certificate verification because all the websites i had tried used SSL (eg instagram, google, etc.)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false)
This question is marked as answered but for those who see this in future, the comment of #amphetamachine is important. Setting CURLOPT_SSL_VERIFYPEER to false is not a good idea. It will work on your local server but do you really want this on the remote server?
Rather than having to remember to comment out this line for production (or make it conditional on the environment), I suggest you add to your php.ini file the absolute path to the Certificate Authority file (where you will have already uncommented the cURL extension).
curl.cainfo ="your absolute local path\cacert.pem"
This file can be downloaded if you don’t have it.
That way your local test system for will work and you will not compromise your production setup.
You could set the path in the cURL option CURLOPT_CAPATH but again you would not want this in your production code.

Does turning off CURLOPT_SSL_VERIFYPEER in cURL make transmission insecure?

On the PHP docs page about curl_setopt the most upvoted comment is
Please everyone, stop setting CURLOPT_SSL_VERIFYPEER to false or 0. If
your PHP installation doesn't have an up-to-date CA root certificate
bundle, download the one at the curl website and save it on your
server:
http://curl.haxx.se/docs/caextract.html
Then set a path to it in your php.ini file, e.g. on Windows:
curl.cainfo=c:\php\cacert.pem
Turning off CURLOPT_SSL_VERIFYPEER allows man in the middle (MITM)
attacks, which you don't want!
Really? As I understand it, turning off CURLOPT_SSL_VERIFYPEER stops curl from verifying the peer's certificate but data transmission stays secure. Which one is true?
Yes it is insecure. If you don't check the certificate you can't be sure that the sender is truly the server you think you're talking to and it may be an impostor. A man in the middle.
Even impostors can run SSL and negotiate an encrypted connections with you. But they can (supposedly) not purchase a certificate for the forged site using the legitimate cert name.

Bypassing SSL check

I'm debugging an issue that someone is having in accessing a payment gateway using a PHP plugin. The only way he has been able to avoid a 404 error after clicking the Checkout button is by setting CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST to 0. I know this is bad, but does anyone know why this might be? It seems to be distrusting of the SSL certificate of the payment website...could this just be an issue with his server not trusting certain SSL certificates? The response he is getting from the curl_exec() function is just false when the checks are turned on.
EDIT: So I've seen multiple solutions that say to add something similar to this to my curlopt lines after getting the certificate file:
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/certificate.cert");
But what if I'm dealing with a bunch of separate customers that are having this issue? That path won't work for everyone. What can I put instead that will apply to each person?
If I can't put a general line, then where would I tell the person to put their certificate file? This would have to be done by their web hosting service, right?
here is a good answer to your problem:
Security consequences of disabling CURLOPT_SSL_VERIFYHOST (libcurl/openssl)
i suggest to analyze the certificate issued by the payment website..
the url used by the php plugin is exactly the same specified in the common name field of the certificate?
If you are sure the certificate provided it's ok, and trusted, You could set the CURLOPT_CAINFO option to trust this certificate and avoid the error:
curl_setopt($ch, CURLOPT_CAINFO, 'C:\path\to\curl-ca-bundle.crt');
Chech your SSL Certificate here : http://www.digicert.com/help/
I had a similar issue because certificates hadn't been good chained.

cURL stopped working for HTTPS sites

All of a sudden, my PHP cURL implementation that access sites over SSL stopped working. After some digging around in the cURL response headers I discovered that the issue was a result of cURL not liking the sites SSL cert, giving the error:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Now I didn't test it with other sites and I know there are solutions to add Mozilla's certs to cURL. But to get stuff to work I simply added a new cURL option to disable SSL validity checks (CURLOPT_SSL_VERIFYHOS).
But I am still confused as to how this would stop working in just one day. It worked yesterday. The cert on the site didn't change and it is still a valid, unexpired, Verisign-issued cert.
Had this happen to me last month as well, and the only reason was that the SSL certificate in question was expired. So I just renewed it and the curl ssl link worked again. If you happen to deal with self-signed certificates it's the same deal btw, you either import it or switch of the verification.
That's the only thing I can think off but you state you already verified that...weird. Any chance to take a peek at the site's certificate or is it private? If you haven't changed anything it's almost certainly that something happened to the SSL certificate.
Try These two options in curl
CURLOPT_SSL_VERIFYPEER, FALSE
CURLOPT_SSL_VERIFYHOST, 2

Source of PEM files for web service access

I should have paid more attention to my classes that covered security. I'm quite confused about something. To start, here's the background of what I'm trying to accomplish.
I have a web service that I need to access. The web service is set up as HTTPS. The traffic between client and server is encrypted (this doesn't have to do with authentication).
I'm interacting with the web service via cURL and PHP. I've gotten an example to work locally over HTTP and I'm fairly confident I'm on the right track with regards to cURL/PHP side of things.
When using the HTTP version of the code to access a web service over HTTPS, I am getting an error code 60 "SSL certificate problem, verify that the CA cert is OK" (error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed)
From my reading, it seems that I need a PEM file and I need to set additional cURL options such as the following:
CURLOPT_CAINFO
CURLOPT_SSLCERT
CURLOPT_SSLKEYPASSWD
My question is how do I know where to get the PEM file or whether I can simply make it? This is probably going to be an obvious answer as I'm sure I'm missing something but I figure I just need to ask and get the background I'm missing.
Amendment: The web service is using a certificate signed by VeriSign. So it's not a self signed certificate. Also, the web service is owned and operated by an external organization.
Thanks.
Despite googling around prior to asking this, it seems I've stumbled upon the answer after a bit of back-n-fourth with 'thatidiotguy' (his user name, not my name for him. ;-) ).
cURL, out of the box, does not trust any CA (VeriSign or otherwise). This needs to be setup on your server. To "solve" the problem, you have two options. You can bypass the verification with the following command:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Note that this is not optimal with regards to security. Any certificate, signed by a CA or not, will be accepted as trusted.
The proper fix involves getting the original certificate (in my case this means the web service) and "exporting" the certificate as a X.509 Certificate (PEM). The certificate then needs to appropriately moved to the server and the following configurations set:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //Check that the common name exists and that it matches the host name of the server
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/path/to/cert/my-exported.crt"); //PEM file
Source: http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/
The answer is very simple. You need to download a certificate bundle, one that also ships with regular browsers.
Luckily that work is already done for you here:
http://curl.haxx.se/docs/caextract.html
Once downloaded you specify the path to this file with CURLOPT_CAINFO.

Categories