17

这与我问的另一个问题有关。总而言之,我有一个 URL 的特殊情况,当一个表单被发布到它时,我不能依赖 cookie 进行身份验证或维护用户的会话,但我需要知道他们是谁,我需要知道他们已经登录了!

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

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

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

4

12 回答 12

15

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

于 2008-09-15T19:27:12.720 回答
14

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

  1. 块密码加密(使用 AES-256+)和散列(使用 SHA-2+)发送到客户端的所有状态/随机数相关信息。否则黑客只会操纵数据,查看数据以了解模式并规避其他一切。记住……它只需要一个打开的窗口。

  2. 每个与 POST 请求一起发回的请求生成一次性随机且唯一的 nonce。这做了两件事:它确保 POST 响应与那个请求一起出现。它还允许跟踪给定的一组 get/POST 对的一次性使用(防止重放)。

  3. 使用时间戳使 nonce 池易于管理。按照上面的 #1 将时间戳存储在加密的 cookie 中。丢弃任何早于应用程序的最大响应时间或会话(例如,一个小时)的请求。

  4. 使用加密的时间戳数据存储发出请求的机器的“合理唯一”数字指纹。这将防止攻击者窃取客户端 cookie 以执行会话劫持的另一个技巧。这将确保请求不仅返回一次,而且从发送表单的机器(或足够接近以使攻击者几乎不可能复制)返回。

有基于 ASPNET 和 Java/J2EE 安全过滤器的应用程序可以零编码完成上述所有工作。如果性能至关重要,那么管理大型系统(如股票交易公司、银行或大容量安全站点)的 nonce 池并非易事。建议查看这些产品,而不是尝试为每个 Web 应用程序进行编程。

于 2012-09-18T07:30:41.787 回答
13

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

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

其中 Ts 是时间戳,U 是用户名,Ks 是服务器的密钥。用户将其发送回服务器,服务器通过在提供的值上重新计算 HMAC 来验证它。如果它是有效的,你知道它是什么时候发出的,如果它早于 5 分钟,你可以选择忽略它。

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

于 2008-09-15T19:24:15.970 回答
5

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

于 2008-09-04T18:27:22.630 回答
2

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

于 2009-03-16T23:05:03.910 回答
1

您可以使用内存或数据库来维护有关用户或请求的任何信息吗?

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

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

于 2008-09-04T18:34:32.003 回答
1

我对网络编程的某些方面不熟悉,但前几天我正在阅读。我相信您需要使用Nonce

于 2008-09-04T19:28:39.533 回答
1

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

你在这里追求的不仅仅是重播,孤立它是没有意义的。只需使用 SSL 并避免手工制作任何东西..

ASP.Net ViewState 是一团糟,避免它。虽然 PKI 是重量级且臃肿的,但至少它可以在没有发明您自己的安全“方案”的情况下工作。因此,如果可以,我会使用它并始终寻求相互验证。仅服务器身份验证毫无用处。

于 2009-03-16T23:23:41.807 回答
1

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();
}
于 2010-01-19T10:13:41.013 回答
1

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

于 2017-02-27T08:38:31.137 回答
0

如果您只接受每个密钥一次(例如,将密钥设为 GUID,然后检查它何时返回),则可以防止重播。当然,如果攻击者首先响应,那么你就有一个新问题......

于 2008-09-04T18:31:10.670 回答
0

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

另一件事,您是否考虑过在回发时检查推荐人?这不是万无一失的,但它可能会有所帮助。

于 2008-09-04T18:33:20.230 回答