What is the relationship between cURL, WordPress and cacert.pem?

HTTPS isn’t all about encryption alone. SSL also uses a process known as certificate verification to prevent host forgery. This is a multi-layered process, but here’s the quick overview:

There exist in the world a number of Certificate Authorities (CAs). When you get a certificate for your domain name to allow it to do SSL, generally you buy it from one of these CAs. They digitally “sign” the certificate, verifying that they’ve checked it or what have you.

Every web browser comes with a list of CAs (and their cryptographic signature) that that browser trusts. Thus, when you go to an HTTPS URL, the server presents its signed certificate. Your browser performs an operation to verify the signature against the CAs it knows about. If it knows it, and the domains match, then it assumes the domain is valid and it trusts that site. Generally this means it displays the trusted icon or something. If it doesn’t match, then it usually presents the viewer with a box saying that it can’t verify the certificate and that the user should proceed with caution.

Now, curl is a web browser too. It also verifies certificates in the exact same way. However, curl is a program installed on your web server, and it’s probably not up-to-date on all the latest and greatest CAs and revocation lists and such. So when it checks the signature, the check fails because it doesn’t know the relevant CAs.

The fix for this that you’re thinking about involves getting the newest cacert.pem file (the CA certificates list) and then telling the curl library where that file is and to use it. This would work fine, if you have the cacert.pem file and you put your code into the wp-config.php file. Every once in a while you may have to update the cacert.pem file to the latest version.

The other alternative is to tell curl to ignore the verification phase and to just use SSL for encryption. This works well, but means that you’d potentially be vulnerable to a specialized kind of attack, but what they could do depends on what you’re using the remote get for. To do this, you can add the sslverify argument to the wp_remote_get call, like so:

wp_remote_get('https://whatever',array('sslverify'=>false));

Edit to avoid a new “answer”, as my reputation is null and I cannot comment – MeanderingCode:

In answer to MikeSchinkel’s comment/question: The absence of verifying that the signature on the certificate is from a “trusted” Certificate Authority means that anyone could have created the certificate in order to initiate the encrypted HTTP session, and potentially there is a Man-In-The-Middle, decrypting your traffic, reading or altering it, re-encrypting it, and sending it along in their own session with your intended destination. Potentially, sensitive information is traveling over the connection; most commonly, authentication credentials. A MITM would see in plaintext any information sent over the link, and then have your credentials and any other information that was sent either direction.

Leave a Comment