简体   繁体   English

ASP.NET MVC - 关于GET请求的CSRF

[英]ASP.NET MVC - CSRF on a GET request

We have a ASP.NET MVC application. 我们有一个ASP.NET MVC应用程序。 All the POST requests (form submits) have been protected from CSRF by using @Html.AntiForgeryToken and ValidateAntiForgeryToken attribute. 通过使用@Html.AntiForgeryTokenValidateAntiForgeryToken属性,所有POST请求(表单提交)都已受到CSRF保护。 One of the action methods on a controller is a GET which returns a report to the user (a pdf file with data from database). 控制器上的一个操作方法是GET,它向用户返回一个报告(一个包含数据库数据的pdf文件)。 The signature is: 签名是:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetReport()
{
    // get data from db
    return GetReport();

}

Here are the steps I am following to test the CSRF against this operation: 以下是我要针对此操作测试CSRF的步骤:

  1. User logs into the application 用户登录到应用程序
  2. When logged in , user opens the below HTML file and clicks on the Submit button: 登录后,用户打开以下HTML文件并单击“提交”按钮:
  3. The report gets downloaded. 该报告已下载。

Questions: 问题:

Can this be considered a CSRF attack? 这可以被视为CSRF攻击吗?

If yes, how can it be mitigated? 如果是的话,如何减轻它? Since the action method is a GET request, how can I use MVC's CSRF approach (applying @Html.AntiForgeryToken and ValidateAntiForgeryToken on the action method). 由于action方法是GET请求,我如何使用MVC的CSRF方法(在action方法上应用@Html.AntiForgeryTokenValidateAntiForgeryToken )。

HTML File: HTML文件:

<html>
      <body>
        <form action="https://<baseurl>/Analysis/GetReport">
                <input type="submit" value="Submit request" />
            </form>
          </body>
</html>

In short, what you've just described is not an example of an XSRF attack... 简而言之,您刚才描述的并不是 XSRF攻击的一个例子......


What is an XSRF attack? 什么是XSRF攻击?

Both CSRF and XSRF are used to describe what's called a Cross Site Request Forgery . CSRFXSRF都用于描述所谓的Cross Site Request Forgery It's where a malicious website takes advantage of your authenticated state on another website, to perform fraudulent cross-site requests. 这是恶意网站利用您在其他网站上的身份验证状态来执行欺诈性跨网站请求的地方。

Example: Online banking. 示例:网上银行。

The Bank 银行

Imagine that you're authenticated on your bank's website, and that your banks website contains a form to create new transactions, all pretty straight forward... 想象一下,您在银行的网站上进行了authenticated ,并且您的银行网站包含一个用于创建新交易的form ,所有这些都很直接......

<!-- Malicious website -->
<form action="http://yourbank.com/send_moneh" method="POST">
    <input type="hidden" name="amount" value="100.00"/>
    <input type="hidden" name="accountNumber" value="123456" />
</form>
The Malicious website 恶意网站

Now let's think of the Malicious website you're also visiting, imagine that it also contains a form , one that is hidden and the values of which are pre-populated... 现在让我们想一下您正在访问的Malicious website ,想象它还包含一个form ,一个隐藏的form ,其值已经预先填充...

 <!-- Malicious website --> <form action="http://yourbank.com/send_moneh" method="POST"> <input type="hidden" name="amount" value="100.00"/> <input type="hidden" name="accountNumber" value="123456" /> </form> 

When the form on the malicious website is submitted, an HTTP request will be sent straight from you to your bank , and because you're authenticated on your bank's website, the transaction could be accepted. 当提交恶意网站上的表单时, HTTP request将直接从发送到您的银行 ,并且由于您在银行的网站上进行了身份验证,因此可以接受该交易。

Essentially, an attacker is using your own authentication against you by forging requests and using you as the messenger to deliver that request. 从本质上讲,攻击者通过伪造请求并使用您作为传递该请求的信使来使用您自己的身份验证。


How do prevent it? 怎么预防呢?

You use an anti-forgery token, this token is a string containing a random value, the token is placed in your cookies , in addition to your HTML forms. 您使用防伪令牌,此token是包含随机值的字符串,除了您的HTML表单之外,令牌也会放在您的cookies中。

When you receive a request, you validate that the form contains an anti-forgery token and that it matches the one stored in your cookies. 当您收到请求时,您将验证该表单是否包含防伪令牌,并且它与您存储在Cookie中的令牌相匹配。 A malicious site can not see the tokens your website sets on a client, and without this information, XSRF attacks are stopped in their tracks. 恶意站点无法看到您的网站在客户端上设置的令牌,如果没有此信息,XSRF攻击就会停止。


