关于asp.net:如何防止重播攻击?

关于asp.net:如何防止重播攻击?

How do I prevent replay attacks?

这与我问的另一个问题有关。总而言之,我有一个URL的特殊情况:在其中将表单发布到其中时,我不能依靠Cookie进行身份验证或维持用户的会话,但是我需要某种方式知道他们是谁,并且我需要知道他们已登录!

我想我想出了解决这个问题的方法,但是需要充实。这就是我的想法。我创建了一个名为"用户名"的隐藏表单域,并在其中放置了加密的用户名。然后,在表单POST时,即使我没有从浏览器收到任何cookie,我也知道它们已登录,因为我可以解密隐藏的表单字段并获取用户名。

我可以看到的主要安全漏洞是重放攻击。如何防止某人获取该加密字符串,并以该用户身份发布?我知道我可以使用SSL来提高窃取该字符串的难度,也许我可以定期旋转加密密钥以限制该字符串适合的时间,但是我真的很想找到一个防弹的方法解。有人有什么想法吗? ASP.Net ViewState是否可以防止重播?如果是这样,他们怎么做?

编辑:我希望一个不需要任何存储在数据库中的解决方案。应用程序状态将是可以的,除了它不会在IIS重新启动或在Web场或花园场景中完全无法工作的情况下。我现在接受Chris的回答,因为我不相信没有数据库甚至可以保护它。但是,如果有人提出了一个不涉及数据库的答案,我会接受的!


如果您在时间戳记中加上用户名和密码,则可以在几秒钟内关闭用于重放攻击的窗口。我不知道这是否满足您的需求,但这至少是部分解决方案。


如果您真的不想存储任何状态,我认为您能做的最好的事情就是使用时间戳和较短的到期时间来限制重放攻击。例如,服务器发送:

{Ts,U,HMAC({Ts,U},Ks)}

其中Ts是时间戳,U是用户名,Ks是服务器的密钥。用户将其发送回服务器,服务器通过根据提供的值重新计算HMAC来对其进行验证。如果有效,则可以知道它是何时发出的,并且如果它早于5分钟,可以选择忽略它。

此类开发的一个很好的资源是Web上客户端身份验证的注意事项


这里有几个很好的答案,而将它们全部放在一起是最终的答案:

  • 块密码加密(使用AES-256 +)和哈希(使用SHA-2 +)将发送到客户端的所有与状态/随机性相关的信息。否则,黑客只会操纵数据,查看数据以学习模式并规避其他所有内容。请记住...它只需要一个打开的窗口。

  • 为每个请求生成一次随机且唯一的随机数,该随机数随POST请求一起发送回去。这有两件事:确保POST响应与THAT请求一起进行。它还允许跟踪对一组给定的get / POST对的一次性使用(防止重放)。

  • 使用时间戳使随机数池易于管理。按照上面的#1将时间戳存储在加密的cookie中。丢弃所有早于应用程序的最大响应时间或会话次数(例如一个小时)的请求。

  • 存储带有加密时间戳数据的发出请求的机器的"合理唯一"的数字指纹。这将防止另一种技巧,其中攻击者会窃取客户端cookie来执行会话劫持。这将确保不仅将请求发送回一次,而且还会从计算机(或者距离足够近,几乎使攻击者无法复制)发送到表单。

  • 有基于ASPNET和Java / J2EE安全筛选器的应用程序,它们使用零编码来完成上述所有操作。如果性能至关重要,那么为大型系统(如股票交易公司,银行或高容量安全站点)管理随机数池并不是一件容易的事。建议您查看这些产品,而不是尝试为每个Web应用程序进行编程。


    您可以使用与用户名一起使用的某种随机质询字符串来创建哈希。如果将质询字符串存储在服务器上的数据库中,则可以确保该质询字符串仅使用一次,并且仅用于一个特定用户。


    在阻止我的"重放"攻击的一个应用程序中,我已将IP信息插入到会话对象中。每次我访问代码中的会话对象时,请确保将Request.UserHostAddress传递给它,然后进行比较以确保IP匹配。如果他们没有这样做,那么显然不是该人提出了请求,因此我返回null。这不是最佳解决方案,但至少是阻止重放攻击的另一个障碍。


    ViewState包含安全功能。请参阅本文以了解ASP.NET中的某些内置安全性功能。它针对服务器上machine.config中的服务器machineKey进行验证,以确保每个回发均有效。

    在本文的更下方,您还将看到,如果要将值存储在自己的隐藏字段中,则可以使用LosFormatter类以与ViewState加密相同的方式对值进行编码。

    1
    2
    3
    4
    5
    6
    private string EncodeText(string text) {
      StringWriter writer = new StringWriter();
      LosFormatter formatter = new LosFormatter();
      formatter.Serialize(writer, text);
      return writer.ToString();
    }


    (重播攻击很容易与IP / MAC欺骗有关,而且您还面临动态IP的挑战)

    这不只是您在这里的重播,孤立地讲,这毫无意义。只需使用SSL即可,避免手工制作任何东西。

    ASP.Net ViewState是一团糟,请避免使用。尽管PKI非常笨重,但至少在没有发明自己的安全"方案"的情况下就可以工作。因此,如果可以的话,我会使用它并始终进行相互认证。仅服务器身份验证非常无用。


    我是Web编程某些方面的新手,但是前几天我在阅读。我相信您需要使用Nonce。


    您是否可以使用内存或数据库来维护有关用户或请求的所有信息?

    如果是这样,那么在请求表单时,我将包括一个隐藏的表单字段,其内容是随机生成的数字。呈现请求时,将此令牌保存到应用程序上下文或某种类型的存储区(数据库,平面文件等)中。提交表单后,检查应用程序上下文或数据库以查看该随机生成的数字是否仍然有效(但是您定义的有效数字-可能会在X分钟后过期)。如果是这样,请从"允许的令牌"列表中删除该令牌。

    因此,任何重播的请求都将包含相同的令牌,该令牌在服务器上不再有效。


    使用https ...内置了重放保护。


    这是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/

    另一件事,您是否考虑过在回发中检查引荐来源?这不是防弹的,但可能会有所帮助。


    如果只接受一次每个密钥(例如,将密钥设置为GUID,然后检查何时返回),则将阻止重放。当然,如果攻击者首先做出反应,那么您就会遇到新问题...


    推荐阅读