我是否正确消毒/逃生?

时间:2013-04-21 17:46:11

标签: php mysql input output mysql-real-escape-string

我在PHP中创建了一个简单的搜索脚本,用于搜索mySQL数据库并输出结果。这是如何工作的:

  • 用户搜索" jack""通过搜索表单。
  • 我的PHP脚本GET进行了此搜索,并对其进行了清理。
  • 然后,使用SELECTLIKE的脚本会获得结果。
  • 然后脚本将结果输出给用户。
  • 最后,该脚本告诉用户" jack&#s;返回x结果。"在逃避的帮助下。

我想问的是,我做得对吗?

这是我在SELECTING之前从数据库中清理的方法:

if(isset($_GET['q'])){
  if(strlen(trim($_GET['q'])) >= 2){
    $q = trim(mysql_real_escape_string(addcslashes($_GET['q'], '%_')));
    $sql = "SELECT name, age, address FROM book WHERE name LIKE '%".$q."%'";
  }
}

这就是我在输出" jack返回的x结果之前逃脱的方式。":

echo htmlspecialchars(stripslashes($q)) . " returned x results.";

这是正确的方法吗?

顺便说一句,我知道PDO和mySQLi是首选的,因为他们通过使用准备好的语句来消毒自己,但我对它们没有任何实际经验。但我很乐意看看,如果你们可以链接我一些新手教程/解释。 此外,我听说magic_quotescharset可能会以某种方式导致注射 - 这是正确的吗?

1 个答案:

答案 0 :(得分:0)

出于某种原因,我们也需要escape a backslash 所以,正确的代码是,我相信

if(isset($_GET['q'])){
  $_GET['q'] = trim($_GET['q']);
  if(strlen($_GET['q']) >= 2){
    $q = $_GET['q'];
    $q = '%'.addCslashes($q, '\%_').'%';
    // now we have the value ready either for escaping or binding
    $q = mysql_real_escape_string($q);
    $sql = "SELECT name, age, address FROM book WHERE name LIKE '$q'";
    //or 
    $sql = "SELECT name, age, address FROM book WHERE name LIKE ?";
    $stm = $pdo->prepare($sql);
    $stm->execute(array($q));
    $data = $stm->fetchAll();
  }
}

对于输出,请使用

echo htmlspecialchars($_GET['q']);

这里不需要striplashes。

  

此外,我听说magic_quotes和charset可能以某种方式导致注射 - 这是正确的吗?

如果你不使用它们,魔法引号不会损害你的安全。
在一些非常罕见的编码的情况下,charset是危险的,但只有在设置不当的情况下。如果mysql(i)_set_charset或DSN(如果是PDO)用于此目的 - 您再次安全。

至于PDO,tag wiki应该足够首发,我相信