如何检测隐藏的现场篡改?

时间:2010-04-13 19:36:35

标签: html security webforms hidden-field

在我的网络应用程序的一种形式上,我有一个隐藏的字段,我需要防止因安全原因而被篡改。我试图想出一个解决方案,我可以检测隐藏字段的值是否已经改变,并做出适当反应(即通用“出错了,请再试一次”错误信息)。解决方案应该足够安全,暴力攻击是不可行的。我有一个基本的解决方案,我觉得它会起作用,但我不是安全专家,我可能在这里完全遗漏了一些东西。

我的想法是渲染两个隐藏的输入:一个名为“important_value”,包含我需要保护的值,一个名为“important_value_hash”,包含与常量长随机字符串连接的重要值的SHA哈希(即每次都会使用相同的字符串)。提交表单时,服务器将重新计算SHA哈希值,并与提交的important_value_hash值进行比较。如果它们不相同,则important_value已被篡改。

我还可以使用SHA的输入字符串(可能是用户的IP地址?)连接其他值,但我不知道这是否真的让我获得了任何东西。

这会安全吗?任何人都可以了解它是如何被打破的,以及可以/应该做些什么来改进它?

谢谢!

6 个答案:

答案 0 :(得分:4)

最好将哈希值存储在服务器端。 可以想象,攻击者可以更改值并生成他/她自己的SHA-1哈希并添加随机字符串(他们可以很容易地反复访问该页面)。如果哈希是在服务器端(可能在某种缓存中),您可以重新计算哈希并检查它以确保该值没有以任何方式被篡改。

修改

我读了关于随机字符串(恒定盐)的错误问题。但我想最初的观点仍然存在。攻击者可以建立一个与隐藏值对应的哈希值列表。

答案 1 :(得分:1)

数字签名

它可能有点矫枉过正,但这与您对外发电子邮件进行数字签名时没有什么不同,因此收件人可以验证其来源和内容是否真实。篡改敏感字段的签名可以通过您的防篡改字段释放到野外,几乎不用担心检测不到篡改,只要您保护私钥并验证数据和签名与公众返回时的关键。

这个方案甚至有一个漂亮的属性,你可以限制“签名”到受保护的服务器/进程集合访问私钥,但使用一组更大的服务器/进程与公钥一起提供处理表单提交

如果你有一个非常敏感的“do-not-tamper”字段并且无法在服务器上维护它的散列签名,那么这就是我要考虑的方法。

虽然我怀疑大多数人都熟悉数字签名,但对于任何一个不熟悉的人来说,这里都有一些维基百科:

Public Key Cryptography - Security

  

......另一种类型的应用程序   公钥加密是的   数字签名方案。数字   签名方案可用于   发件人认证和   不可抵赖性。在这样的方案中   想要发送消息的用户   计算这个的数字签名   消息,然后发送此数字   签名和消息一起   预期的接收者。数字   签名方案有财产   签名只能计算   了解私钥。   验证消息是否已经过   由用户签名但尚未签名   修改接收器只需要   知道相应的公钥。在   存在某些情况(例如RSA)   数字签名方案有很多   与加密方案的相似之处。在   其他情况(例如DSA)算法   不像任何加密   方案。 ...

答案 2 :(得分:1)

如果您无法在服务器上处理会话,请考虑使用您的私钥加密数据并为其生成HMAC,将结果作为隐藏字段发送。然后,您可以验证返回的内容是否与发送的内容相匹配,因为没有其他人知道您的私钥,否则其他任何人都无法生成有效信息。但是处理服务器端的“不得更改”数据会好得多。

您必须认识到,任何有足够决心的人都可以向您(您的表单)发送包含他们想要的信息的HTTP请求,这些信息可能与您上次发送的信息有任何关系。

答案 3 :(得分:0)

如果您不能/不会存储哈希服务器端,则需要能够在服务器端重新生成它以进行验证。

为了它的价值,你也应该为你的哈希加盐。当你说:

时,这可能就是你的意思
  

与常数长连接   随机字符串(即相同的字符串   将每次都使用)

知道如果每个用户/登录/ sesison的值不相同,那么它实际上不是盐值。

答案 4 :(得分:0)

只要你用你的生命保护“恒定的长随机字符串”,那么你的方法相对较强。

为了更进一步,您可以生成一次/唯一的“常量长随机字符串”。

答案 5 :(得分:0)

您所描述的内容类似于所谓的金丝雀所需的部分实施,并用于缓解跨站点请求伪造攻击。

一般来说,HTML表单中的隐藏输入包含使用HTTP请求回发的加密值。会话中保存的浏览器cookie或字符串包含相同的加密值,这样当隐藏的输入值被解密并且cookie /会话值被解密时,未加密的值将相互比较 - 如果它们不相同,则为HTTP请求不可信任。

加密值可能是包含属性的对象。例如,在ASP.NET MVC中,canary实现使用一个类,该类包含经过身份验证的用户名的属性,使用RNGCryptoServiceProvider类生成的加密伪随机值,创建对象的DateTime(UTC格式)和一个可选的盐串。然后使用带有256位密钥的AES加密算法对对象进行加密,并在请求进入时使用相同的密钥解密。