vlambda博客
学习文章列表

Django关于CSRF的顺便一提

目录

  1.  Django-CSRF问题

  2. 如何使用

  3. CSRF攻击是咋回事

  4. Token抵御CSRF攻击概述



Django在书写模板的时候,比如登录页,会出现这样的CSRF提示问题:

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

<body>
<h1>用户登录</h1>
<!--内部url,action="/myapp/..."-->
<form method="post" action="/myapp/login/">
    <input type="text" name="user" placeholder="用户名">
    <input type="password" name="user" placeholder="密码">
    <input type="submit" placeholder="提交">
</form>

</body>
</html>



我们只需要在html页面的form表单中添加csrf_token,带着表单的POST请求一起发送到服务器去验证:

<form method="post" action="/myapp/login/">
    <!-- 不加这句会有CSRF跨域问题,django有。Flask没有 -->
    {% csrf_token %}

    <input type="text" name="user" placeholder="用户名">
    <input type="password" name="user" placeholder="密码">
    <input type="submit" placeholder="提交">
</form>



结果发现:网页中隐性的input了相应的一串csrf_token随机数

<input type="hidden" name="csrfmiddlewaretoken" value="p5k.....IeW5">




CSRF攻击



黑客通过钓鱼网站诱使 Bob 来访问他的网站。当 Bob 访问该网站时,上述 url 就会从 Bob 的浏览器发向银行,而这个请求会附带 Bob 浏览器中的 cookie 一起发向银行服务器。大多数情况下,该请求会失败,因为他要求 Bob 的认证信息。但是,如果 Bob 当时恰巧刚访问他的银行后不久,他的浏览器与银行网站之间的 session 尚未过期,浏览器的 cookie 之中含有 Bob 的认证信息。这时,悲剧发生了,这个 url 请求就会得到响应,钱将从 Bob 的账号转移到黑客的账号,而 Bob 当时毫不知情。等以后 Bob 发现账户钱少了,即使他去银行查询日志,他也只能发现确实有一个来自于他本人的合法请求转移了资金,没有任何被攻击的痕迹。



防御策略:在请求地址中添加 token 并验证

CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中。

所以抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。


token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。


对于 POST 请求来说,要在 form 的最后加上 <input type=”hidden” name=”csrftoken” value=”tokenvalue”/>,这样就把 token 以参数的形式加入请求了。