Mr.Boon Mr.Boon - 6 months ago 19
SQL Question

Building Secure Public API with PHP/MYSQL

I'm currently building an API for a very busy internet website. Its being written in PHP with MySQL. Now this is my first API that i'm writing that allows people to access their account remotely. Once the API is online, developers will be able to write their own tools from it.

Now I have the API working, but I'm not sure if its entirely safe.

An example URL that would work is:

http://domain.com/api.php?api_option=list&api_user_name=USERNAME&api_user_password=PASSWORD


USERNAME
: would be the users actual username

PASSWORD
: would be the MD5 encoded string of their actual password.

If the details match, a result is returned, if not, and error.

All external
$_GET
inputs get the
mysql_real_escape_string()
treatment.

I wanted to keep things simple, but I'm not sure if this way is a SAFE way of having a public API that taps directly into users accounts data.

Ideas and suggestions are much appreciated.

Answer

How about signing requests using HMAC_SHA1 and the user's password? For example, your URL: http://domain.com/api.php?api_option=list&api_user_name=USERNAME&api_user_password=PASSWORD

Add the timestamp and/or a random string (nonce) and build a normalized base_string:

$base_string = "api_option=list&api_user_name=USERNAME&timestamp=1296875073&nonce=hgg65JHFj";
$signature = hmac_sha1($base_string, PASSWORD);

then the new URL would be: http://domain.com/api.php?api_option=list&api_user_name=USERNAME&timestamp=1296875073&nonce=hgg65JHFj&signature=kfvyhgfytgyr6576yfgu

What your server does is to get all the options, excluding the signature, then generate the signature using the same method and compare it to the signature sent by the client, which should be the same.