使用 GET 执行数据库操作的快速、简单且安全的方法

发布于 2024-08-28 15:42:23 字数 678 浏览 5 评论 0原文

我确信这里有一个方法/最佳实践问题已经得到解决,但我无法根据我输入的模糊搜索词找到解决方案。

我知道以“快速而简单”开始这个问题可能会引起一些叹息,所以我很抱歉。

这是交易。

我有一个登录区域,管理员可以在其中执行一系列 POST 操作来输入与其个人资料相关的数据。我的数据结构方式非常独特,并且在大多数表中都进行了很好的分段,因为它与管理员的 ID 相关。

现在,我有一个表,将一种类型的数据转储到其中,并通过为每条记录分配 ADMIN 的唯一 ID 来区分这些数据。换句话说,所有 ADMIN 都向该表写入这种类型的数据。我只是通过每条记录的 ADMIN ID 来区分。

计划让管理员通过单击带有查询字符串的链接来删除这些记录 - 显然是使用 GET。显然,查询结构位于链接中,因此任何登录的管理员都可以利用该 URL 并删除竞争对手的记录。

这是通过 POST 安全执行此操作的唯一方法,还是我应该传递包含密码的会话信息并根据请求删除的 ADMIN ID 对其进行验证?

这对我来说显然是更多的工作。

正如他们在我曾经工作过的汽车维修行业所说的那样……工作有 3 种方法:快、好、便宜。您一次只能拥有两个。又快又便宜就不好了。又好又便宜的周转速度不会很快。又快又好并不便宜。哈哈,

我想这也适用于这里……永远不可能同时拥有快速、简单和安全;)

提前致谢……

Sort of a methods/best practices question here that I am sure has been addressed, yet I can't find a solution based on the vague search terms I enter.

I know starting off the question with "Fast and easy" will probably draw out a few sighs, so my apologies.

Here is the deal.

I have a logged in area where an ADMIN can do a whole host of POST operations to input data relating to their profile. The way I have data structured is pretty distinct and well segmented in most tables as it relates to the ID of the admin.

Now, I have a table where I dump one type of data into and differentiate this data by assigning the ADMIN's unique ID to each record. In other words, all ADMINs have this one type of data writing to this table. I just differentiate by the ADMIN ID with each record.

I was planning on letting the ADMIN remove these records by clicking on a link with a query string - obviously using GET. Obviously, the query structure is in the link so any logged in admin could then exploit the URL and delete a competitor's records.

Is the only way to safely do this through POST or should I pass through the session info that includes password and validate it against the ADMIN ID that is requesting the delete?

This is obviously much more work for me.

As they said in the auto repair biz I used to work in... there are 3 ways to do a job: Fast, Good, and Cheap. You can only have two at a time. Fast and cheap will not be good. Good and cheap will not have fast turnaround. Fast and good will NOT be cheap. haha

I guess that applies here... can never have Fast, Easy and Secure all at once ;)

Thanks in advance...

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

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

发布评论

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

