1

i have an android app, that connects to a remote DB with PHP. OK, i have it done and working, but i need something special.

I need to pass one parameter more to each PHP, and in the PHP code, i need to check if this extra parameter is equal to this word "sea", and only if it is equal, my php will do the remote DB querys. ¿why i want to do this? to make more safe my php codes, because they can be accesed by internet, but i want to add this extra parameter to certificate that only my app will do querys to the DB, because only my app knows this extra parameter "sea".

but i dont know how to do it, because my skills on PHP are null (the phps of my app are done by a friend)

can someone complete my code with the check i need? the parameter name will be "app_password" and the correct value of the parameter will be "sea"

this is my php code where i need the comprobation:

<?php

$link =mysql_connect(("theip","theuser","thepass"););
mysql_select_db("pervasive_locations", $link );

$q=mysql_query("Delete From permission Where 
fk_email1='".$_REQUEST['email1']."' and 
fk_email2='".$_REQUEST['email2']."'",$link );


while($e=mysql_fetch_assoc($q))
        $output[]=$e;

print(json_encode($output));

mysql_close($link);

?>
NullPointerException
  • 36,107
  • 79
  • 222
  • 382
  • Slightly off topic, but you **really** need to use **mysql_real_escape_string** around all un-trusted variables in SQL statements. Otherwise your code will be susceptible to SQL injection attacks. For a discussion of this and other related topics, see the existing [Best way to stop SQL Injection in PHP](http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php) question. – John Parker Jan 20 '11 at 12:12
  • i'm using it on the PHPs that have parameters that can be inserted by the user, but in this case, this PHP is called only by the java code and the user can't write nothing. ¿it is vulnerable to SQL injection if the user can't write nothing in this php? – NullPointerException Jan 20 '11 at 12:27
  • If the above code is on the internet, it's only a matter of time before the URL is discovered. As such, you need to be sure that it doesn't suffer from SQL injection. (It's trivial to fix, that said.) – John Parker Jan 20 '11 at 12:32

6 Answers6

2

More secure by kinda limiting MYSQL injection ...

i recomment using $_POST or $_GET instead of $_REQUEST ($_POST is more secure but you have to modify your app to do POST requests instead of GET)

<?php
if ($_REQUEST["app_password"]=='sea'){
$link =mysql_connect('localhost','database_user','database_password');
mysql_select_db("pervasive_locations", $link );

$email1=$var=str_replace('"','&quot;',$_REQUEST['email1']);
$email1=str_replace("'",'&#039;',$email1);

$email2=$var=str_replace('"','&quot;',$_REQUEST['email2']);
$email2=str_replace("'",'&#039;',$email2);  

$q=mysql_query("Delete From permission Where fk_email1='$email1' and fk_email2='email2'",$link );


while($e=mysql_fetch_assoc($q))
        $output[]=$e;

print(json_encode($output));

mysql_close($link);

}//end if
?>
Rami Dabain
  • 4,709
  • 12
  • 62
  • 106
  • I don't think that using $_REQUEST is a good idea though - it's a bit too generic. You should be specifying exactly which request type you'll be receiving (for some partial security) - $_POST / $_GET / $_COOKIE – xil3 Jan 20 '11 at 12:07
2

If you mean pass the parameter to the PHP by the url, you can fetch it from the $_GET superglobal. For example, if the parameter is named 'param':

if(isset($_GET['param']) && $_GET['param'] == 'sea') {
   // rest of your code
}
mrbellek
  • 2,300
  • 16
  • 20
2

3 tier answer....

Part 1

The solution you need is to check the query string parameters on the call, something like this:

if ($_GET['app_password'] == 'sea')
{
    .... Do your DB query ....
}

This would work if you called:

http://www.mysite.com/dodbquery.php?app_password=sea

but would not work if you called

http://www.mysite.com/dodbquery.php?app_password=air
http://www.mysite.com/dodbquery.php
http://www.mysite.com/dodbquery.php?foobar=sea

Part 2 - Possibly the more important part

The 'solution' above is all well and good, however this is not going to give you any real security - the URL can be seen, and therefore reused, by any intermediary (between the mobile device and your webserver).

The same would apply if you used post instead of get, any intermediary would be able to see the content of the post and therefore replay it.

There are a myriad potential solutions, the simplest IMHO (without reworking scripts etc) is to use post to pass the "password" and do this over SSL. This means that only the client and the server get to see the plaintext post data and therefore an intermediary cannot see your 'secret' key. As an added bonus you could do time sensitive secret keys, so from 1am to 2am you use 'pass1', 2am to 3am you use 'pass2' etc etc. You could also use something similar for the actual key as well (i.e. app_password)

You could also check that the device making the call is a mobile device, easily spoofable though.

Part 3 - Definately the more important part

The code sample you posted above is vunerable to SQL injection. In summary this means that somebody could inject additional SQL (i.e. drop table my_really_important)table) into your code and this would be executed without question. You should always verify the inputs to the script to ensure that somebody isn't attempting to 'hack' your script. As an example your script seems to indicate that the remote inputs are email addresses. So your code should verify that these are indeed email address. For example:

$email1Valid = VerifyEmail($_REQUEST['email1']); 
$email2Valid = VerifyEmail($_REQUEST['email2']);

if ((!$email1Valid) || (!$email2Valid))
{
    ...abort as emails are not valid...
}
else if ($_GET['app_password'] == 'sea')
{
     .... Do your DB query (and SQL escape the input emails)  .... 
} 
else
{
    .... Abort as your secret password was not passed correctly .... 
}

function VerifyEmail($email)
{
    return (!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email))
} 

