如何保护我的 JsonResult GET 调用?

Posted

技术标签:

【中文标题】如何保护我的 JsonResult GET 调用?【英文标题】:How do I secure my JsonResult GET calls? 【发布时间】:2010-10-07 23:12:03 【问题描述】:

我知道如何使用 MVC 的 AntiForgeryToken 属性及其关联的 html 帮助程序来帮助 XSRF 保护我的应用程序的表单 POST。

可以为实现 GET 的 JsonResults 做类似的事情吗?

例如,我的视图包含一个 onSubmit jQuery 调用,如下所示:

$.getJSON("/allowActivity/YesOrNo/" + someFormValue, "", function(data) 
  if(data.Allow) 
    //Do something.
  
);

我想确定这个 JsonResult 只能从预期的页面调用。

编辑:

我发现this post 有一个类似的问题,但没有具体答案。

确保我的 GET(非破坏性)URL 仅由来自我自己页面的 AJAX 调用使用的最简单方法是什么?

【问题讨论】:

【参考方案1】:

您可以将 AntiForgeryToken 与一些自定义逻辑结合使用。在服务器上创建 AntiForgery 令牌是相同的,但默认情况下该值不包含在您的 XmlHttpRequest 中。

此令牌的值在仅 HTTP cookie“__RequestVerificationToken”中,也应该在发布到服务器的表单数据中。因此,在您的 XmlHttpRequest 中包含一个键/值对并在您的控制器上使用 ValidateAntiForgeryToken - 属性

编辑:

今天我自己尝试使用 AntiForgeryToken 处理 Ajax 请求,它工作正常。只需使用以下 javascript

$.post('my_url',  $.getAntiForgeryTokenString(), function()  ... );

$.getAntiForgeryTokenString = function() 
    return $(document.getElementsByName("__RequestVerificationToken")).fieldSerialize();
;

在服务器端,您不必更改代码 - 只需为您的操作使用 ValidateAntiForgeryToken- 属性。

希望对你有帮助

【讨论】:

如何将 __RequestVerificationToken 值与 $.getJSON 或 $.ajax 调用集成?请记住,这是一个 GET 请求。 从owasp.org/index.php/… 中读取“URL 中令牌的披露”“如果保证敏感的服务器端操作只响应 POST 请求,则无需在 GET 请求中包含令牌”关键是确保您的 GET 不会修改数据。否则,您不需要保护 GET 请求【参考方案2】:

首先为什么不使用 $.post(url, data, callback, 'json') 而不是 getJSON? 正如 kleolb02 所说,您可以使用 cookie plugin - __RequestVerificationToken: $.cookie('__RequestVerificationToken') 将 cookie 中的值添加到帖子数据中

【讨论】:

听起来不错。对于这样一个简单的 ajax 调用,我希望避免使用 POST,但如果这是保护它的唯一方法,我当然会这样做。 你应该使用 post 来更新服务器上的一些数据。这是一个常见的场景。据我所知,AntiForgeryToken 仅适用于发布请求(它们仅在 FormCollection 中查找值)。 这不是更新,只是简单的“获取”。我只想将 URL 的使用限制为我自己页面的 AJAX 调用。 对不起,这是无法限制的。您可以检查引荐来源网址和一些特定的 cookie,但它们很容易被模仿。您只能将对 url 的访问限制为未经授权的用户。为此,您可以使用标准登录授权。【参考方案3】:

我在一个 ASP.NET MVC 项目中使用了类似的代码来在没有 Ajax 表单的情况下使用元素的模糊功能。当某个 HTML 元素 Blur 事件发生时,此代码提供了用服务器数据填充文本字段。

希望这也有帮助。这是我的代码:

Javascript:

var mytext =  'myText': 'example text' ;
$.post('/MyController/JsonResultMethod', AddAntiForgeryToken(myText), function (resultData) 
        $('#htmlElement').val(resultData);
);
AddAntiForgeryToken = function (data) 
    data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
    return data;
;

C-Sharp 代码:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public JsonResult SeoString(string myText)
    
        try
        
            // do something here
            return this.Json("result text");
        
        catch (Exception)
         return this.Json(string.Empty); 
    

【讨论】:

【参考方案4】:

你可以做一些类似于反 XSRF 方法的事情。只需生成一些 ID 将其插入到 javascript 中,当用户调用您的 JSON url 时,让该 url 包含生成的 ID 并检查它是否存在。

针对 XSRF 的防御也使用 sessionID 作为密钥,但这不会阻止用户从另一个网站为自己的帐户执行它。

一些基于会话和时间的哈希可能会起到作用。当然,如果用户从 JS 复制值,他仍然可以从另一个位置执行它,但是您可以让该值每 x 分钟过期一次。另一种选择是用JS设置一个cookie并在服务器端读取它。

希望这能给您一些帮助您入门的想法。

【讨论】:

以上是关于如何保护我的 JsonResult GET 调用?的主要内容,如果未能解决你的问题,请参考以下文章

在 JsonResult 之后不调用 Ajax 成功

如何从 Razor 页面返回带有 HTTP 状态代码 500 的 JsonResult?

修复 URL 以返回带有 JsonResult 的下拉列表项 - MVC- C#

从工作灯适配器调用受密码保护的 URL 时如何输入用户凭据?

ASP.NET MVC:用JsonResult控制属性名的序列化。

简单的 JsonResult 在 Jquery ajax 方法上返回 parsererror