动态查询和安全选项

时间:2011-10-22 13:49:04

标签: php mysql pdo sql-injection security

我已经制作了简单而精简的数据库层来帮助我正常运行。现在它正在发挥作用,我决定仔细审查它的安全性。第一个碰撞(with help of Mordred)是我的动态查询。通过针对固定正则表达式验证表变量,可以轻松解决表的第一个问题变量:

$regex = '/^[a-zA-Z0-9_$]+$/';

现在,清理/验证的下一个变量是列名称,AFAICS是我有两个选项。首先是检索该表中的所有列并构建白名单或再次使用regex来验证列变量。我的问题是,上述哪一种方法是可行的?对表名使用正则表达式验证是否合适?下面是我正在谈论的示例SQL字符串

$stmt= $this->conn->prepare("SELECT * FROM $table WHERE $id_col[0]=:id");            
$stmt->execute(array(":id"=>$id_val[0]));
$this->resultset = $stmt->fetch(PDO::FETCH_ASSOC);  

希望收到朋友们的回复(很抱歉,如果问题在某个地方得到解答。我找不到任何类似的东西!)

2 个答案:

答案 0 :(得分:1)

我所做的是创建一个脚本,扫描所有表并为表名和列创建白名单,然后我用它来验证任何应该是表/列名的用户输入,因为它们不会进入参数查询。其他任何东西都通过PDO Bind参数化了!

答案 1 :(得分:-1)

function escapeIdent($str) {
  return "`".str_replace("`","``",$str)."`";
}

但是,我建议不要从另一个答案中逃避和大量白名单。

白名单应该不是站点范围的,而是特定于它用于它的声明。

虽然用户提供的字段名称可能不包含注入代码,但无论如何它仍然存在一些危险。

比如说,如果攻击者设法用surname替换某个无害的字段名称(例如access level),那么他可以获得该网站的管理员权限。