More information on SQL injection can be found here:

http://php.net/manual/en/security.database.sql-injection.php

MrEyes
  • 13,059
  • 10
  • 48
  • 68
  • any intermediary? who can see wich php urls and parameters are sending the internal code of my android app? – NullPointerException Jan 20 '11 at 12:13
  • +1 Good detail and mentions SQL injection. (For future reference, there's a good resource here on SO in the form of the [Best way to stop SQL Injection in PHP](http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php) question.) – John Parker Jan 20 '11 at 12:27
  • When you "call" a website you don't make a direct connection to the server, your request goes through many many different nodes. So "Any intermediary" is any system between your mobile user and your server, so that could be an ISP, router, switch etc – MrEyes Jan 20 '11 at 12:28
  • also another question: i'm protecting for SQL injection only on the PHPs that have parameters that can be inserted by the user, but in this case, this PHP is called only by the java code and the user can't write nothing. ¿it is vulnerable to SQL injection if the user can't write nothing in this php? – NullPointerException Jan 20 '11 at 12:28
  • It won't be vunerable from your app as the user doesn't have access to the code that is making the call. However the script is on the internet so it could be called by anybody from anywhere with an internet connection. This is where your injection could come from. – MrEyes Jan 20 '11 at 12:30
0

Assuming I understand what you need, you could do this:

<?php

// assuming you're posting, but you can change it to $_GET['app_password] if you're not
$pass = $_POST['app_password'];

if($pass == 'sea') {
  $link =mysql_connect(("theip","theuser","thepass"););
  mysql_select_db("pervasive_locations", $link );

  $q=mysql_query("Delete From permission Where 
  fk_email1='".$_REQUEST['email1']."' and 
  fk_email2='".$_REQUEST['email2']."'",$link );


  while($e=mysql_fetch_assoc($q))
        $output[]=$e;

  print(json_encode($output));

  mysql_close($link);
}
?>
xil3
  • 16,305
  • 8
  • 63
  • 97
0

Quite Easy man,

you need to use a control structure, if in this case

<?php

/* Here you start the if condition to verify the parameter 
   First, you need to GET your value */

$param = $_GET['app_password'];
if ($param == 'sea') {



$link =mysql_connect(("theip","theuser","thepass"););
mysql_select_db("pervasive_locations", $link );

$q=mysql_query("Delete From permission Where 
fk_email1='".$_REQUEST['email1']."' and 
fk_email2='".$_REQUEST['email2']."'",$link );


while($e=mysql_fetch_assoc($q))
        $output[]=$e;

print(json_encode($output));

mysql_close($link);


}  /* Here you close your IF statement. */

?>
devasia2112
  • 5,844
  • 6
  • 36
  • 56
0

if you passing by $_GET:

if ( isset ( $_GET ['secret_word'] ) && $_GET ['secret_word'] == 'sea') {
    // your code 
} 

or if you passing by $_POST ( most save from all three )

if ( isset ( $_POST ['secret_word'] ) && $_POST ['secret_word'] == 'sea') {
    // your code 
} 

or

if ( isset ( $_REQUEST ['secret_word'] ) && $_REQUEST ['secret_word'] == 'sea') {
    // your code 
} 

and go to http://php.net/manual/en/security.database.sql-injection.php to read about SQL injection, because your code is like open Pandora Box

bensiu
  • 24,660
  • 56
  • 77
  • 117