2 处理CSRF token步骤 通过2-10的介绍,我们发现启用CSRF token开关后,录制脚本返回403没有权限访问的响应码,这节我们来介绍一下如何解决这个问题。 要解决这个问题,我们首先来介绍一下CSRF攻击以及CSRF token原理。 2.1 CSRF攻击 对于一个网站,比如登录功能,为了防止暴力破解或者DDoS攻击,往往采取连续输入5次错误的用户名或密码后,封锁这个账号,只能等到一个小时甚至第二天才可以重新登录的方法,其HTML代码可能是如下。
代码语言:javascript复制<form method="post" action="/login_action/"
onsubmit=javascript:check()>
….
<form>
其中javascript:check()函数就用来防止暴力破解或者DDoS攻击的。在这种情况下,黑客可以把这段form程序拷贝下来,在自己的机器上建立一个HTML文件,把action路径改为绝对路径。
代码语言:javascript复制 <form method="post" action="http://www.mydoman.com/login_action/">
….
<form>
其中http://www.mydoman.com为攻陷网站所处的域名。这样没有JavaScript来防止暴力破解或者DDoS攻击了,这就是CSRF攻击。 2.2 CSRF token原理 为了防止CSRF攻击。有人想出了CSRF 令牌(token)的方法。当浏览器向服务器发送一个POST请求的时候,发送一个随机固定长度类型为hidden的字符串,同时向服务器发送一个cookie,其值应该与POST请求hidden的字符串一致。当服务器接受到POST请求拿到hidden的字符串后,再检查是否有一个指定名称的cookie,二者的值如果一致,表示不存在CSRF攻击,返回200响应码,否则表示存在CSRF攻击,返回403响应码。如图3所示。
图3 CSRF token原理
POST请求hidden的名称为csrfmiddlewaretoken;cookie的名为csrftoken。服务器接受到POST请求,比对这两个值,如果一致返回200响应码;否则返回403响应码。试想一下对于。
代码语言:javascript复制<form method="post" action="http://www.mydoman.com/login_action/">
….
</form>
可以在里面加一行。
代码语言:javascript复制<form method="post" action="http://www.mydoman.com/login_action/">
<input type="hidden" name="csrfmiddlewaretoken" value="EBE0TZyDmX7zm858DktM2UktS489URIhI6UiwXh5lCN8kjrejzRRcUypUu75oDdV">
….
</form>
但是不用特殊的方法产生不了名为csrftoken的cookie,从而防止了CSRF攻击。 2.3 处理CSRF token步骤 解决CSRF token的方法是通过“正则表达式提取器”从登录HTTP请求中获取随机产生的字符串放入一个变量中,然后建立一个HTTP cookie管理器,设置一个名“csrftoken”为其值为获取的变量,同时设置POST请求的hidden字段也为这个变量。具体操作步骤如下。 1)右键点击登录HTTP请求,在弹出菜单中选择“添加->后置处理器->边界提取器”。按照图4中进行设置。
图4 边界提取器
- 把名称改为:获取csrftoken。
- Apply选择默认值:Main sample only。
- 要检查的响应字段选择默认值:主体。
- 引用名称输入:csrftoken。为获取到的参数名。
- 左边界输入:name="csrfmiddlewaretoken"value="
- 右边界输入:">。
- 匹配数字输入:1。(1表示第1个匹配项;2表示第2个匹配项;...;n表示第n个匹配项;0表示随机由JMeter分配一个匹配项;负数表示获得所有的匹配项)。
- 缺省值输入:null。
你可以从察看结果树中登录HTTP请求响应数据中的Response Body中获取。如图5所示。或者在浏览器上查看登录页面的源代码。
图5 通过察看结果树获取正则表达式提取器
2)右键点击登录HTTP请求,在弹出菜单中选择“添加>配置元件>HTTP Cookie管理器”。按照图6中进行设置。
图6 设置csrftoken cookie信息
- 修改名称为:设置csrftoken cookie信息。
- 确认类型为:standard。
- 加入一个cookie,名称由Fiddle抓包获得,为:csrftoken。值为上一步引用名称设置:${csrftoken}。
3)进入商品列表HTTP请求。把名称为csrfmiddlewaretoken的字段值也设为${csrftoken},以便于cookie的值保持一致。见图7所示。
图7 设置csrfmiddlewaretoken字段值
4)运行测试用例,点击“察看结果树”,如图5-8所示,全绿,表示配置成功。
图8 处理CSRF token配置成功
由于商品列表HTTP请求中我们设置的是跟随重定向,所以在这里显示了商品列表-0和商品列表-1。商品列表-0是http://192.168.1.3:8000/login_action/,检查用户名密码是否正确,如图9所示。商品列表-1才是检查正确后重定向到商品列表页面http://192.168.1.3:8000/goods_view/,如图10所示。
图9 login_action请求体
图10 goods_view请求体
查看调试取样器,如图11所示。我们可以获得正则表达式提取器设置的参数结果。
图11 获得正则表达式提取器设置的参数
代码语言:javascript复制csrftoken=Y7z9WwddMR7VCBwoW91nPGXIb9XOb0RWiJYrHBO9FuT4zwKWSyME6oT23SYW4VbX
csrftoken_g=1
csrftoken_g0=name="csrfmiddlewaretoken"
value="Y7z9WwddMR7VCBwoW91nPGXIb9XOb0RWiJYrHBO9FuT4zwKWSyME6oT23SYW4VbX">
csrftoken_g1=Y7z9WwddMR7VCBwoW91nPGXIb9XOb0RWiJYrHBO9FuT4zwKWSyME6oT23SYW4VbX
password=8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
username=cindy
- csrftoken为提取到的变量。
- csrftoken_g为提取到的变量个数,这里为1。
- csrftoken_g0为设置的name="csrfmiddlewaretoken"value="(.?)",其中(.?)为获取到的csrftoken值。
- csrftoken_g1为获取到第一个的变量值,在这里与csrftoken一致。
- password为发送的密码(已经进行了SHA-256散列)。
- username为发送的用户名。
关于边界提取器将在第5.2-2节进行详细介绍。