tornaod十:XSRF跨站请求伪造

针对跨站请求伪造,通常设置XSRF保护。

XSRF保护:同源策略保护。

XSRF设置:在settings中配置

#config.py
# 配置,同django.settings
settings = {
    "xsrf_cookies": True,
}

 

xsrf_cookies设置为True的时侯,开启XSRF保护;False,关闭XSRF保护。

当开启XSRF保护后,所有的访问都将访问不了,包括同源访问。

 

XSRF保护应用:

1.在模板中应用:在模板中加上 {% module xsrf_form_html() %}

  原理、作用:1).为浏览器设置了名为"_xsrf"的安全cookie,这个cookie在关闭浏览器后失效;2).为模板表单添加了一隐藏域,名为_xsrf,值为_xsrf这个cookie的值。

  开启模板应用后,同源将可以访问。

添加的隐藏作用域为:

    <input type="hidden" name="_xsrf" value="234sfasdf">

 

2.在非模板中应用

原理同在模板中应用一样,仿照上面用脚本生成一个同样的隐藏作用域。

第一种方式:

1).在模板中应用,会自动设置名为"_xsrf"的cookie。在非模板中应用,需要手动设置名为"_xsrf"的cookie

            # 手动设置xsrfCookie
            (r'/setxsrfcookie', index.SetXSRFCookieHandler),

 

class SetXSRFCookieHandler(RequestHandler):
    def get(self, *args, **kwargs):
        # 这种方式需要自己设置一个value
        # self.set_secure_cookie("_xsrf", "value")
        # 第二种方式,会自动设置value,且名为_xsrf的cookie
        self.xsrf_token
        self.finish("ok")

 

2).在模板中,添加脚本,生成一个上面同样的隐藏作用域。

手动创建一个name为"_xsrf",value从浏览器获得的xsrf的value值,的隐藏作用域input。

<form action="/postfile", method="post">
    <input type="hidden" id="hi" value="">
    <input type="text", name="username">
    <hr/>
    <input type="password", name="pwd">
    <hr/>
    <input type="submit" value="登录">
    <script>
        function getCookie(name) {
        var ck = document.cookie.match("\\b" + name + "=([^:]*)\\b")
        return ck ? ck[1] : undefined
        }
        document.getElementById("hi").value = getCookie("_xsrf")
    </script>
</form>

 

访问站点,在浏览器中查看xsrfcookie及其值。

在模板中查看一下xsrfcookie,是否可以获取到,并与浏览器的值比较是否相等。

        console.log(getCookie("_xsrf"))

 

 

第二种方式:

上面,只是说明了原理。通常,不会使用上面的手动设置的方式;通常,发起ajax请求,点击某个按钮(如login事件),执行某个脚本方法。

使用ajax语法,或者使用jquery。

使用jquery,放在static/js/jquery.min.js。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script type="text/javascript" charset="utf-8" src="{{ static_url('js/jquery.min.js')}}"></script>
</head>
<body>
<h1>第{{ count }}访问</h1>

    <input type="hidden" id="hi" value="">
    <input type="text", name="username">
    <hr/>
    <input type="password", name="pwd">
    <hr/>
    <input type="submit" value="登录">
    <button onclick="login"></button>
    <script>
        function getCookie(name) {
        var ck = document.cookie.match("\\b" + name + "=([^:]*)\\b")
        return ck ? ck[1] : undefined
        }
        function login() {
            console.log("***查看点击成功")
            // _xsrf=asdfkj234ka&username=jerry&pwd=234234
            // 实际中,用户名和密码用变量代替
            $.post("/postfile", "_xsrf="+getCookie('_xsrf')
            +"&username="+"jerry"+"&pwd="+234234", function(data){
                alert("ok")
            })
            }
    </script>
</body>
</html>

 

 

以上第二种方式:就是在开启XSRF保护后,在发起ajax请求的时侯,带上_xsrf的cookie,并生成第一种方式中产生的同样的隐藏域。

建议使用ajax:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script type="text/javascript" charset="utf-8" src="{{ static_url('js/jquery.min.js')}}"></script>
</head>
<body>
<h1>第{{ count }}访问</h1>

    <input type="hidden" id="hi" value="">
    <input type="text", name="username">
    <hr/>
    <input type="password", name="pwd">
    <hr/>
    <input type="submit" value="登录">
    <button onclick="login"></button>
    <script>
        function getCookie(name) {
        var ck = document.cookie.match("\\b" + name + "=([^:]*)\\b")
        return ck ? ck[1] : undefined
        }
            // _xsrf=asdfkj234ka&username=jerry&pwd=234234
            // 实际中,用户名和密码用变量代替
            function login() {
                data = {
                    "username": "jerry",
                    "pwd": "234234"
                }
                var dataStr = JSON.stringify(data)
                // 使用ajax发送一个post请求
                $.ajax({
                    url: "/postfile",
                    method: "POST",
                    data: dataStr,
                    success: function(data){
                        alert("ok")
                        },
                    headers: {
                        "X-XSRFToken": getCookie("_xsrf")
                    }
                })
            }
    </script>
</body>
</html>

 

通常,在首页或登录页设置xsrf。

示例:在首页设置xsrf

重新静态加载文件StaticFileHandler的__init__方法,将生成xsrf Cookie加入init;并设置首页路由。最后,使用上面的方法,在模板中或非模板中应用XSRF。

            # (r'/(.*)$', tornado.web.StaticFileHandler,
             (r'/(.*)$', index.StaticFileHandler,
             {"path": os.path.join(config.BASE_DIRS, "static/html"),
              "default_filename": "html/index.html"})
class StaticFileHandler(tornado.web.StaticFileHandler):
    def __init__(self, *args, **kwargs):
        super(StaticFileHandler, self).__init__(*args, **kwargs)
        self.xsrf_token

 

posted on 2018-07-31 21:32  myworldworld  阅读(305)  评论(0)    收藏  举报

导航