Brian Fenton | Contributor
September 28, 2011

Know who is accepting your API calls

 

Several months ago when I was working on a Foursquare notification tool, I was made aware of a security issue with using SSL through cURL. API calls to Foursquare require SSL, which a good idea for many API-driven applications. However, all the common examples for how to make API calls to Foursquare (including the PHP classes recommended by Foursquare itself), included setting some innocent-looking, and potentially dangerous settings. Namely:

curl_setopt(CURLOPT_SSL_VERIFYPEER, false)

This tells cURL to stop caring who answers its request, as long as they use SSL, breaking one of the basic cryptography assumptions that SSL is supposed to provide.

Cryptography Advantages

Here's an extremely brief overview of what cryptography is supposed to provide, and what they mean.

  • Confidentiality - unintended users cannot read your data
  • Integrity - data is not modified in transit
  • Authentication - the user is who they say they are. This is lost with the wrong cURL setup
  • Non-repudiation - if a message is cryptographically signed, the sender can't deny they sent it

 

Risks

If you disable SSL verification, all you are asking SSL to do is ensure that the machine on the other end of your call supports SSL and has a certificate. It no longer requires that the certificate/host receiving your request is the one you think it is. All it takes to hijack your data in this case is bad DNS, a compromised hosts file, or any other type of man-in-the-middle attack.

The Fix

  1. Tell cURL to verify that the certificate it is presented with is recognized by a certificate authority
  2. Tell cURL to verify that the certificate it is presented with is issued to the site it says it is
  3. Tell cURL where your local certs are stored so it can perform these verifications

 

Step 3 is the hardest because I can't just tell you where they are on your local system, but see the two blog posts linked below for discussions on this. The short answer is that you'll need to either export a .pem file from your browser's certificate cache or download one from a trusted source.

You owe it to yourself and your users, whether you're providing or consuming APIs via cURL (or higher-level libraries that rely on cURL) to set those SSL options properly, and provide cURL with your local certificates cache so it can verify that the certificate used to sign your data is known and valid.

Resources