0

我有一个已经运行了一段时间的站点,它使用大量用户输入来构建站点。网站上自然有几十种表格。在构建站点时,我经常使用隐藏的表单字段将数据传回服务器,以便我知道要更新哪条记录。

一个例子可能是: <input type="hidden" name="id" value="132" /> <input type="text" name="total_price" value="15.02" />

提交表单时,这些值会传递到服务器,然后我根据传递的数据更新记录(即记录 132 的价格将更改为 15.02)。

我最近发现你可以通过像萤火虫这样简单的东西来改变属性和值。所以...我打开 firebug 并将 id 值更改为“155”,将价格值更改为“0.00”,然后提交表单。中提琴!我在网站上查看产品编号 155,现在它说它是 0.00 美元。这让我很担心。

如果没有查询字符串(容易修改)或隐藏的输入元素将 id 传递给服务器,我如何知道要更新哪个记录?

如果没有更好的方法(我已经看到数以千计的网站以这种方式传递数据),那么我将如何做到这一点,以便如果用户更改这些值,服务器端的数据不会被执行(或其他东西类似解决问题)?

我曾考虑过加密 id 然后在另一边解密它,但这仍然不能保护我免受有人更改它并且碰巧得到与数据库中另一个 id 匹配的东西。

我也考虑过 cookie,但我听说它们也可以被操纵。

有任何想法吗?这对我来说似乎是一个巨大的安全风险。

4

2 回答 2

4

$_SERVER['HTTP_REFERER']通过执行以下操作检查敏感页面总是很好的:

if ($_SERVER['HTTP_REFERER'] !== "previous_page.php") {
 header("Location: error_page.php");
 session_destroy();
 exit;
}

但这并不是完全的证明,因为如果攻击者在 previous_page.php 上,他可以简单地浏览到我们试图保护的页面,因此需要进一步的保护。

您可以(并且应该)实施令牌系统。在您的表单页面上,您将添加以下 PHP 代码:

$_SESSION['token'] = md5(uniqid(rand(), TRUE));
$token = $_SESSION['token'];

在表格的某处,添加:

<input type="hidden" name="token" value="<?php echo $token; ?>"/>

这将生成一个漂亮的长字符串,该字符串对于浏览该页面的人来说是唯一的。这样做的目的是将此会话变量作为 $_POST 变量传递到下一页,然后在接收页面上将 与 进行比较$_POST$_SESSION确保它们彼此相等。这在接收页面上是这样完成的:

$token = $_SESSION['token']; //re declaring your session variable

if ($_POST['token'] !== $_SESSION['token']) {
 header("Location: error_page.php");
 session_destroy();
 exit;
}

我建议对“CSRF Forgery”进行更多研究。希望这能让你朝着正确的方向前进。

于 2012-04-05T23:52:20.730 回答
4

不要试图控制提交的数据(因为你不能)。

检查进行提交的用户是否有权进行它将触发的任何更改。

例如,如果他们将 id 更改为 155 并将价格更改为 0.00,那么请确保他们有权更新记录 155 并将价格设置为 0.00。

于 2012-04-05T23:19:09.317 回答