23

关于这个 Haacked 博客,我对实施建议的反 JSON GET 劫持解决方案犹豫不决,因为

  1. 减轻 JSON 劫持的推荐解决方案涉及到 GET 数据的非 REST-full JSON POST

  2. 替代解决方案(对象包装)会导致我无法访问源代码的第 3 方控件出现问题。

  3. 我找不到一个经过社区审查的实现,它实现了关于如何编写安全令牌或在网页中安全地交付它的替代解决方案(如下所列)。我也不会声称有足够的专家来推出我自己的实现。

  4. 不能依赖引用标题

背景

这篇博客描述了一个关于 JSON 劫持的 CSRF 问题,并建议使用 JSON POST 来获取数据。由于使用 HTTP POST 来获取数据不是 REST 完整的,因此我正在寻找一种更 REST 完整的解决方案,该解决方案可以在每个会话或每个页面上启用 REST 操作。

另一种缓解技术是将 JSON 数据包装在一个对象中,如此处所述。恐怕这可能只会延迟问题,直到找到另一种技术。

替代实施

对我来说,为我的 JSON 扩展使用ASP.NET MVC 的 AntiForgeryToken和 jQuery HTTP GET似乎很自然。

例如,如果我 GET 一些敏感数据,根据上面的 Haacked 链接,以下代码很容易受到攻击:

$.getJSON('[url]', { [parameters] }, function(json) {
    // callback function code
});

我同意使用推荐的 POST 解决方法获取数据不是 RESTfull。我的想法是在 URL 中发送一个验证令牌。这样 CSRF 风格的攻击者就不会知道完整的 URL。缓存或未缓存,他们将无法获取数据。

下面是如何完成 JSON GET 查询的两个示例。我不确定哪种实现最有效,但可能会猜测第一个更安全,因为错误的代理缓存了这些数据,从而使其容易受到攻击者的攻击。

http://localhost:54607/Home/AdminBalances/ENCODEDTOKEN-TOKEN-HERE

或者

http://localhost:54607/Home/AdminBalances?ENCODEDTOKEN-TOKEN-HERE

...这也可能是 MVC3 的 AntiForgeryToken 或其变体(参见 swt)。此标记将设置为上面选择的任何 URL 格式的内联值。

阻止我推出自己的解决方案的示例问题

  1. 您将使用什么 URL 格式(上图)来验证 JSON GET(斜杠、问号等) 代理是否会使用http ://localhost:54607/Home/AdminBalances 响应http://localhost:54607/Home/AdminBalances? ENCODEDTOKEN-TOKEN-HERE数据?

  2. 您将如何将该编码令牌传递到网页?内联,还是作为页面变量?

  3. 您将如何编写令牌?内置 AntiforgeryToken,还是通过其他方式?

  4. AntiForgeryToken 使用 cookie。在这种情况下是否会使用/需要支持 cookie?仅 HTTP?SSL 与仅 HTTP 结合使用如何?

  5. 您将如何设置缓存标头?Google Web Accelerator 的任何特殊功能(例如)

  6. 仅使 JSON 请求 SSL 有什么含义?

  7. 为了安全起见,返回的 JSON 数组是否仍应包装在一个对象中?

  8. 此解决方案将如何与 Microsoft 提出的模板和数据绑定功能互操作

上面的问题是我自己不进取并这样做的原因。更不用说可能还有更多我没有想到的问题,但这些问题仍然存在风险。

4

3 回答 3

18

Asp.net MVC AntiForgeryToken 不能通过 HTTP GET 工作,因为它依赖于依赖于 HTTP POST 的 cookie(它使用OWASP XSRF预防备忘单中描述的“双重提交 cookie ”技术)。您还可以通过将 设置为httponly来额外保护发送到客户端的 cookie ,这样它们就不会被脚本欺骗。

本文档中,您可以找到可用于防止 XSRF 的各种技术。您所描述的似乎属于方法 1。但是我们在使用 Ajax HTTP GET 请求时如何在服务器上检索会话时遇到问题,因为 cookie 没有随请求一起发送。因此,您还必须在操作的 URL 中添加一个会话标识符(又名无 cookie 会话,它更容易被劫持)。因此,为了执行攻击,攻击者只需要知道正确的 URL 即可执行 GET 请求。

也许一个好的解决方案是使用来自用户 SSL 证书的一些密钥(例如证书指纹)来存储会话数据。这样,只有 SSL 证书的所有者才能访问他的会话。这样您就不需要使用 cookie,也不需要通过查询字符串参数发送会话标识符。

无论如何,如果您不想在 Asp.net MVC 中使用 HTTP POST,则需要推出自己的 XSRF 保护。

于 2011-02-09T10:31:08.577 回答
5

我遇到了这个问题,解决方案并不是那么简单,但是有一个很棒的博客可以帮助您入门,这可以与 get 和 post ajax 一起使用。

http://johan.driessen.se/posts/Updated-Anti-XSRF-Validation-for-ASP.NET-MVC-4-RC

如果您将以下内容放在全局名称空间中,您的所有帖子/获取都可以利用防伪令牌,并且您不必修改您的 ajax 调用。在公共页面中创建输入元素。

<form id="__AjaxAntiForgeryForm" action="#" method="post">@Html.AntiForgeryToken()</form>

以下 javascript 将读取防伪令牌并将其添加到请求标头中。

// Wire up the global jQuery ajaxSend event handler.
$(document).ajaxSend(namespace.ajax.globalSendHandler);

// <summary>
// Global handler for all ajax send events.
// </summary>
namespace.ajax.globalSendHandler = function (event, xhr, ajaxOptions) {
    // Add the anti forgery token
    xhr.setRequestHeader('__RequestVerificationToken', $("#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]").val());
};
于 2013-09-03T21:38:45.277 回答
0

我认为在 ajax http GET 请求中使用 AntiforgeryToken (AFT) 是合法的,前提是它嵌入在已经提供 AFT 和相关 cookie 的表单中。然后,ajax 处理程序可以在服务器上进行验证,就像在普通表单中一样。

于 2021-02-09T12:25:06.637 回答