哈克准备声明(先读)

时间:2013-09-05 03:16:10

标签: php mysql pdo sql-injection

我有这段代码:

<?php
$table = $_GET ["table"];
$query = "SELECT 1 FROM $table";
$st = $pdo->prepare($query);
$st->execute();

这不是真正的代码,但它是一个实现这个想法的例子。

如果我做:

hacked.php?table=users;DROP TABLE users;

它会起作用,因为它没有被正确转义。

但是,如果我想更新这样的信息:

hacked.php?table=users; UPDATE users SET name="abc" WHERE name="def";

它不起作用,因为它被转义,pdo会将查询转换为

SELECT 1 FROM users; UPDATE users SET name=\"abc\" WHERE name=\"def\";

显然它失败了。

无论如何都可以使这个查询有效吗?

编辑1

我们团队中只有一个人专门检查我的代码并将其破解。所以我想做好准备,如果这可以通过某种方式完成。

编辑2

我已经读过这个:Are PDO prepared statements sufficient to prevent SQL injection?但它确实没有回答我的问题。然而它给了我一个通过的方法。 @duskwuff的解决方案和我来的一样。因此,对于管理员来说,如果这应该删除或标记为重复是可以的。但我坚持认为,这对于有人知道pdo如何准备被黑客攻击是有帮助的。

2 个答案:

答案 0 :(得分:3)

我认为你问的是错误的问题。如果你的代码甚至与此类似,那么你编写代码的方式就会遇到很大的问题...而且你可能正在构思你需要解决的问题,或者你是从一个非常糟糕的设计工作。

如果由于某种原因,您需要在URL查询字符串或http帖子中传递数据库的设计,并且由于某种原因,您认为执行未转义的查询是接近你需要的......然后你正在做什么,you're doing it wrong

如果,通过某些远程机会,您实际上需要将表的名称传递给网页,那么您必须做的是将输入值与某种静态结构进行比较以查看是否输入value在列表中...然后使用列表中的值,或者从静态的东西,从不使用输入。

简单地说,像下面这样原始的东西将是一种非常优越的方法,尽管如果表名,列名或任何数据库内部需要进入浏览器领域,这可能是一个糟糕的设计。

$table = $_GET ["table"];
IF ($table == "users")
{
   $query = "SELECT 1 FROM users;"
}
ELSEIF ($table == "points")
{
   $query = "SELECT 1 FROM points;"
}  

...

答案 1 :(得分:2)

  

它不起作用,因为它被转义,pdo会将查询转换为

SELECT 1 FROM users; UPDATE users SET name=\"abc\" WHERE name=\"def\";

这是不正确的! PDO不会对插入到查询中的文本执行转义,因为它无法识别插入的文本。您所看到的是PHP已弃用magic_quotes功能的结果,该功能在请求变量的内容中添加反斜杠(如$_GET$_POST)。即使启用了此功能,也可以通过使用非引用结构(例如:

)在类似查询中避免琐事
SELECT 1 FROM users; UPDATE users SET name = CHAR(97,98,99) WHERE name = CHAR(100,101,102)

CHAR()是一个MySQL函数,它从字符代码值列表构造一个字符串。如果你正在使用其他数据库,则可能存在等效函数。)

将非转义内容直接插入查询从不安全。不要这样做。