3
\$\begingroup\$

I am starting to play with POST request to save in my server the user token so I can send push notifications in Swift (this is the Swift code). This is the PHP file that processes the request (please note that I will improve it using prepare statements to prevent SQL injection):

<?php
error_reporting(E_ALL);
 ini_set("display_errors", 1);
// typically there would be much more
// validation done on the request and
// cleaner database handling

// create link to database
$host = "localhost";
$db = "myDatabase";
$dbuser = "admin";
$dbpass = "mypassword";

$now = date("Y-m-d H:i:s");

$dbConnection = mysql_connect($host, $dbuser, $dbpass);
if ($dbConnection) {
    mysql_select_db($db, $dbConnection);
} else {
    // return error status code
    sendAPIResponse(500);
    return;
}



// get the post body
$userid = $_REQUEST['user'];
$token = $_REQUEST['token'];


if (empty($userid) || empty($token)) {
    sendAPIResponse(400);
    return;
}

// determine if user exists
$sql = "SELECT user_id 
        FROM users 
        WHERE user_id='".$userid."' LIMIT 1;";
$query = mysql_query($sql, $dbConnection);
$userExists = mysql_fetch_row($query);

// add a 'user' record
if (!$userExists) {

    $sql = "INSERT INTO users (user_id) 
            VALUES ('".$userid."');";
    if (!mysql_query($sql, $dbConnection)) {
        // return error
        sendAPIResponse(400);
        return;
    }

}

// determine if token already exists
$sql = "SELECT token 
        FROM user_tokens 
        WHERE user_id='".$userid."' 
          AND token='".$token."' LIMIT 1;";
$query = mysql_query($sql, $dbConnection);
$tokenExists = mysql_fetch_row($query);

// add a token for current user
if (!$tokenExists) {

    $sql = "INSERT INTO user_tokens (user_id, token, datecreated) 
            VALUES ('".$userid."','".$token."','".$now."');";
    if (!mysql_query($sql, $dbConnection)) {
        // return error
        sendAPIResponse(400);
        return;
    }
}

// close the database connection
mysql_close($dbConnection);

// return success
sendAPIResponse(200);



date_default_timezone_set('America/New_York');

function getStatusCodeMessage($status) {

    $codes = Array(
        100 => 'Continue',
        101 => 'Switching Protocols',
        200 => 'OK',
        201 => 'Created',
        202 => 'Accepted',
        203 => 'Non-Authoritative Information',
        204 => 'No Content',
        205 => 'Reset Content',
        206 => 'Partial Content',
        300 => 'Multiple Choices',
        301 => 'Moved Permanently',
        302 => 'Found',
        303 => 'See Other',
        304 => 'Not Modified',
        305 => 'Use Proxy',
        306 => '(Unused)',
        307 => 'Temporary Redirect',
        400 => 'Bad Request',
        401 => 'Unauthorized',
        402 => 'Payment Required',
        403 => 'Forbidden',
        404 => 'Not Found',
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        407 => 'Proxy Authentication Required',
        408 => 'Request Timeout',
        409 => 'Conflict',
        410 => 'Gone',
        411 => 'Length Required',
        412 => 'Precondition Failed',
        413 => 'Request Entity Too Large',
        414 => 'Request-URI Too Long',
        415 => 'Unsupported Media Type',
        416 => 'Requested Range Not Satisfiable',
        417 => 'Expectation Failed',
        500 => 'Internal Server Error',
        501 => 'Not Implemented',
        502 => 'Bad Gateway',
        503 => 'Service Unavailable',
        504 => 'Gateway Timeout',
        505 => 'HTTP Version Not Supported'
    );

    return (isset($codes[$status])) ? $codes[$status] : '';
}

// Helper method to send a HTTP response code/message
function sendAPIResponse($status = 200, $body = '', $content_type = 'text/html') {

    $status_header = 'HTTP/1.1 ' . $status . ' ' . getStatusCodeMessage($status);
    header($status_header);
    header('Content-type: ' . $content_type);


}

?>

If somebody gets the correct address:

http://www.myServer.com/api/v1.0/saveToken.php

would he be capable of sending a post request adding fake users and token IDs?

Shall I use an API key (not sure is the correct word) to "identify" the user?

$apiKey = $_REQUEST['apiKey'];
if(isset($apiKey)){

  if($apiKey == 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'){

  //then run the code

 }
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Please look into SQL injection and how to defend against them (prepared statements). Currently, your code is extremely vulnerable. And don't use mysql_ as it's deprecated for quite a while, use mysqli_ or pdo instead. \$\endgroup\$
    – tim
    Commented Apr 11, 2015 at 15:27

1 Answer 1

3
\$\begingroup\$

If somebody gets the correct address http://www.myServer.com/api/v1.0/saveToken.php, would he be capable to send a post request adding fake users and token ids?

Sure, why wouldn't an attacker be able to do that?

You can test this yourself, either by writing a short script, or using a plugin such as tamper data for firefox. Or, as you are using REQUEST instead of POST, just pass the values as GET.

So if you want to avoid this, you need some kind of authentication mechanism (and you obviously need to fix the SQL injection).

Other than the use of mysql_ which is deprecated for a long time, and the SQL injection, your PHP code looks good. I would probably move some of the code to it's own function (such as addUser, selectUser, addToken, etc) to make it even easier to read. And instead of setting the header and status message yourself you could use http_response_code.

\$\endgroup\$

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.