Django中的CSRF(跨站请求伪造)

Django中的CSRF(跨站请求伪造)

Django CSRF 

什么是CSFR

即跨站请求伪装,就是通常所说的钓鱼网站。
钓鱼网站的页面和正经网站的页面对浏览器来说有什么区别? (页面是怎么来的?)
钓鱼网站的页面是由 钓鱼网站的服务端给你返回的

正经网站的网页是由 正经网站的服务端给你返回的

CSFR示例

模拟钓鱼网站中的转账操作
通常用户在正规网站进行转账操作,网页页面由正规网站服务端提供,数据返回到正规网站的服务端,而钓鱼网站页面与正规网站页面无异,但是会将用户输入的数据进行修改后返回到正规网站的服务端。

正规网站的页面代码

<form action=“/transfer/” method=“post”>

&lt;p&gt;<br/>
    转账人:<br/>
    &lt;input type=&#34;text&#34; name=&#34;from&#34;&gt;<br/>
&lt;/p&gt;

&lt;p&gt;

    收款人:<br/>
    &lt;inputtype=&#34;text&#34;name=&#34;to&#34;&gt;<br/>
&lt;/p&gt;

&lt;p&gt;

    金额:<br/>
    &lt;input type=&#34;text&#34; name=&#34;money&#34;&gt;<br/>
&lt;/p&gt;

&lt;p&gt;

    &lt;input type=&#34;submit&#34; value=&#34;转账&#34;&gt;<br/>
&lt;/p&gt;<br/>

&lt;/form&gt;

注意: 正规网站的 form 表单中的action自然是返回给自己

钓鱼网站的页面代码

  1. &lt;formaction=“http://127.0.0.1:8000/transfer/&#34;method=&#34;post&#34;&gt; 
  2. &lt;p&gt; 
  3. 转账人: 
  4. &lt;input type=”text“ name=”from“&gt; 
  5. &lt;/p&gt; 
  6. &lt;p&gt; 
  7. 收款人: 
  8. &lt;inputtype=”text“name=”“&gt; 
  9. &lt;inputtype=”text“name=”to“value=”bad_guy“style=”display: none“&gt; 
  10. &lt;/p&gt; 
  11. &lt;p&gt; 
  12. 金额: 
  13. &lt;input type=”text“ name=”money“&gt; 
  14. &lt;/p&gt; 
  15. &lt;p&gt; 
  16. &lt;input type=”submit“ value=”转账“&gt; 
  17. &lt;/p&gt; 
  18. &lt;/form&gt; 

注意:

  1. 在钓鱼网站的 form 表单中将 action 设置的是正规网站的链接地址。
  2. 代码的第 9 10 行是关键所在,通过设置一个不可见的 input 标签来更改返回到正规网站服务端的数据。

Django 的应对措施

Django中内置了一个专门处理csrf问题的中间件

django.middleware.csrf.CsrfViewMiddleware

使用方式

在页面上 form 表单里面写上

{% csrf_token %}

例如:

&lt;form action=”/transfer/“ method=”post“&gt;

{% csrf_token %}<br/>
&lt;p&gt;<br/>
    转账人:<br/>
    &lt;input type=&#34;text&#34; name=&#34;from&#34;&gt;<br/>
&lt;/p&gt;

&lt;p&gt;

    收款人:<br/>
    &lt;input type=&#34;text&#34; name=&#34;to&#34;&gt;<br/>
&lt;/p&gt;

&lt;p&gt;

    金额:<br/>
    &lt;input type=&#34;text&#34; name=&#34;money&#34;&gt;<br/>
&lt;/p&gt;

&lt;p&gt;

    &lt;input type=&#34;submit&#34; value=&#34;转账&#34;&gt;<br/>
&lt;/p&gt;<br/>

&lt;/form&gt;

这个中间件做的事情:

  1. 在render返回页面的时候,在页面中塞了一个隐藏的input标签
  2. 当提交POST数据的时候,它帮你做校验,如果校验不通过就拒绝这次请求
csfr添加的隐藏的 input 标签