评论(3

椒妓 2024-09-04 15:42:23

作为一般规则,任何更改状态(无论是会话状态还是数据库状态)的操作都应使用 POST。这意味着您可以使用 GET 执行的唯一“安全”SQL 操作是 SELECT。即使您只使用后端管理功能,也不应该使用 get。想象一下,重新打开浏览器,发现上次关闭 Firefox 是在“删除所有内容”GET->删除页面,导致所有内容再次被删除。

这样做的主要原因之一是防止跨站点请求伪造。例如,如果您有一个采用 GET 变量的页面,例如 http://example.com/account ?action=logout,攻击者可以在您的网站上发布图像,如下所示:

<img src="http://example.com/account?action=logout" />

任何打开包含该图像标签的页面的人都会立即注销,即使他们是管理员。然后在原始数据库中搜索该数据并将其删除会非常烦人。

尽管 POST 操作“几乎”很容易伪造,但作为任何 Web 安全问题的一般规则,权衡是速度/简单性与安全性,因此您必须选择其中之一。

As a general rule, any operation that alters state (whether its session state, or database state) should use POST. That means the only 'safe' SQL operation you can perform with GET is SELECT. Even if you're only using a back-end admin thing, you shouldn't use get. Imagine re-opening your browser and finding that the last time you closed firefox was on your 'DELETE EVERYTHING' GET->delete page resulting in everything being deleted again.

One of the main reasons for this is preventing cross-site request forgeries. For example, if you had a page that took a GET variable such as http://example.com/account?action=logout, an attacker could post an image on your site like this:

<img src="http://example.com/account?action=logout" />

and anyone who opened a page containing that image tag would be immediately logged out, even if they were an admin. It would be very annoying to then search through your raw database for that data and remove it.

Although POST operations are 'nearly' as easy to forge, as a general rule with any web security issue, the trade-off is speed/simplicity vs. security, so you're going to have to choose one or the other.

深居我梦 2024-09-04 15:42:23

您应该设置某种会话。

就安全性而言,使用 POST 而不是 GET 不会给你带来任何实际的好处。 POST 可以像 GET 一样被伪造。

因此,假设您的管理员登录后,您在会话中获得了某种标识符,您只需利用它即可。

考虑一下与此大致类似的情况:

<?PHP
session_start();

if (empty ($_SESSION['admin_id'])) die("Log in, son.");

if (empty($_GET['record_id'])) die("You've got to tell me which record to delete!");

if (! is_numeric($_GET['record_id'])) die("Invalid record ID");

//just to be totally safe, even though we just enforced that it's numeric.
$record_id = mysql_real_escape_string($_GET['record_id']));

$sql = "DELETE FROM table WHERE record_id='{$record_id}' AND admin_id = {$_SESSION['admin_id']}";

mysql_query($sql);

echo "Record was deleted (assuming it was yours in the first place)";
?>

在该示例中,我们通过利用 DELETE 查询中的 WHERE 子句来避免“删除其他人的记录”问题。当然,为了更加用户友好,您需要首先获取记录,然后将记录上的 admin_id 与 $_SESSION 中的 admin_id 进行比较,如果它们不匹配,则抱怨,记录一些内容,抛出错误,等

You should have some kind of session set up.

Using POST over GET gets you nothing tangible as far as security is concerned. POSTs can be forged just like GETs.

So assuming once your admin logs in, you've got some kind of identifier in the session, you just leverage that.

Consider something roughly similar to this:

<?PHP
session_start();

if (empty ($_SESSION['admin_id'])) die("Log in, son.");

if (empty($_GET['record_id'])) die("You've got to tell me which record to delete!");

if (! is_numeric($_GET['record_id'])) die("Invalid record ID");

//just to be totally safe, even though we just enforced that it's numeric.
$record_id = mysql_real_escape_string($_GET['record_id']));

$sql = "DELETE FROM table WHERE record_id='{$record_id}' AND admin_id = {$_SESSION['admin_id']}";

mysql_query($sql);

echo "Record was deleted (assuming it was yours in the first place)";
?>

In that example, we're avoiding the "delete someone else's records" problem by leveraging the WHERE clause in the DELETE query. Of course, to be more user friendly, you'd want to first fetch the record, then compare the admin_id on the record to the admin_id in $_SESSION, and if they don't match, complain, log something, throw an error, etc.

HTH

森罗 2024-09-04 15:42:23

您的意思是:“如果 Admin 123 直接访问 Admin 321 的 URL,从而删除他的内容会怎么样?” 不?

如果是这样,那么每个登录的管理员都应该至少有一个会话,其中包含该管理员的一些唯一标识符。如果不是,他一开始就不应该进入管理部门。不能只比较 URL 中的标识符和会话中的标识符吗?

如果任何用户(不仅仅是管理员)访问这些“删除我”URL,他应该被会话识别为该数据的原始“所有者”(管理员)。

You're saying: "What if Admin 123 access the URL of Admin 321 directly, thus deleting his stuff?" no?

If that's so then, every admin that is logged in should have at least one session with some unique identifier to that admin. If not, he shouldn't be able to be in the admin section in the first place. Can't you just compare the identifier in the URL with the identifier in the session?

If any user, not just an admin, access those 'delete me' URLs he should be identified by a session as the original 'owner' (admin) of that data.

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