MySQL表的主键是否应该公开? [英] Should primary keys of MySQL tables be exposed?

查看:92
本文介绍了MySQL表的主键是否应该公开?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多描述诸如用户",业务"等模型的MySQL表.这些表的主键是否曾经暴露给客户端?我主要是从安全角度出发,但是还有其他我没有想到的注意事项吗?

I have a number of MySQL tables describing models such as "User", "Business" etc. Should the primary keys of these tables ever be exposed to the client-side? I am asking from a security perspective, primarily, but are there also other considerations that I haven't thought of?

推荐答案

公开主键(尤其是可预测的主键)是一个称为不安全直接对象引用"的漏洞.

Exposing your primary keys (especially if they are predictable) is a vulnerability called Insecure Direct Object Reference.

通过拥有这样的URL(或任何其他客户端提供的参数):

By having a URL (or any other client provided param) like this:

http://www.domain.com/myaccount?userid=12

您为最终用户提供了处理这些变量并传递他们喜欢的任何数据的机会.缓解此漏洞的对策是创建间接对象引用.这听起来可能是一个很大的变化,但不一定必须如此.您不必去重新键入所有表或任何东西的密钥,只需使用间接引用映射来巧妙地处理数据即可.

You give your end users the opportunity to mess with those variables and pass any data that they like. The counter measure to mitigate this vulnerability is to create indirect object references instead. This may sound like a big change, but it does not necessarily have to be. You don't have to go and rekey all your tables or anything, you can do it just by being clever with your data through the use of an indirect reference map.

考虑一下:您有一个正在您的网站上购物的用户.当需要付款时,会向您显示您已存档"的信用卡号的下拉列表.如果您查看下拉菜单的代码,则会看到信用卡号与键8055、9044和10099相关联.

Consider this: You have a user who is making a purchase on your site. And when it is time to pay they are presented with a drop down of the credit card numbers of theirs that you have "on file". If you look at the code for the drop down you see that the credit card numbers are associated with the keys 8055, 9044, and 10099.

用户可能会对此进行查看,并认为它们看起来很像自动递增主键(用户可能是正确的).因此,他开始尝试其他钥匙,看能否用别人的卡付款.

The user might look at this and think that they look a lot like auto-incrementing primary keys (the user would probably be right). So he starts trying other keys to see if he can pay with someone else's card.

现在,从技术上讲,您应该在服务器端具有代码,以确保所选卡是用户帐户的一部分并可以使用.这是一个人为的例子.现在,我们将假定情况并非如此,或者这是另一种可能没有这种服务器端控件的形式.

Now technically, you should have code on the server-side that ensures that the selected card is part of the user's account and that they can use it. This is a contrived example. For now we will assume that this is not the case or that this is another type of form that perhaps does not have that kind of server side control.

那么我们如何防止最终用户选择他们不应该使用的密钥?

So how do we prevent the end user from choosing a key that should not be available to them?

给他们一个间接引用,而不是向他们显示对数据库中记录的直接引用.

Instead of showing them a direct reference to the record in the DB, give them an indirect reference.

我们将在服务器上创建一个数组并将其填充到用户会话中,而不是将数据库密钥放入下拉列表中.

Instead of putting the DB keys into the dropdown, we will create an array on the server and stuff it in the user's session.

Array cards = new Array(3);
cards[0] = 8055;
cards[1] = 9044;
cards[2] = 10099;

在下拉列表中,我们现在提供对存储卡的阵列索引的引用.因此,如果最终用户查看源代码,那么他们将看到值0、1和2,而不是看到实际的键.

In the drop down we now provide the reference to the index of the array where the card is stored. So instead of seeing the actual keys, the end user will see the values 0, 1 and 2, if they view the source.

提交表单后,这些值之一将被传递.然后,我们从用户会话中获取数组,并使用索引获取值.实际的密钥从未离开过服务器.

When the form is submitted one of those values will be passed along. Then we get the array out of the user's session and use the index to get the value. The actual key has never left the server.

如果用户愿意的话,用户可以整天传递不同的值,但是无论使用哪种服务器端访问控制,他都永远不会获得除自己的卡以外的任何结果.

And the user can pass in different values all-day-long if he wants, but he will never, ever, get a result other than his own cards, regardless of the server-side access control thats in place.

请记住,但是当使用传入索引获取值时,如果用户确实喜欢它,则可能会遇到一些异常(ArrayOutOfBounds,InvalidIndex等).因此,将这些内容包装在try/catch中,以便您可以抑制这些错误并记录故障以寻找破解尝试.

Keep in mind though that when using the passed-in index to get the value out that if the user does mess with it that you could get some exceptions (ArrayOutOfBounds, InvalidIndex, whatever). So wrap that stuff in a try/catch so you can suppress those errors and log the failures to look for cracking attempts.

希望这会有所帮助.

要了解有关不安全直接对象引用的更多信息,请查看OWASP Top10.风险编号为A4. https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References

To read more about Insecure Direct Object References, check out the OWASP Top 10. It is risk number A4. https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References

这篇关于MySQL表的主键是否应该公开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