在我的MVC应用程序中,我有一个页面供用户编辑他们的帐户详细信息,如电子邮件地址,密码等。在我的数据库中,User表保存此数据,主键是UserId。
在我创建的ChangeAccountDetails视图中,我传递了一个ViewModel,其中包含用户应该能够在其帐户上修改的数据。我还将UserId存储在ViewModel中,该ViewModel渲染到我的实际视图中的隐藏字段中。我担心这是不安全的,因为在保存更改数据的POST操作上,我的服务层加载了刚刚由ViewModel中发回的UserId更改的用户帐户详细信息的持久版本。
我使用Fiddler来改变POST请求,并将UserId更改为我数据库中另一条用户记录的UserId,这可能会产生严重问题,因为有人可能会以这种方式更改别人密码和/或其他详细信息。
有人可以建议我在使用ViewModels时如何避免这样的问题。是不是在这种情况下使用Session是唯一的方法(我知道最好避免使用Session,但为此目的呢?)
答案 0 :(得分:2)
答案 1 :(得分:1)
这是一个常见问题。最好通过不将UserID发送到客户端来解决。由于您不想使用服务器端会话,并且希望保护您的应用程序免受恶意用户的攻击,因此您必须使用数据库表模拟会话。当用户登录时,将UserId和Random GUID放入表中。确保此表对于任何给定的UserId只有一行(我尝试简化 - 当用户稍后再次登录时使用新的guid更新现有行)。
现在将GUID作为ViewModel的一部分发送给客户端。当更新的电子邮件等与原始guid一起返回时,请查阅我们的表以将guid解析回用户ID。请注意,这是一种基本的会话,并实现防篡改。篡改GUID以找到其他一些用户Guid几乎不可能。
正如您所理解的那样,将我们的数据库标识发送给任何模型,不仅是用户到客户端作为输入隐藏字段是一个坏主意,每一个黑客的早餐一醒来,就是查看隐藏的输入字段和修补它。