如何防止重播攻击?
这与我问的另一个问题有关。总而言之,我有一个URL的特殊情况,在其中将表单发布到其中时,我不能依靠Cookie进行身份验证或者维护用户的会话,但是我需要某种方式知道他们是谁,并且我需要知道他们已登录!
我想我想出了解决这个问题的方法,但是需要充实。这就是我的想法。我创建了一个名为"用户名"的隐藏表单域,并在其中放置了加密的用户名。然后,在表单POST时,即使我没有从浏览器收到任何cookie,我也知道它们已登录,因为我可以解密隐藏的表单字段并获取用户名。
我可以看到的主要安全漏洞是重放攻击。如何防止某人获取该加密字符串并以该用户身份发布?我知道我可以使用SSL来使它更难以窃取该字符串,也许我可以定期旋转加密密钥以限制该字符串适合的时间,但是我真的很想找到一个防弹头解决方案。有人有什么想法吗? ASP.Net ViewState是否可以防止重播?如果是这样,他们怎么做?
编辑:我希望一个不需要任何存储在数据库中的解决方案。应用程序状态是可以的,除了它不会在IIS重新启动或者在Web场或者花园场景中完全无法工作的情况下。我暂时接受Chris的回答,因为我不相信没有数据库也可以保护它。但是,如果有人提出了一个不涉及数据库的答案,我会接受的!
解决方案
回答
我们可以使用与用户名一起使用的某种随机质询字符串来创建哈希。如果将质询字符串存储在数据库中的服务器上,则可以确保该质询字符串仅使用一次,并且仅用于一个特定用户。
回答
如果只接受一次每个密钥(例如,将密钥设置为GUID,然后检查何时返回),则将阻止重放。当然,如果攻击者首先做出反应,那么我们就会遇到新的问题...
回答
这是WebForms还是MVC?如果是MVC,则可以利用AntiForgery令牌。这似乎与我们提到的方法类似,除了它基本上使用GUID并为该帖子设置具有guid值的cookie。有关更多信息,请参见Steve Sanderson的博客:http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/
另一件事,我们是否考虑过在回发中检查引荐来源网址?这不是防弹的,但可能会有所帮助。
回答
我们是否可以使用内存或者数据库来维护有关用户或者请求的任何信息?
如果是这样,那么在请求表单时,我将包括一个隐藏的表单字段,其内容是随机生成的数字。呈现请求时,将此令牌保存到应用程序上下文或者某种类型的存储区(数据库,平面文件等)中。提交表单后,检查应用程序上下文或者数据库以查看该随机生成的数字是否仍然有效(但是我们定义的有效数字可能会在X分钟后过期)。如果是这样,请从"允许的令牌"列表中删除该令牌。
因此,任何重播的请求都将包含相同的令牌,该令牌在服务器上不再有效。
回答
我是Web编程某些方面的新手,但是前几天我在阅读。我相信我们需要使用Nonce。
回答
如果我们真的不想存储任何状态,我认为我们能做的最好的就是通过使用时间戳和较短的到期时间来限制重放攻击。例如,服务器发送:
{Ts,U,HMAC({Ts,U},Ks)}
其中Ts是时间戳,U是用户名,Ks是服务器的密钥。用户将其发送回服务器,服务器通过根据提供的值重新计算HMAC来对其进行验证。如果有效,则可以知道它是何时发出的,并且如果它早于5分钟,可以选择忽略它。
此类开发的一个很好的资源是Web上客户端身份验证的注意事项
回答
如果我们在时间戳记中加上用户名和密码,则可以在几秒钟内关闭用于重放攻击的窗口。我不知道这是否满足需求,但这至少是部分解决方案。
回答
在我的一个阻止"重播"攻击的应用程序中,我已将IP信息插入到会话对象中。每次我访问代码中的会话对象时,请确保将Request.UserHostAddress传递给它,然后进行比较以确保IP匹配。如果他们没有这样做,那么显然不是该人提出了请求,因此我返回null。这不是最佳解决方案,但至少是阻止重放攻击的障碍。
回答
(重播攻击很容易与IP / MAC欺骗有关,而且我们还面临动态IP的挑战)
这不只是我们在此之后的重播,孤立地讲,这是没有意义的。只需使用SSL即可,避免手工制作任何东西。
ASP.Net ViewState是一团糟,请避免使用。虽然PKI非常笨重,但至少在没有发明自己的安全"方案"的情况下就可以工作。因此,如果可以的话,我会使用它并始终进行相互认证。仅服务器身份验证是完全没有用的。
回答
ViewState包括安全功能。请参阅本文以了解ASP.NET中的一些内置安全性功能。它针对服务器上machine.config中的服务器machineKey进行验证,以确保每个回发均有效。
在本文的更下方,我们还将看到,如果要将值存储在自己的隐藏字段中,则可以使用" LosFormatter"类以与ViewState加密相同的方式对值进行编码。
private string EncodeText(string text) { StringWriter writer = new StringWriter(); LosFormatter formatter = new LosFormatter(); formatter.Serialize(writer, text); return writer.ToString(); }