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.
Related
I'm trying to get the profile picture of this website but getting the error as below. I tried going to Plugins and replacing this code, but it didn't work
Link: https://vn.joboko.com/viec-lam-ky-su-he-thong-pacs-y-te-tai-ha-noi-xvi2125694
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
with
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
but still can't.
This is most likely related to the expired DST Root CA X3, which expired Sep 30 14:01:15 2021 GMT.
Libcurl is using VERIFYPEER and VERIFYHOST to ensure trust between client and server.
The DST CA Root X3 certificate is part of the "cacert-bundle".
As of today the "cacert-bundle" can be found here: https://curl.se/docs/caextract.html
as part of the bundle https://curl.se/ca/cacert.pem.
The expired certificate is:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
44:af:b0:80:d6:a3:27:ba:89:30:39:86:2e:f8:40:6b
Signature Algorithm: sha1WithRSAEncryption
Issuer: O=Digital Signature Trust Co., CN=DST Root CA X3
Validity
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Which is used to verify peer in libcurl calls to websites using Let's Encrypt issued certificates.
Here's a detailed solution to your problem: https://stackoverflow.com/a/69411107/1549092
Another solutions is to disable VERIFYHOST and VERIFYPEER in your curl calls using that WP code.
Before doing that there's something to be aware of:
Let's explain the comparing your SSL/TLS certificate to the verified CA Authorities and how does that affect Man-in-the-middle (MITM) attacks.
Your program could be misled into talking to another server instead. This can be achieved through several mechanisms like DNS or ARP poisoning.
The intruder can also self-sign a certificate with the same 'comon name' your program is expecting.
The communication would still be encrypted but you would be giving away your secrets to an impostor.
This kind of attack is called 'man-in-the-middle'.
Defeating the 'man-in-the-middle'
We need to verify the certificate being presented to us is good for real. We do this by comparing it against a certificate we reasonably trust.
If the remote resource is protected by a certificate issued by one of the main CA's like Verisign, GeoTrust etc., you can safely compare against Mozilla's CA certificate bundle, which you can get from http://curl.haxx.se/docs/caextract.html
CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER prevent MITM attacks
WARNING: Disabling this would prevent CURL from detecting Man-in-the-middle' attacks!
#param CURLOPT_SSL_VERIFYPEER
Check the existence of a common name in the SSL peer certificate.
Check the existence of a common name and also verify that it matches the hostname provided.
To disable set the value to false:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
#param CURLOPT_SSL_VERIFYHOST
FALSE to stop CURL from verifying the peer's certificate.
Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option.
CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE if CURLOPT_SSL_VERIFYPEER is disabled (it defaults to 2).
Setting CURLOPT_SSL_VERIFYHOST to 2 (This is the default value) will guarantee that the certificate being presented to you have a 'common name' matching the URN you are using to access the remote resource.
This is a healthy check but it doesn't guarantee your program is not being decieved.
To disable this set the value to false:
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
Doing this disables the most important part of the CURL SSL handshake for your website!
I would consider resolving this issue globally for your OS as explained here: https://stackoverflow.com/a/69411107/1549092
Check again your host/vps. I crawled it on my delicated server which in the image
Gallery Image URL Selectors
Exchange element attributes
The solution to this problem is described here in detail: https://wp-kama.com/note/error-making-request-wordpress
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.
I'm attempting to interface with the Google PHP API client and I am having issues with the certificate provided by Google:
Google error:
SSL certificate problem, verify that the CA cert is OK.
Retrying with the CA cert bundle from google-api-php-client.
PHP cURL error:
SSL certificate problem: unable to get local issuer certificate
I had no problems whatsoever on a Linux box. These errors are occuring on a Windows box.
I've tried a couple of different solutions:
https://code.google.com/
http://richardwarrender.com/
but to no avail.
PS:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
won't be acceptable ...
Courtesy of rmckay at webaware dot com dot au:
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!
\Google_Client::$io->setOptions(array(CURLOPT_SSL_VERIFYPEER => FALSE));
#sKophek is correct and I appreciate the help as I was struggling with this. For those that prefer a touch more detail, here it is: (this is true, at least, for the 0.6.x version of the google-api-php-client)
1) \google-api-php-client\src\io\Google_CurlIO.php
2)
private $curlParams = array (
...
CURLOPT_SSL_VERIFYPEER => false,
... );
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.
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.