是否应公开MySQL表的主键?

Jay*_*Jay 8 mysql security

我有许多MySQL表描述模型,如"用户","业务"等.这些表的主键是否应该暴露给客户端?我主要是从安全角度提问,但是还有其他一些我没有想过的考虑因素吗?

Jas*_*ean 19

公开主键(特别是如果它们是可预测的)是一个称为不安全直接对象引用的漏洞.

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

http://www.domain.com/myaccount?userid=12
Run Code Online (Sandbox Code Playgroud)

您可以让最终用户有机会搞乱这些变量并传递他们喜欢的任何数据.缓解此漏洞的对策是创建间接对象引用.这可能听起来像是一个很大的变化,但并不一定如此.您不必重新键入所有表格或任何内容,只需通过使用间接参考地图聪明地处理数据即可.

请考虑一下:您的用户正在您的网站上进行购买.当需要支付时,他们会向您提供他们"存档"的信用卡号码.如果您查看下拉列表的代码,您会看到信用卡号码与密钥8055,9044和10099相关联.

用户可能会看到这一点,并认为它们看起来很像自动递增主键(用户可能是正确的).所以他开始尝试其他钥匙,看看他是否可以用别人的卡付款.

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

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

而不是向它们显示对DB中记录的直接引用,而是给它们一个间接引用.

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

Array cards = new Array(3);
cards[0] = 8055;
cards[1] = 9044;
cards[2] = 10099;
Run Code Online (Sandbox Code Playgroud)

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

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

如果用户愿意,用户可以全天传递不同的值,但除了自己的卡外,他永远不会获得结果,无论服务器端的访问控制是什么.

请记住,虽然使用传入的索引来获取值,如果用户确实搞乱它,你可能会得到一些例外(ArrayOutOfBounds,InvalidIndex,等等).因此,将这些内容包装在try/catch中,这样您就可以抑制这些错误并记录失败以查找破解尝试.

希望这可以帮助.

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

  • 在一个安全的系统中,你应该做到这两点.防御纵深.如果进行身份验证的服务器端逻辑有漏洞怎么办?以合理的成本提供双重保护. (2认同)