使用带链接的MVC3 AntiforgeryToken?

时间:2011-12-30 09:18:44

标签: asp.net-mvc-3 antiforgerytoken

在我的MVC3网站上,我有一个包含多个链接的页面。这些链接都链接回我网站上的路线,具有不同的ID值,结构如下:

ie:www.mysite.com/links/33351/3

我想利用MVC3的antiforgerytoken机制,以便我可以确保从链接索引页面向www.mysite.com/links/33351/3发送所有请求。

我熟悉如何将令牌添加到表单中,但这些都是独立的链接。

我该如何做到这一点?

3 个答案:

答案 0 :(得分:3)

您不能将AntiForgeryToken用于GET请求(即单击链接)。有关详细信息,请参阅Using MVC3's AntiForgeryToken in HTTP GET to avoid Javascript CSRF vulnerability

一种解决方案是检查Request.UrlReferrer以确保它们来自您的索引页面,但这远非可靠。

也许您可以解释为什么要强制实施此限制,我或许可以提出替代方案。

答案 1 :(得分:2)

感谢上面的评论帮我解决了这个问题。

基本上,我创建了一个Javascript函数来处理项目点击。我页面上的每个链接都有一个ID,所以我只是将ID传递给提交表单的JS函数:

<script type="text/javascript"> <!--
    function doClick(itemID) {
        document.getElementById('hid_ItemID').value = itemID;

        // add whatever additional js type processing needed here - ie. analytics, etc.

        document.forms[0].submit();
    }
//-->
</script>

表单本身包含MVC防伪标记标记:

@using (Html.BeginForm("DoRequest", "DoItemClickRq", FormMethod.Post, new { target = "_blank" }))
{
    @Html.AntiForgeryToken()
    <input type="hidden" id="hid_ItemID" name="hid_ItemID" value="" />
.
.
.

控制器方法:

    [ValidateAntiForgeryToken]
    [HttpPost]
    public ActionResult DoItemRequest()
    {
        int itemListID = 0;
        int pagePositionNumber = 0;
        int.TryParse(Request["hid_ItemID"], out itemListID);

。 。

答案 2 :(得分:0)

  1. 对于良好的设计实践,可通过HTTP GET访问的应用程序中的所有URL都应该是幂等的,这意味着无论访问它们多少次,它们都不应更改状态。听起来这可能是您问题的根源,具体取决于“导航到链接执行某些维护”的解释。或者您可能会因维护而担心系统负载。这就是为什么CSRF方法通常避免处理GET请求的原因之一。
  2. 在会话ID中公开URL中的CSRF令牌是不好的安全措施。 URL可能会泄漏到日志文件,代理服务器中,特别是如果您的站点不使用100%SSL。
  3. 网络抓取工具是标准的乖巧的吗?如果是这样,为什么不使用robots.txt来约束抓取行为?

    如果这还不够,也许您需要施加某种工作流程限制以防止深层链接访问(例如,您的控制器会拒绝访问具有会话ID A而不经过步骤1和2的链接X)。