zoukankan      html  css  js  c++  java
  • Nancy启用跨站攻击防护(CSRF)

    什么是CSRF(跨站攻击)

    可能很多人已经对CSRF有所了解,就简单的介绍下:

    CSRF全程是 Cross-Site Request Forgery 。大概意思就是在登录用户不知情的情况下,由一个网站对已经登录的另外一个网站发送请求。

    为了保证请求是来自我们自己的网站,在表单的隐藏域中添加一个唯一的值,这个值被成为 AntiForgeryToken。

    如果你想详细的了解下CSRF,你可以看下百度百科

    CSRF和Nancy

    正如Nancy的其他功能,你不可能在默认情况下就能获得一个完整的解决方案。由于Nancy是轻量级、自由开发的,我们还是需要付出一点努力才能使用CSRF防护。

    1. 在Bootstrapper中启用CSRF防护支持
    2. 在应用的每一个Form中添加AntiForgeryToken
    3. 使用Nancy内置的方法ValidateCsrfToken验证CSRF票据
    4. 处理Nancy无法接收正确票据的请求

    启用CSRF

    如果没有创建就创建一个NancyDefaultBootstrapper类,添加下面的代码到ApplicationStartup()方法中

    Nancy.Security.Csrf.Enable(pipelines);

    我们的Bootstrapper如下:

    using Nancy;
    using Nancy.Bootstrapper;
    using Nancy.TinyIoc;
    
    namespace NancyCsrfDemo
    {
        public class Bootstrapper : DefaultNancyBootstrapper
        {
            protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
            {
                base.ApplicationStartup(container, pipelines);
                Nancy.Security.Csrf.Enable(pipelines);
            }
        }
    }

    在表单中添加AntiForgeryToken

    如果你采用的是Razor视图引擎,视图文件应该是下面的样子:

    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title></title>
    </head>
        <body>
            <h1>Welcome to Nancy CSRF Demo, @ViewBag.Name</h1>
            <form action="/" method="POST">
                Name:<br/>
                <input type="text" name="name" value="@ViewBag.Name" />
                <input type="submit" />
                @Html.AntiForgeryToken()
            </form>
        </body>
    </html>

    如果采用的是SSVE (The Super Simple View Engine)

    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title></title>
    </head>
        <body>
            <h1>Welcome to Nancy CSRF Demo, @Model.Name</h1>
            <form action="/" method="POST">
                Name:<br/>
                <input type="text" name="name" value="@Model.Name" />
                <input type="submit" />
                @AntiForgeryToken
            </form>
        </body>
    </html>

    不管使用那个引擎,都会在表单中生成一个隐藏域

    <input type="hidden" name="NCSRF" value="AAEAAAD/////AQAAAAAAAAAMAgAAAD1OYW5jeSwgVmVyc2lvbj0wLjIyLjIuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBQEAAAAYTmFuY3kuU2VjdXJpdHkuQ3NyZlRva2VuAwAAABw8UmFuZG9tQnl0ZXM+a19fQmFja2luZ0ZpZWxkHDxDcmVhdGVkRGF0ZT5rX19CYWNraW5nRmllbGQVPEhtYWM+a19fQmFja2luZ0ZpZWxkBwAHAg0CAgAAAAkDAAAAOrVPNrYs0YgJBAAAAA8DAAAACgAAAAI4qmisW7sYu2FlDwQAAAAgAAAAAsdnVjuuU1fzpb58LEjF1pcK98u9ENMjG0viyxLpvlv/CwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="/>

    校验Token

    当用户点击按钮的时候,浏览器就会向后台发送 AntiForgeryToken/CSRF 票据。

    Nancy有一个内置方法ValidateCsrfToken,这个方法会自动检测隐藏域Request.Form.Ncsrf,如果票据不对会报错异常:CsrfValidationException

    异常会默认返回一个500错误,我们需要捕捉这个异常,并进行一些处理:

    using Nancy;
    using Nancy.Security;
    
    namespace NancyCsrfDemo
    {
        public class HomeModule : NancyModule
        {
            public HomeModule()
            {
                Get["/"] = p =>
                {
                    return View["Index"];
                };
    
                Post["/"] = p =>
                {
                    try
                    {
                        this.ValidateCsrfToken();
                    }
                    catch (CsrfValidationException)
                    {
                        return Response.AsText("Csrf Token not valid.").WithStatusCode(403);
                    }
                    
                    ViewBag.Name = Request.Form.Name;
                    return View["Index"];
                };
            }   
        }
    }

    这样如果票据没有验证通过的话,用户就会收到一个 403禁止访问错误,而不是500错误。

  • 相关阅读:
    POJ 1753(1)
    2015.12 杭电校赛 Bitwise Equations
    codeforces B
    POJ2387 水水最短路
    CodeForces 337C SDUT秋季训练--周赛(10.31)
    HDU 1241
    POJ 3126 Prime Path
    HDU 2612
    POJ 1426 Find The Multiple
    day94 flask-session 表单验证 信号 SQLALchemy
  • 原文地址:https://www.cnblogs.com/lilunjia/p/6885891.html
Copyright © 2011-2022 走看看