-1

Hi We are facing a very critical issue with PHP. Actually i don't know whether it is PHP limitation or something else. We really need some expert advise. We are having a redirect application developed in PHP where we capture the variables of all incoming request and store it in database using system command.But Recently we have found for some records it is not able to capture the variable into the database though those variables are there in APACHE log file. Please advice what might be the problem, Because capturing variable is directly affecting business. Is it because of php system command limitation of not able to handle multiple request at a time? Ex.

dt.php?key=46232X&fh=E30103ERCQSM4WOZU61&id=ERCWOZU61

This is the normal pattern of incoming request. Code to capture source of incoming variable:

$query_string=$_SERVER['QUERY_STRING'];
 $referer=$_SERVER['HTTP_REFERER'];
 $uri=$_SERVER['REQUEST_URI'];

Apart from the above mentioned variable i can't put here but we are capturing all variables.

System Command which i am using

system("nohup php $folder_path/incoming-process.php $p_id $cd $query_string $referer $ipaddress $uid $vid $uri > /dev/null &");

incoming-process.php

ignore_user_abort(true);
set_time_limit(0);
error_reporting(0);

include_once('database.php');
$project_id =$_SERVER['argv'][1];
$cd=$_SERVER['argv'][2];
$query_string=$_SERVER['argv'][3];
$referer=$_SERVER['argv'][4];
$ipaddress=$_SERVER['argv'][5];
$user_id=$_SERVER['argv'][6];
$vendor_rule_id=$_SERVER['argv'][7];
$vendor_id=$_SERVER['argv'][8];
$uri=$_SERVER['argv'][9];

$uri=urldecode($uri);
$query_string=urldecode($query_string);
$ipaddress=urldecode($ipaddress);



 //inserting variables & other details into Vendor_incoming_Info                           

$url = $uri;
parse_str(parse_url($url, PHP_URL_QUERY), $parts);
$keys = array_keys($parts);
$total=substr_count($uri, '=');

$uri=mysql_real_escape_string($uri);

$insert_incoming_info="insert into Vendor_Incoming_Info( Vendor_Id,Variable_Name,Value,User_Id) VALUES";
 for($i=0;$i<$total;$i++){
     $var=$keys[$i];
     $value=$parts[$var];
     if($var!='cd'){
        $insert_incoming_info=$insert_incoming_info." ('$vendor_id','$var','$value','$user_id') ,";
     }

    }
$insert_incoming_info= substr($insert_incoming_info,0,-1);
    $insert_incoming_info=$insert_incoming_info." ;";    
    mysql_query($insert_incoming_info);
Ethen
  • 161
  • 3
  • 3
  • 16
  • 3
    How do you store it “using system command”? What system command? – Gumbo Jun 17 '14 at 18:17
  • Gumbo I have updated my question please see. – Ethen Jun 17 '14 at 18:26
  • Smells like [OS command injection](http://cwe.mitre.org/data/definitions/78.html) and maybe [SQL injection](http://cwe.mitre.org/data/definitions/89.html). Where do the variable values come from and how does *incoming-process.php* process them? – Gumbo Jun 17 '14 at 18:27
  • Echoing Gumbo, we'll need to see the code in `incoming-process.php` – Patrick Q Jun 17 '14 at 18:30
  • Yeah i have updated my question.Please check it – Ethen Jun 17 '14 at 18:34
  • And what about the source of the variable values before the `system` call? – Gumbo Jun 17 '14 at 18:38
  • By the way: you *are* vulnerable to SQL injection. You should read on [how to prevent them](http://stackoverflow.com/q/60174/53114). – Gumbo Jun 17 '14 at 18:41
  • … and you’re also vulnerable to OS command injection. – Gumbo Jun 17 '14 at 18:43
  • Thanks Gumbo. we are aware of both. Do you think is it happening because of that? Because in most cases it is working fine – Ethen Jun 17 '14 at 18:44
  • The `&` is a special character in Unix shells that makes the command run in background. The `&` delimits the command and anything following is handled as a new command. – Gumbo Jun 17 '14 at 18:48

1 Answers1

1

You are vulnerable to both OS command injection and SQL injection.

In both cases you fail to ensure that the values get interpreted as intended, i. e., as string parameters.

As for OS command parameters, use escapeshellarg, e. g.:

$args = array(
    "php",
    "$folder_path/incoming-process.php",
    $p_id,
    $cd,
    $query_string,
    $referer,
    $ipaddress,
    $uid,
    $vid,
    $uri,
);
$args = array_map("escapeshellarg", $args);
$args = implode(" ", $args);
system("nohup $args > /dev/null &");

As for the SQL parameter values, have a look at How can I prevent SQL-injection in PHP?

Community
  • 1
  • 1
Gumbo
  • 643,351
  • 109
  • 780
  • 844