How do I implement it in ASP.NET MVC? 如何在ASP.NET MVC中实现它?

On your controller Action that will be handling the request, add the attribute [ValidateAntiForgeryToken] , and in the HTML form add (@Html.AntiForgeryToken()) . 在您的控制器上将处理请求的Action,添加属性[ValidateAntiForgeryToken] ,并在HTML表单中添加(@Html.AntiForgeryToken())

 public class ExampleController : Controller { [ValidateAntiForgeryToken] [HttpPost] public ActionResult Test(Foo fooModel) { // do your thing... return this.View(); } } <form action="/Example/test" method="POST"> @Html.AntiForgeryToken() <input type="text" name="bar" /> <input type="submit" value="Submit" /> </form> 

That's it! 而已!


Tips/Pointers/Advice 提示/指针/建议

Anti-Forgery Tokens don't make a lot of sense when performing GET requests, in fact, they don't make sense to have them anywhere that you're not modifying and persisting data, as any GET request will be returned to your user, not the attacker. 防伪代码在执行GET请求时没有多大意义,实际上,将它们放在您未修改和保留数据的任何地方都没有意义,因为任何GET请求都将返回给您的用户而不是攻击者。

If you're Creating, Updating or Deleting data... make sure that you're using it then. 如果您正在创建,更新或删除数据...请确保您正在使用它。

Ordinarily safe methods do not have to be protected against CSRF because they do not make changes to the application, and even if they're returning sensitive information this will be protected by the Same Origin Policy in the browser. 通常安全的方法不必受CSRF保护,因为它们不会对应用程序进行更改,即使它们返回敏感信息,也会受到浏览器中同源策略的保护。

If your site is implemented as per standards, your GET requests should be safe and therefore do not need protection. 如果您的站点是按照标准实现的,那么您的GET请求应该是安全的,因此不需要保护。

However, there is a specific case where a "Cross-Site DoS" * attack could be executed. 但是,存在可以执行“跨站点DoS” *攻击的特定情况。 Say your reporting page takes 10 seconds to execute, with 100% CPU usage on your database server, and 80% CPU usage on your web server. 假设您的报告页面需要10秒钟才能执行,数据库服务器上的CPU使用率为100%,Web服务器上的CPU使用率为80%。

Users of your website know never to go to https://<baseurl>/Analysis/GetReport during office hours because it kills the server and gives other uses a bad user experience. 您的网站用户知道在办公时间内永远不会访问https://<baseurl>/Analysis/GetReport ,因为它会导致服务器死亡并使其他用户体验不良。

However, Chuck wants to knock your <baseurl> website offline because he doesn't like you or your company. 但是, Chuck想要将你的<baseurl>网站脱机,因为他不喜欢你或你的公司。

On the busy forum he posts to often, http://forum.walkertexasranger.example.com , he sets his signature to the following: 在他经常发帖的繁忙论坛http://forum.walkertexasranger.example.com ,他将自己的签名设置为以下内容:

<img src="https://yoursite.example.org/Analysis/GetReport" width=0 height=0 />

He also knows that your company employees frequent the forum, often while also logged into yoursite.example.org . 他也知道贵公司的员工经常在论坛上,经常登录yoursite.example.org

Every time one of Chuck's posts are read by your employees, authentication cookies are sent to https://yoursite.example.org/Analysis/GetReport , so your site processes the request and generates the report, and your system goes offline because CPU is eaten by these constant requests. 每当您的员工读取Chuck的帖子之一时,身份验证cookie就会发送到https://yoursite.example.org/Analysis/GetReport ,因此您的站点会处理请求并生成报告,并且您的系统因为CPU而脱机被这些不断的要求吃掉了。

So even though the request is a GET request and doesn't make any permanent changes to your system (aka "safe"), it is infact bringing down your system every time it is ran. 因此,即使请求是GET请求并且不对系统进行任何永久性更改(也称为“安全”),它实际上会在每次运行时关闭系统。 Therefore, it would be better to protect this with some CSRF prevention methods. 因此,最好采用一些CSRF预防方法来保护这一点。 The easiest way would be to convert this so that the report can only be generated via a POST request and therefore the request can be validated via the AntiForgeryToken. 最简单的方法是转换它,以便只能通过POST请求生成报告,因此可以通过AntiForgeryToken验证请求。

*XSDoS, or Cross-Site Denial of Service, is a phrase coined by me, so don't go Googling for it. * XSDoS,或跨站点拒绝服务,是我创造的一个短语,所以不要去谷歌搜索它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM