我正在创建一个拥有用户帐户的网站。对于每个用户帐户,用户可以执行更新其个人详细信息,撰写博客等内容。 当用户想要编辑博客时,我有以下表格(这是一个简化的版本)。
<form action="goToThisPage.php" method="get">
<input type="hidden" name="blogID" value="4" />
<input type="text" name="blogTitle" value="" />
<textarea name="blogContent"></textarea>
<input type="submit" name="submit" value="Update Blog" />
</form>
现在你可以看到这个用户的blogID是4,所以当他们更新记录时,它会更新ID为4的博客表。现在使用firebug或其他欺骗技术,用户可以将此ID更改为某些内容像8,更新记录8,这可能是别人的条目。
我如何防止这种情况? 到目前为止,我已经想到了两种方法,想知道你认为最好的想法(或建议另一种方法)。
我显然想限制数据库查询,并通过编码ID我相信是更好的选择。你们有什么感想?
提前致谢
答案 0 :(得分:2)
构建Web应用程序时,如果您采取以下措施,您将会感到最开心:
客户端(即浏览器)不受信任。假设发送到您服务器的任何数据都是由坏人发送的。
该应用程序是无状态的。您不能认为仅仅是因为您打算请求X在请求Y之前,它们就是这样发生的。
您的选项2是更好的选择。如果您需要经过身份验证的用户更新博客帖子,并且您需要授权用户执行此操作,请在更新博客帖子的代码中检查这些要求。您可能不会遇到太多数据库查询的问题,如果这样做,您可以在执行时处理它。
答案 1 :(得分:0)
在HTML级别上做任何事都是浪费时间。 PHP根本不应该允许这个,也就是检查条目是否实际属于发出更改的用户。
答案 2 :(得分:0)
有很多方法可以解决这个问题,其中一些方法是:
散列(sha1或类似)一个秘密字符串以及id,在提交时验证散列。如果不匹配,请拒绝。
将用户有权访问的所有博客存储在会话var中,提交时检查提交的博客是否在会话数组中,如果不是拒绝。
由于您说要限制数据库查询,因此您可以在更新查询中添加另一个where条件。实际查询当然取决于您的数据库模式。
UPDATE blogs SET ... snip ... WHERE BLOG id = FORM_SUBMITTED_ID AND blog.owner = CURRENT_USER
这将确保仅在用户是实际所有者时才进行更新。
答案 3 :(得分:0)
Ned Batchelder的回答包含一些非常重要的事情需要记住,我不再重复了。
我将概述更多实施细节。
假设:
确保用户仅更新自己帖子的最简单方法是事先简单检查:
<?PHP
$blog = get_blog_by_id($_POST['blogId']);
if ($blog['ownerId'] != $_SESSION['userId']){
die("You're a BAD MAN. Cut it out!");
}
$blog['blogContent'] = $_POST['blogContent'];
$blog['blogTitle'] = $_POST['blogTitle'];
update_blog($blog); //escapes any strings, and runs an update.
如果您真的不想在更新之前从数据库中提取博客文章,无论出于何种原因,您可以随时执行以下操作:
<?PHP
$title = mysql_real_escape_string($_POST['blogTitle']);
$content = mysql_real_escape_string($_POST['blogContent']);
$id = mysql_real_escape_string($_POST['blogId']);
$userId = $_SESSION['userId'];
$sql = "UPDATE blog SET blogTitle='$title', blogContent='$content' WHERE blogId = '$id' AND ownerId = $user_id";
mysql_query($sql);
这可以节省初始查找,但如果当前用户不拥有博客,则基本上会无声地失败,因为WHERE条件将匹配零记录。