Log in

View Full Version : PHP Serializing



connor4312
05-31-2011, 06:03 PM
Hi,

So long story short, I have one page containing the following code:

function mysql_remote_query($sql, $link=""){
$ch=curl_init("seekrit url"); //Replaced for the forums
$key="password";
$post="sql=".urlencode(base64_encode(serialize($sql)))."&key=".$key;
curl_setopt($ch, CURLOPT_POST ,1);
curl_setopt($ch, CURLOPT_POSTFIELDS ,$post);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,1);
curl_setopt($ch, CURLOPT_HEADER ,0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER ,1);
$result = trim(curl_exec($ch));
if (strpos($result, 'ERROR')===false) {
$result=unserialize($result);
if ($result=='false'){
return false;
} else {
return $result;
}
} else {
die ("\n\n".$result."\n\n");
}
return $result;
}
to communicate with

<?php
if (isset($_POST['key'])){
if ($_POST['key']=="dASKmtDSosw"){
if (isset($_POST['sql'])){
mysql_connect('localhost', 'tppusr_index', 'password');
mysql_select_db('tppusr_tpp');
mysql_query("SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'");
$sqls=unserialize(base64_decode($_POST['sql']));
if (!is_array($sqls)){
$out=db_exec($sqls);
} else{
$out=array();
foreach ($sqls as $sql){
$out[]=db_exec($sql);
}
}
echo serialize($out);
mysql_close();
}
}
}
function db_exec($sql){
$result=mysql_query($sql) or die("ERROR: ".mysql_error()."\n\n".print_r($sql));
if ($result!==true){
if (mysql_num_rows($result)==0){
return "false";
} else {
$out=array();
while ($row=mysql_fetch_assoc($result)){
$out[]=$row;
}
return $out;
}
} else {
return "true";
}
}
?>

Now, that's fine, but when I tried to read a returned array using mysql_fetch_array, it yells at me saying "supplied argument is not a valid MySQL result resource" The queries themselves are correct and have worked before.

Any help?
Thanks,
Connor

traq
05-31-2011, 07:45 PM
i haven't worked with CURL, but i notice that when you prepare the post, you serialize first and base64encode second; but when you read the post you try to unserialize first. since the last thing you did was base64encode, I suspect you'd need to decode it before you could unserialize.

To figure out the problem with the query, try printing out mysql_error(); after your query.

midhul
06-01-2011, 04:47 AM
$sqls=unserialize(base64_decode($_POST['sql']));
I believe he did decode it

traq
06-01-2011, 05:15 AM
I'm referring to the order of operations:

urlencode(base64_encode(serialize($encodethis))) is not the same as base64_encode(urlencode(serialize($encodethis))).

Likewise, when you decode, unserialize(urldecode(base64_decode($decodethis))) is not the same as unserialize(base64_decode(urldecode($decodethis))).

in order to decode something that's been encoded twice, you need to decode in the opposite order: i.e., if you encode in A->B->C order, you must decode in C->B->A order (not B->C->A order, as shown in the original post).



$sql = 'Some + Value';
// (note I included a character that will be affected by urlencode();
// otherwise, you might get a misleading "True" result from this test)

$urlencoded = urlencode(base64_encode(serialize($sql)));

if( $sql === unserialize(urldecode(base64_decode($urlencoded))) ){ print 'True'; }else{ print 'False'; }
// prints "False"

if( $sql === unserialize(base64_decode(urldecode($urlencoded))) ){ print 'True'; }else{ print 'False'; }
// prints "True"

// NOW, try it the other way:

$base64 = base64_encode(urlencode(serialize($sql)));

if( $sql === unserialize(urldecode(base64_decode($base64))) ){ print 'True'; }else{ print 'False'; }
// prints "True"

if( $sql === unserialize(base64_decode(urldecode($base64))) ){ print 'True'; }else{ print 'False'; }
// prints "False"

// as you can see, the results switch.



Actually, there's no urldecode() at all. That may be the problem, too (as I said, I don't use cURL much; if this is done somewhere else along the line please LMK)

SO, unserialize(base64_decode()) is appropriate to base64_encode(serialize())
BUT is not appropriate to urlencode(base64_encode(serialize()))

In any case, thanks, midhul, for getting me to take a second look.



Connor,

What line gives you that error? place print mysql_error(); on the line after and let us know what it tells you.