Curl Requires Curlopt_Ssl_Verifypeer=False

cURL requires CURLOPT_SSL_VERIFYPEER=FALSE

Thanks to Dave Chen's suggestions, I realized I must have misplaced my certificate. The problem is solved by this certificate which is provided by the cURL creator (extracted from Mozilla): https://curl.haxx.se/ca/cacert.pem

So after downloading this cacert.pem file into your project, in PHP you can now do this:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt($ch, CURLOPT_CAINFO, "/path/to/cacert.pem");

Alternatively, this can be set globally by adding the following to your php.ini

curl.cainfo=/path/to/cacert.pem

If CURLOPT_SSL_VERIFYPEER is false, is the data transfer no longer secure?

The connection will still be SSL encrypted. You just won't be doing it on a link that uses validated-as-correct certificates. Anyone can create themselves an SSL certificate which will do perfectly acceptable encryption at whatever level your browser and the webserver support.

However, what you will get is many complaints about not being able to verify the certificate's authenticity. This is to prevent Joe M. Alicious from creating themselves a certificate claiming to be "microsoft.com" and setting up their own Windows Update host. The cert will say it's microsoft.com, but it cannot be authenticated as actually being microsoft.com, as Verisign (or whoever) did not actually issue that cert and put their own stamp of authenticity (signing the cert) on it.

_VERIFYHOST is there to check that the hostname of the URL you're connecting to (e.g. "microsoft.com") is listed within the SSL cert. With this option set to false, url/cert hostname mismatches will be ignored (say, you've got a development box at testbox.develhost.com, but are using your client's real valid 'example.com' cert).

_VERIFYPEER disables validating the entire certificate. This allows self-signed certs to work. Otherwise the SSL library will barf saying that the cert's issuer isn't valid.

But regardless of either setting, if you force through a connection, it WILL be ssl encrypted.

Why we need CURLOPT_SSL_VERIFYPEER in windows

This cURL man page on SSL Certificates describes the process for Certificate Verification when connecting to SSL/TLS secured hosts.

The reason you are needing to set CURLOPT_SSL_VERIFYPEER to false on Windows is because the CA bundle it uses to verify the certificates is missing (or there is no default path compiled into cURL so you need to explicitly define it).

You can configure it in php.ini using the curl.cainfo directive, or specify it at runtime using:

curl_setopt($curl, CURLOPT_CAFILE, 'C:/path/to/ca-bundle.crt');

If you don't have a copy, grab a recent one here.

While disabling peer verification is a workaround, this can be unsafe because you're disabling the very check that ensures you are securely communicating with the site you think you are.

Anyone can generate a self signed certificate to impersonate a domain, but browsers or clients (like cURL) will fail if the certificate can't be verified unless you ignore or bypass this check (i.e. CURLOPT_SSL_VERIFYPEER = false).

CURLOPT_SSL_VERIFYPEER = false?

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.

Does turning off CURLOPT_SSL_VERIFYPEER in cURL make transmission insecure?

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.

Is it ever safe to set CURLOPT_SSL_VERIFYPEER to FALSE? Even if you control both servers?

Is it safe to leave this set to false, because I control the traffic on both ends? In fact, do I even need an SSL cert? As long as it goes over HTTPS it's secure, right?

No. You are only safe if you not only control both ends but also everything in between. If you have a single cable between two computers and control both computers than you are probably safe. If there is any cabling, router etc which might be accessed by somebody else you are not safe anymore.

Am I in danger of a man-in-the-middle attack?

Yes, unless you can control everything in between you cannot prevent a man in the middle. And unless you validate the certificates you can neither detect nor prevent the attack.

Why does cUrl fail to download via HTTPS unless CURLOPT_SSL_VERIFYPEER is set to false?

This happens because you have not configured curl with CA certificates that are considered trustworthy, so it has no way of verifying the signature on the remote server's certificate (although in all likelihood the signature is valid).

To verify the signature you should set either CURLOPT_CAINFO or CURLOPT_CAPATH appropriately.

Not hacking CurlException: 60 (cURL SSL Certificate Verification)

What It Does & Meaning:

The following code tells the cURL to NOT verify that security certificates are correct. Hence, the error disappears.

  $opts[CURLOPT_SSL_VERIFYPEER] = false;
$opts[CURLOPT_SSL_VERIFYHOST] = 2;

When you connect to a remote server with SSL, their certificate might be invalid, expired, or not signed by a recognized CA. The cURL normally checks it.

CURLOPT_SSL_VERIFYHOST:

  • 1: to check the existence of a common name in the SSL peer certificate.
  • 2: to check the existence of a common name and also verify that it matches the hostname provided.

CURLOPT_SSL_VERIFYPEER: 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).


How to Enable & Verify Correctly:

To verify correctly, we need to to verify the certificate being presented to us is good for real. We do this by comparing it against a certificate we reasonable* trust.

If the remote resource is protected by a certificate issued by one of the main CA's like Verisign, GeoTrust et al, you can safely compare against Mozilla's CA certificate bundle which you can get from http://curl.haxx.se/docs/caextract.html

Save the file cacert.pem somewhere in your server and set the following options in your script.

curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE); 
curl_setopt ($ch, CURLOPT_CAINFO, "pathto/cacert.pem");

If you are connecting to a resource protected by a self-signed certificate, all you need to do is obtain a copy of the certificate in PEM format and append it to the cacert.pem of the above paragraph.



Related Topics



Leave a reply



Submit