Playframework 如何防止ID为的隐藏字段被黑客攻击

Playframework 如何防止ID为的隐藏字段被黑客攻击,playframework,Playframework,我正在构建一个简单的CRUD应用程序(不使用CRUD模块) 我的模型是一个具有一个属性的简单类。id是从模型隐式继承的 @实体 公共类帐户扩展模型{ @必需的 公共字符串域; } 观点如下。请注意id为的隐藏字段 设置 #{field'帐户.域'} &{field.name} ${field.error} #{/field} 我已经能够构建一个保存、更新工作的场景 完成更新的方法是从隐藏字段读取ID,然后更新记录。如果ID不可用,将创建新记录 所以问题是:是否可以对ID进行黑客攻击,即修

我正在构建一个简单的CRUD应用程序(不使用CRUD模块)

我的模型是一个具有一个属性的简单类。id是从模型隐式继承的

@实体
公共类帐户扩展模型{
@必需的
公共字符串域;
}
观点如下。请注意id为的隐藏字段


设置
#{field'帐户.域'}
&{field.name}
${field.error}
#{/field}

我已经能够构建一个保存、更新工作的场景

完成更新的方法是从隐藏字段读取ID,然后更新记录。如果ID不可用,将创建新记录

所以问题是:是否可以对ID进行黑客攻击,即修改ID,使我将1更改为2,并假设存在一个包含2的记录,它将被覆盖。(我想使用firebug或其他插件应该不难)

我如何防止这种情况?我想到的一个选项是读取具有给定Id的记录,如果允许用户修改它,我允许更新,否则不允许。这仍然不是万无一失的,因为虽然用户可以被允许,但“错误”的记录可以被修改

我想这是一个已知的问题,希望有一个已知的解决方案


感谢您抽出时间回答我的问题。

是的,可以修改。这样做不需要真正的知识或技能。在任何情况下,来自用户的信息都不能被信任,除非您进行了其他验证

为了做到这一点,您需要某种服务器端逻辑。在许多情况下,这只是服务器上链接到用户对象的会话,它允许您执行授权(您确保记录是他们可以修改的记录;这一记录不太重要,是用户故意造成的错误,而不是安全风险)

只要您可以将请求绑定回用户,然后确保允许该用户执行请求,您就可以了。最简单的方法是典型的会话,但有很大的空间

是否可以对ID进行黑客攻击,即修改,以便将1更改为2,以及 假设存在一个包含2的记录,它将被覆盖。(我想是吧 使用firebug或其他插件并不困难)

你说得对。编辑这些东西就像在Chrome的控制台中检查和编辑元素一样简单。记得;客户端完成的任何操作都是不安全的,用户可以修改。始终进行服务器端检查,始终

我如何防止这种情况

一种可能的修复方法是将记录链接到用户,即在用户和记录之间创建一个称为“recordAccess”的桥接表(或您的命名约定所要求的名称)。此桥接表将有一个用户ID列和一个记录ID列。服务器将根据此表检查用户ID和记录ID,并且仅当数据库中存在匹配行时才允许更改。如何将行添加到此表取决于应用程序的工作方式,但这并不难

为了防止用户编辑错误的记录,您可以在这个桥接表中添加一个名为“current”(或者,也可以是您喜欢的任何列)的附加列,这是一个简单的布尔值。当用户去编辑允许他/她编辑的记录时,该值将设置为“true”,与该用户关联的所有其他行将设置为“false”。然后,当用户提交编辑时,如果该行中的值设置为“true”,则该行将成功更新,并且该值将变回“false”。否则,所有值都设置为“false”,并拒绝更新

希望这能给你一些想法

所以问题是:这个ID可以被黑客入侵,也就是说可以被修改以使我改变吗 1到2,并且假设存在一个包含2的记录,它将被覆盖。(一) 假设使用firebug或其他插件并不困难)

我如何防止这种情况?我想到的一个选择是看唱片 对于给定的Id,如果允许用户修改它,我允许更新, 否则就不行了。这仍然不是傻瓜式的,因为 可以允许修改“错误”记录

当然,攻击者有可能更改记录的id

有几种方法可以将此攻击的影响降至最低

1) 最简单的方法-对象获取

从数据库中获取对象并检查它是否属于相关用户。这将防止其他用户与不属于他们的对象混淆,但不会阻止用户更改属于他的另一个对象。这是一种简单的方法,在大多数情况下已经足够了

2) 更复杂:签名

这里的想法是对提供给模板的常量进行签名,并在表单提交后检查哈希是否仍然匹配。 这与play的会话非常相似。攻击者不可能乱动常量(例如id)并提供最大的安全性。。但是,您将有更多的工作要做

例如:

    public static void someActionDisplayingForm(){
  SomeObject o = ....
  SomeOtherObject o2 = ....
      String constants = o.id + "|" + o2.id;
      String hash = Crypto.sign(constants);
       render(o, o2, hash);
}
在您拥有的模板中

 #{form ...}
   <input type='hidden' name='id1' value='${o.id}' />
   <input type='hidden' name='id2' value='${o2.id}' />
   <input type='hidden' name='hash' value='${hash}' />

希望能有所帮助。

谢谢。现在,我正在探索将这与某种消息摘要相结合。HMAC(RFC2104)似乎符合这一要求。我需要更好地理解它。如果我取得任何进展,将更新此线程。这似乎正是我所需要的。Crypto.sign计算HMAC.SHA1签名。今晚我要试试。我一直在考虑的是要有特定于用户的秘密,但这是一个实现细节。你让我头脑中的阴霾变得清晰。谢谢:)很有魅力。比在服务器上维护状态更简单。我计划使用我将在注册时生成的特定于用户的密钥,而不是默认使用的应用程序密钥。我不知道你为什么要麻烦。剧本f
 public static void processing(String id1, String id2, String hash, String otherValues, ...){
   String constants = id1 + "|" + id2;
   String checkHash = Crypto.sign(constants);
    if(!checkHash.equals(hash))
     badRequest();
   ... 
}