Google+
Shineyrock web design & consultancy

Shineyrock

blog

  • dislike -11 22

    Building Your Startup: Securing an API

    Final product image
    What You'll Be Creating

    Welcome to the Building Your Startup With PHP series, which is guiding readers through the launch of an actual startup, Meeting Planner. Each episode details different coding and business challenges, with detailed examples you can use to learn.

    Introduction

    Recently, I introduced you to Yii's simple REST API generation and Meeting Planner's new "RESTful" service API. At that time, I mentioned that these APIs were only loosely secured. Sure, there was a shared secret between the client and the server, but there were a couple of problems.

    First, the secret key and user tokens were repeatedly transmitted in query parameters of SSL calls. And there was no other authenticity check for the data, allowing a middle-person attack.

    In today's episode, I'll guide you through how I secured the API against these weaknesses for a more robust API.

    If you've been reading our startup series, you've probably already tried Meeting Planner and Simple Planner, but if not, please do. Scheduling a meeting is easy:

    As usual, I'll be participating in the comments below, so please offer your thoughts. You can also reach me on Twitter @lookahead_io. I'm always especially intrigued if you want to suggest new features or topics for future tutorials.

    As a reminder, all of the code for Meeting Planner is written in the Yii2 Framework for PHP. If you'd like to learn more about Yii2, check out our parallel series Programming With Yii2.

    The Initial API Security

    Let's begin by taking a look at the early API security I coded. We'll presume there's a mobile app that I've shared an $app_id and $app_secret with. Only API callers with these keys are accepted.

    For example, the app tries to register its owner, likely a new Meeting Planner user:

    The app calls the above actionRegister via https://api.meetingplanner.io/user-token/register/ with arguments as follows:

    • $app_id and $app_secret for authentication
    • $source = 'facebook' for the OAuth service we're using, and accompanying $oauth_token from that service
    • $email, $firstname, and $lastname provided via OAuth

    All of those are query arguments such as:

    Service::verifyAccess($app_id,$app_secret) looks up the keys to authenticate the call as shown below:

    Because the keys and the data were sent via SSL, they're pretty secure but not invincible. Neither is the secret key safe on users' iPhones for certain.

    How can we make this more secure? Here are a few ideas:

    1. Don't ever transmit the secret key over the Internet.
    2. Don't transmit any of the data as URL parameters which might show up in server logs.
    3. Sign all the data to verify its accuracy.

    These are actually standard practices used for securing APIs.

    Note: An example of the risk of transmitting data that could be exposed in server logs would be the email and the Facebook OAuth token. If found in logs, these could be used with the Facebook API to access someone's Facebook account.

    Implementing Better API Security

    Using Hash Signatures

    First, I'm going to stop transmitting the $app_secret. Instead, we'll sign the outgoing data with it before making an API call. 

    So we'll alphabetize the variables and concatenate them into a string, like this:

    Resulting in:

    Then, we'll hash the data with PHP's hash_hmac and the sha256 algorithm using our secret key.

    Building Your Startup Securing API - PHP hash_hmac docs

    This creates a unique hash code based on the arguments of the API call and our shared secret key:

    Now, we can make a call on the API without transmitting the secret key. Instead, we transmit the signature of the hashed data above.

    I've been using Postman to test the API, but you can also use cURL:

    Building Your Startup Securing API - Testing the API with a signature

    Here's the receiving API code that responded to the call above:

    Furthermore, as I reviewed last time, each user receives their own token when they access Meeting Planner through the API, e.g. via their mobile phone. So, subsequent to registration, we can sign calls with their individual token and don't need to transmit either the application's secret key or the user's individual token.

    Sending Data in the HTTPS Headers

    Next, we'll migrate sending data in the headers. You can do this easily with Postman or cURL. Here's Postman:

    Building Your Startup Securing API - Testing the API sending data in the headers

    And here's cURL:

    Here's the receiving code which gets the API data from HTTPS Headers:

    In Closing

    We began today with the following goals:

    1. Don't ever transmit the secret key over the Internet.
    2. Don't transmit any of the data as URL parameters which might show up in server logs.
    3. Sign all the data to verify its accuracy.

    And we accomplished all of these goals with only modest changes to our API code. It was fun making these changes and seeing how easily we can better secure an API. I hope you enjoyed following along with today's episode.

    I regularly monitor the comments, so please join in the discussion. You can also reach me on Twitter @lookahead_io directly. And, of course, watch for upcoming tutorials here in the Building Your Startup With PHP series.

    If you didn't earlier, try scheduling a meeting at Meeting Planner and let me know what you think. I especially appreciate feature requests.

    Related Links

    martijn broeders

    founder/ strategic creative bij shineyrock web design & consultancy
    e-mail: .(JavaScript must be enabled to view this email address)
    telefoon: 434 210 0245

Per - categorie

    Op - datum