一种在表单中存储表 ID 的有效方法,这样用户就无法覆盖另一个表记录

发布于 2024-09-07 05:07:36 字数 778 浏览 8 评论 0原文

我正在创建一个拥有用户帐户的网站。对于每个用户帐户,用户可以执行诸如更新个人详细信息、撰写博客等操作。 当用户想要编辑博客时,我有以下表单(这是一个简化版本)。

<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,该记录可能是其他人的条目。

我该如何防止这种情况? 到目前为止,我已经想到了两种方法,想知道您认为最好的想法是什么(或建议另一种方法)。

  1. 使用随机字符串对 ID 进行编码,然后在提交后对字符串进行解码,检索正确的 ID。
  2. 将其保留为数字,然后通过数据库查询检查以确保更新后其记录。

我显然想限制数据库查询,并且通过对 ID 进行编码,我认为这是更好的选择。你们觉得怎么样?

提前致谢

I am creating a website which has user accounts. For each user account, the user can do stuff like update their personal details, write a blog etc.
When the user wants to edit a blog, i have the following form (this is a simplied version).

<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>

Now the blogID as you can see is 4 for this user, so when they update the record, it'll update the blog table with ID 4. Now using firebug or other spoofing techniques, the user could change this ID to something like 8, and update record 8, which could be someone else's entry.

How do i prevent this?
I've thought of two methods so far, wondering what you think is the best idea (or suggest another).

  1. Encode the ID with a random string, then decode the string once submitted, retrieving the correct ID.
  2. Leaave it as the numeric number and then check to make sure once updated, its their record by a database query.

I obviously want to limit the database queries, and by encoding the ID i believe is the better option. What do you guys think?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

混吃等死 2024-09-14 05:07:36

在构建 Web 应用程序时,如果您假设以下情况,您将会感到最高兴:

  1. 客户端(即浏览器)不可信。假设发送到您服务器的任何数据都是由坏人发送的。

  2. 应用程序是无状态的。您不能仅仅因为您希望请求 X 在请求 Y 之前就假设它们以这种方式发生。

您的选项 2 是更好的选择。如果您需要经过身份验证的用户更新博客文章,并且需要授权用户执行此操作,请检查更新博客文章的代码中的这些要求。您可能不会遇到太多数据库查询的问题,如果有,您可以在出现时处理它。

When building a web application, you'll be happiest if you assume the following:

  1. the client (that is, the browser) is not to be trusted. Assume any data sent to your server has been sent by a bad guy.

  2. the application is stateless. You can't assume that just because you intended request X to be preceded by request Y that they occurred that way.

Your option 2 is the better choice. If you require an authenticated user to update a blog post, and you require the user to be authorized to do so, then check those requirements in the code that updates blog posts. You probably will not have an issue with too many db queries, and if you do, you can deal with it when you do.

愛放△進行李 2024-09-14 05:07:36

在 HTML 级别上做任何事情都是浪费时间。 PHP 根本不应该允许这样做,即检查该条目是否确实属于发出更改的用户。

Doing anything on HTML level is a waste time. PHP simply shouldn't be allowing this, aka checking if the entry actually belongs to the user issuing the change.

浅浅 2024-09-14 05:07:36

有很多方法可以解决这个问题,其中一些是:

  1. 将秘密字符串与 id 一起哈希(sha1 或类似),在提交时验证哈希。如果不匹配,则拒绝。

  2. 在提交时将用户有权访问的所有博客存储在会话变量中,检查提交的博客是否在会话数组中,如果没有则拒绝。

  3. 既然您说过要限制数据库查询,那么您可以在更新查询中附加另一个条件。实际的查询当然取决于您的数据库架构。

    更新博客 SET ... 剪断 ... WHERE BLOG id = FORM_SUBMITTED_ID AND blog.owner = CURRENT_USER

    这将确保仅当用户是实际所有者时才会进行更新。

There are many ways to approach this, some of them being:

  1. Hash (sha1 or similar) a secret string along with the id, on submit verify the hash. If it doesn't match, reject.

  2. Store all blogs user has access to in a session var, upon submit check if the submitted blog is in the session array, if not reject.

  3. Since you said you wanted to limit db queries, you could just append another where criterion to your update query. The actual query will of course depend on your db schema.

    UPDATE blogs SET ... snip ... WHERE BLOG id = FORM_SUBMITTED_ID AND blog.owner = CURRENT_USER

    This will make sure the update happens only if the user is the actual owner.

放我走吧 2024-09-14 05:07:36

Ned Batchelder 的回答包含一些非常重要的事情需要记住,我不会重复。

我将概述一些更多的实施细节。

假设:

  • 博客表有一列名为ownerId,它保存拥有/创建该帖子的用户的userId。
  • 你有某种用户登录系统,并且有一个 userId 存储在会话中的某处。

确保用户只更新自己的帖子的最简单方法是提前检查:

<?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 条件将匹配零条记录。

Ned Batchelder's answer contains some very important things to remember, I won't repeat them.

I will outline some more implementation details.

Assumptions:

  • The blog table has a column called ownerId, which holds the userId of whichever user owns/created the post.
  • You have some sort of user login system, and have a userId stored in session somewhere.

The simplest way to ensure user's only update their own posts is to simply check beforehand:

<?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.

If you really don't want pull the blog post from the database before updating it, for whatever reason, you could always do something like this:

<?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);

This saves you the initial lookup, but basically fails silently if the current user doesn't own the blog, since the WHERE condition will match zero records.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文