autocomplete apostrophe AND injection attack

I'm having difficulties passing an apostrophe into my autocomplete. The database contains entries that do not have apostrophes...instead the html equivalent is being used (&POUND039;). I'm still very new to ajax so I really appreciate the help. The question is, how do I pass in the value of an apostrophe and have it match? Also, is my code susceptible to an injection attack? Thanks in advance for your help!

The code is like this:

<script type="text/javascript">
var options = {
        serviceUrl:'autocomplete/autoQuery.php',
            minChars:2, 
            delimiter: /(,|;)\s*/, // regex or character
            maxHeight:400,
            width:500,
            zIndex: 9999,
            deferRequestBy: 0, //miliseconds
            params: { country:'Yes' }, //aditional parameters
            noCache: false, //default is false, set to true to disable caching
            // callback function:
            // onSelect: function(value, data){ alert('You selected: ' + value + ', ' + data); },
            onSelect: function(value, data){ window.location = "textbooks.php?bk=" + data;}
    }; 
$('#query').autocomplete(options);
</script>

I have a php script sending back the query results. The page is called query.php and the code there is this:

$get = htmlentities($_GET['query']);
$query = "SELECT title,author,id,isbn10,isbn13 FROM textbook
        WHERE title LIKE '%" . $get . "%'
        OR author LIKE '" . $get . "%'
        OR isbn10 LIKE '" . $get . "%'
        OR isbn13 LIKE '" . $get . "%'
        LIMIT 5
        ";
$result = mysql_query($query,$connection);
if(mysql_num_rows($result) == 0){
$resString = "'No result found. Click here',";
$idString = "'unknown',";
}else{
$resString = "";
$idString = "";
while($data = mysql_fetch_array($result)){
    $resString .= "'" . $data['title'] . " by " . $data['author'] . "',";
    $idString .= "'" . $data['id'] . "',";
}   
}

$resString = rtrim($resString, ',');
$idString = rtrim($idString, ',');
$code = "{\n";
$code .= "query:'" . $get . "',\n";
$code .= "suggestions:[" . $resString . "],\n";
$code .= "data:[" . $idString . "]\n";
$code .= "}";
echo $code;

Answers


Your script as it is, is vulnerable to SQL injection since $get is used unescaped. htmlentities() the way you have it won't encode quotes.

Fix the data first:

It is not recommended to store encoded values in the database (especially not weirdly encoded ones like &POUND039). So the first thing I would suggest is to replace those values in your database with actual apostrophes.

UPDATE textbook 
SET 
  title = REPLACE(title, '&POUND039', '\''),
  author = REPLACE(author, '&POUND039', '\''),
  etc...

Then instead of using htmlentities() (which by the way doesn't encode quotes unless you pass the ENT_QUOTES constant, pass in a properly escaped string $get, which will match the regular single quotes in your database. Note, there are additional issues with escaping a string containing literal % and _ to be used in a LIKE statement, so this is only the bare minimum of what can be done.

$get = mysql_real_escape_string($_GET['query']);
$query = "SELECT title,author,id,isbn10,isbn13 FROM textbook
        WHERE title LIKE '%" . $get . "%'
        OR author LIKE '" . $get . "%'
        OR isbn10 LIKE '" . $get . "%'
        OR isbn13 LIKE '" . $get . "%'
        LIMIT 5
        ";
The real solution:

However, as suggested in comments, this would all work much more smoothly and without worry of injection if you use PDO and bound parameters:

// PDO connection information omitted...
$query = "SELECT title,author,id,isbn10,isbn13 FROM textbook
        WHERE title LIKE CONCAT('%', :get, '%')
        OR author LIKE CONCAT(:get, '%')
        OR isbn10 LIKE CONCAT(:get, '%')
        OR isbn13 LIKE CONCAT(:get, '%')
        LIMIT 5
        ";

$stmt = $db->prepare($query);
$stmt->execute(array(':get', $_GET['query']);
while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
  $resString .= "'" . $data['title'] . " by " . $data['author'] . "',";
  $idString .= "'" . $data['id'] . "',";
}
// etc...

Need Your Help

Display Image after drag and drop on html page

javascript jquery html drag-and-drop

I am implementing Drag and Drop Images Control using JQuery/JS. What has been accomplished is that user drag some image file and drop into html page. After dropping file, I only show filename and its

Can array members be initialized self-referentially?

c++ c++11 array-initialization member-initialization

Consider the following code in which we initialize part of D based on another part of D: