0

首先,是的,我已经看到了这是否 PDO 准备好的语句足以防止 SQL 注入?,但这还不足以回答我的问题,因为我的做法不同。

假设我有这样的代码:

$userid = $_SESSION['data']['id'];
$query = "SELECT * FROM table WHERE userid='$userid'";
$action = $db->prepare($query);
$action->execute();

它在技术上是安全的,因为用户无法影响$userid,对吧?说我是否错了。

但是,如果代码如下所示:

$userid = $_GET['id'];
$query = "SELECT * FROM table WHERE userid='$userid'";
$action = $db->prepare($query);
$action->execute();

现在安全了吗?我找不到任何关于此的文档,可以让我在白底黑字。

4

3 回答 3

2

即使您使用过PDO,您的代码仍然容易受到攻击,SQL INjection因为您没有参数化查询,查询必须参数化才能清除值。

$userid = $_GET['id'];
$query = "SELECT * FROM table WHERE userid=?";
$db->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
$action = $db->prepare($query);
$action->bindParam(1, $userid);
$action->execute();
于 2013-03-10T11:45:13.623 回答
1

第二种说法不安全。

相反,你应该做类似的事情

$stmt = $db->prepare('SELECT * FROM table WHERE userid=:id');
$stmt->bindParam(':id', $userid);
$stmt->execute();

资源

于 2013-03-10T11:46:13.067 回答
0

这在技术上是安全的,因为用户不能影响 $userid,对吧?说我是否错了。

你错了。会话数据是外部数据,必须谨慎对待。这是因为:

  • SessionID 和 SessionName 直接随请求提供。这些值可以很容易地操作,以便将一些不同的数据放入应用程序的内存中。
  • 坚持。会话数据可以在持久层中修改,因此它始终有资格作为输入数据(!)。

您可能期望一个整数值,因此将其设为 1:

$userid = (int) $_SESSION['data']['id'];

特别是当您直接将变量替换为 SQL 查询时。

以后不要想它是否安全。考虑以安全的方式做事,这样即使您错过了另一层中的某些内容(例如通过会话输入),也不会破坏应用程序中的数据流。

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

...

$userid = (int) $_SESSION['data']['id'];

...

$query = "SELECT column FROM table WHERE userid = ?";

$stmt = $pdo->prepare($query);
$stmt->bindParam(1, $userid);
$stmt->execute();
于 2013-03-10T11:56:16.567 回答