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
 }
asked Apr 11, 2015 at 15:11
\$\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\$ 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.

answered Apr 11, 2015 at 15:45
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.