简体   繁体   中英

Single quote breaking echo in input using htmlentities & htmlspecialchars when serialized mysql in php

UPDATE: So I spent the day reading various posts on SQL injection and parameterized queries. I've come up with something that works and I think it's a reasonable update to my approach.

    $query = "UPDATE message_bundles SET bndName = ?, bndTagId = ?, bndSequence = ?, bndKeyboardArr = ? WHERE id = ?";

    $stmt = mysqli_prepare($connection, $query);
    mysqli_stmt_bind_param($stmt, 'siisi', $bnd_name, $bnd_tag_id, $bnd_sequence, $bnd_keyboard_arr, $id);
    $result = mysqli_stmt_execute($stmt);
    mysqli_stmt_close($stmt);

But, I still have the issue described in this original question. When I echo out the data, it's still breaking with the very first single quote it encounters; whether I use htmlspecialchars or htmlentities. Additional comments would be appreciated.


ORIGINAL: Normally when I save strings to MYSQL in PHP I run a function (below) that escapes quotes. I am doing the same thing but just after I serialize an array of strings before inserting into MYSQL. But when I retrieve the array and unsearialize it, only the first string with a single quote echo's inside an input field. Then the rest of the strings in the array won't echo.

Here is my loop through post to build array (note that the 3 values being added to an array are 1) string, 2) int, 3) string; maybe this is where my issue is):

foreach ($bnd_keyboard as $key) {
    if ($key['keyboard']) {
        $keyboard = $key['keyboard'];
        $target_bundle = $key['targetBundle'];
        $code_execute = $key['codeExecute'];
        $bnd_keyboard_arr["keyboards"][$keyboard] = array(
                "targetBundle" => $target_bundle,
                "codeExecute" => $code_execute          
            );
    }   
}

Then my function to escape quotes (note that it's an older function that might need to be updated, but hasn't caused me any issues until now):

function mysqli_prep($value) {
  global $connection;
  $magic_quotes_active = get_magic_quotes_gpc();
  $new_enough_php = function_exists("mysqli_real_escape_string"); // i.e. PHP >= v4.3.0
  if($new_enough_php) { // PHP v4.3.0 or higher
    // undo any magic quote effects so mysql_real_escape_string can do the work
    if($magic_quotes_active) {$value = stripslashes($value); }
    $value = mysqli_real_escape_string($connection, $value);
  } else { // before PHP v4.3.0
    // if magic quotes aren't already on then add slashes manually
    if(!$magic_quotes_active) {$value = addslashes($value); }
    // if magic quotes are active, then the slashes already exist
  }
  return $value;
}

Then I run this function on the array and serialize it:

$bnd_keyboard_arr = mysqli_prep(serialize($bnd_keyboard_arr));

Serialized data before insert into MYSQL looks like this:

a:1:{s:9:\"keyboards\";a:1:{s:5:\"aaa\'s\";a:2:{s:12:\"targetBundle\";s:2:\"93\";s:11:\"codeExecute\";s:3:\"aaa\";}}}

When I go to retrieve the data, unserialize it and echo into my page, If the 1st field (which is actually the KEY for an array within the array) has a quote, then it echo's ok, but then the next 2 values break and won't echo (either in a normal text echo, or within an input field).

If none of the 3 values have single quotes, then all 3 echo out properly inside the input's.

If the 3rd value has a single quote, then all three echo fine. Basically when my page encounters a single quote, even after htmlentites or htmlspecialchars is used, it breaks the rest of the values being echoed from the array.

I'm really stumped.

Well, I solved it. Good exercise for me though b/c it forced me to upgrade the way I send queries to MYSQL. I think that's way upgraded, although it turns out that had nothing to do with my original issue.

The problem, stupid as it always is, was this:

I was creating a htmlspecialchars string just fine like:

$keyboard = htmlspecialchars($keyboard, ENT_QUOTES);

Then I was grabbing a value from an array, except that used my $keyboard value like this:

$keyboard_arr = $bnd_keyboard_arr['keyboards'][$keyboard];

So of course if I was converting the $keyboard string using htmlspecialchars prior to inserting that string in my array key, well, it would break $keyboard_arr

The solution was to just move the $keyboard_arr = $bnd_keyboard_arr['keyboards'][$keyboard]; to one line after the $keyboard_arr = $bnd_keyboard_arr['keyboards'][$keyboard];

Yup. Like I said, JV.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM