2

I've run into a problem concerning wp_remote_get() and the underlying cURL call. On some WordPress installations I see the following SSL error:

httprequest_failed: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GETSERVER_CERTIFICATE:certificate verify failed

From my research it looks as if the following should resolve my problem: curl_setopt ($handle , CURLOPT_CAINFO, dirname(FILE)."/cacert.pem");

I'm uncertain what I need to configure on my server so that this error doesn't occur. I found the above line of code set in a different plugin but I'm unsure of the reason why.

Thoughts?

Shepherd

1 Answer 1

4

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.

4
  • Great answer, thanks. Question: If someone is using the remote GET in a plugin to call a RESTful web service that is hosted by the developer of the plugin, do you see any potential issues for security there? For example, if an "ACME Plugin for WordPress" using wp_remote_get() on api.acme.com/stuff do you think there's any potential issue if we turn off 'sslverify'? Commented Jul 4, 2011 at 19:16
  • The security implication is that you could be vulnerable to a man-in-the-middle attack, such as via DNS poisoning or a compromised WiFi access point. Basically, when you connect to api.example.com, then you have no way to know if that's really api.example.com you're talking to, or some other system pretending to be api.example.com. Without sslverify (in curl this is called CURLOPT_SSL_VERIFYPEER), then anybody could intercept your communications, pretend to be somebody they're not, and you have no way to tell. Verifying certificates eliminates this possibility.
    – Otto
    Commented Jul 4, 2011 at 21:23
  • and @MeanderingCode - Gotcha, thanks! If this is code only running as a plugin then WiFi access points aren't really a problem, but a rogue ISP could be right? Security hasn't been my strength, but I'll get there. Commented Jul 4, 2011 at 22:07
  • Well, anything that can get between your server and the server that it's contacting could potentially intercept the communication and replace it with something else. What the security implications of that are depends on what exactly you're sending/receiving between the servers.
    – Otto
    Commented Jul 5, 2011 at 13:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.