我是否正确地消毒/逃生?


Do I sanitize/escape correctly?

我用PHP编写了一个简单的搜索脚本,用于搜索mySQL数据库并输出结果。其工作原理如下:

  • 用户通过搜索表单搜索"jack’s"。
  • 我的PHP-script GET的这个搜索,并消毒它。
  • 然后脚本使用SELECTLIKE得到结果。
  • 脚本然后输出结果给用户。
  • 最后,脚本通过转义告诉用户"jack's returned x results."

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

这是我如何从数据库中清理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's returned x results"之前的转义方式。:

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

这是正确的做法吗?

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

由于某些原因,我们也需要转义反斜杠。
所以,正确的代码应该是

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']);

这里不需要横杠。

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

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

对于PDO来说,一个标签wiki应该足够了,我相信