dongsu1951 2012-04-07 12:55 采纳率: 0%
浏览 45
已采纳

自动完成撇号和注射攻击

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 = "{
";
$code .= "query:'" . $get . "',
";
$code .= "suggestions:[" . $resString . "],
";
$code .= "data:[" . $idString . "]
";
$code .= "}";
echo $code;
  • 写回答

1条回答 默认 最新

  • dqq48152418 2012-04-07 13:27
    关注

    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...
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 我想在一个软件里添加一个优惠弹窗,应该怎么写代码
  • ¥15 fluent的在模拟压强时使用希望得到一些建议
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流