专栏首页用户6517667的专栏软件安全性测试(连载6)

软件安全性测试(连载6)

2.2 CSRF注入

跨站请求伪造(Cross-Site Request Forgery:CSRF),也被称为 One-Click Attack 或者 Session Riding,是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。与跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

1. CSRF注入介绍

下面是一个典型的CSRF注入。

URL:http://www.mydomain.com/pay.jsp?user=Jerry&pay=100,表示Jerry给当前用户转了100元。那么黑客登录系统,构造这么一个URL:http://www.mydomain.com/pay.jsp?user=Tom&pay=10000000,表示Tom给当前用户(黑客)转了10,000,000元。

2. CSRF注入分类及攻击方法

CSRF注入可以分为GET注入和POST注入。

1)GET注入

在CSRF注入介绍介绍的就是GET注入,再看下面一个例子。

隐式链接

<ahref="http://www.mydomain.com/del_paper.jsp?id=5">删除</a>

显式链接

<imgscr=http://www.mydomain.com/del_paper.jsp?id=5 width="0"height="0">

均表示删除编号为5的文章。黑客可以通过Python的requests类编写接口代码进行攻击。

for i in range (10000):

payload={id:str(i)}

url= "http://www.mydomain.com/del_paper.jsp"

data =requests.get(url,params=payload)

攻击以后,系统中编号0到10000的文章都被删除。

2)POST注入

以下为一个程序的登录代码

<formclass="form-signin" method="post" action="/login_action/"onsubmit=javascript:check()>

<p>用户名: <input type="text"name="username" maxlength="100" requiredid="id_username"></p>

<p>密码 :<inputtype="password" name="password" requiredid="id_password"></p>

<input type= "submit" value= "提交" requiredid="id_password">

</form>

黑客可以通过Python的requests类编写接口代码,建立存放用户名和密码的文件:a.cvs,使用暴力攻击的办法进行破解。

在本地建立登录HTML,form的action改为绝对路径。

<formclass="form-signin" method="post" action="http://www.yourdomain.com/login_action/"onsubmit=javascript:check()>

<p>用户名: <input type="text"name="username" maxlength="100" requiredid="id_username"></p>

<p>密码 :<inputtype="password" name="password" requiredid="id_password"></p>

<input type= "submit" value= "提交" requiredid="id_password">

</form>

对这个代码建立对应的接口测试代码。

while True:

line=f.readline()

ifnot line:

break

username=line[0:line.rfind(',')]

password=line[line.rfind(','):]

self.driver.find_element_by_id("id_username").clear()

self.driver.find_element_by_id("id_username").send_keys(username)

self.driver.find_element_by_id("id_password").clear()

self.driver.find_element_by_id("id_password").send_keys(password)

self.driver.find_element_by_class_name("form-signin").submit()

如果a.cvs存在系统中的账号,暴力破解成功,否则失败。

3. CSRF注入测试方法

CSRF注入可以用CSRFTester工具进行测试,详细请参见本书下篇6.2.1节。

4. CSRF注入防护方法

1)CSRF Token技术

CSRF Token技术是在页面产生GET或POST请求之前,建立一个参数,以及一个cookie,参数的值与cookie的值是相等的,当HTTP请求传输到服务器端的时候,服务器会检查GET或POST请求参数是否与cookie的值相等,如果相等返回200代码,否则返货403代码。

下面介绍下Django中的django.middleware.csrf.CsrfViewMiddleware的工作原理。比如登录页面路径为/login_form/,登录成功页面路径为/login_action/。/login_form/的HTML代码为。

<form action="/login_action/">

<inputtype="hidden" value="1287A5666…"name="csrfmiddletoken">

</form>

在发送这个页面的同时,发送了一个cookie,内容为:{csrftoken:"1287A5666…"}。当HTML请求页面发送到服务器端,服务器进行验证名为csrfmiddletoken hidden中的内容与名为csrftoken的cookie内容是否相同,如果相同,返回200(OK)响应码,然后进入/login_action/,否则返回403(Forbidden)响应码。如13所示。

13 CSRF Token技术

ESAPI提供了ESAPI.httpUtilities().getCSEFToken来获取token值,通过调用ESAPI.randomizer().getRandomString(8,EncoderConstants.CHAR_ALPHANUMERICS)来生成CSRF Token值。

但是现在许多企业采用了前后端分离技术,前端处理HTTP渲染交互,后端负责向前端与数据库交互数据及业务处理,甚至在中间加入一个以Node.js的中间层,目的是解决效率与跨域问题。这样采用CSRF Token就无能为力了,解决的办法是在服务器端加入一个特殊处理模块,用于传递验证Token。见14中服务器的其他模块。(14来源于参考文献XXX)。

14 CSRF Token在前后端分离中的解决方案

2)其他方法

但是这个方法是防君子不防小人的,有经验的工程师可以构造接口测试代码,将cooiles的值与hidden中的值设置为一样的,然后提交,可以通过假Token绕过检查,代码如下。

def setUp(self):

self.correctusername="cindy"

self.correctpassword="123456"

self.discorrectusername="jerry"

self.discorrectpassword="000000"

self.url="http://127.0.0.1:8000/login_action/"

self.token= "RNF3Y04qFeJkMwCDsTMn4gfMcyfQ2vUjXbcENLADEFyCSRp1pBdezZKwHhlSwqgE"

self.cookie ={"csrftoken":self.token}

#正确的用户名,正确的密码

def test_login(self):

payload={"username":self.correctusername,"password":self.correctpassword,"csrfmiddlewaretoken":self.token}

data = requests.post(self.url,data=payload,cookies=self.cookie)

#验证返回码

self.assertEqual("200",str(data.status_code))

#验证返回内容

self.assertIn("电子商务系统" ,str(data.text))

解决这个问题的办法是:在token的基础上再加上Origin、Referer属性确定请求源与目的源是不是同源。另外还可以通过二次认证、验证码等方式解决。

本文分享自微信公众号 - 软件测试培训(iTestTrain),作者:顾翔

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于Django的电子商务网站开发(连载37)

    顾翔老师开发的bugreport2script开源了,希望大家多提建议。文件在https://github.com/xianggu625/bug2testscr...

    小老鼠
  • 基于Django的电子商务网站开发(连载39)

    顾翔老师开发的bugreport2script开源了,希望大家多提建议。文件在https://github.com/xianggu625/bug2testscr...

    小老鼠
  • LoadRunner12工具介绍(连载3)

    参数化的目的是模拟真实的用户操作来创建的结果。比如,要测试性能测试中一个查询功能,不可能每次都输入一样的值,LoadRunner提供了参数化功能,其原理如22所...

    小老鼠
  • 过去的未来:成为用户体验设计师

    ? 腾讯ISUX isux.tencent.com 社交用户体验设计 ? ? 现如今,在互联网领域,用户体验逐渐成为一个炙手可热的关键词,用户体验设计师也逐...

    腾讯ISUX
  • 前端上传文件到腾讯云(对象存储)

    好吧,没写之前简单的说一下为什么要写,我还是怀着比较沉重的心情写的这篇教程,主要是心里没底,不知道能写明白不,不过既然提笔了,那就硬着头皮写吧,没办法,毕竟跌跌...

    何处锦绣不灰堆
  • MYSQL 的表设计与使用,不要制造对立面

    一个表的设计,个人愚见,首先要看业务,以及你选择的架构,业务量是大还是小,业务是互联网性质的,还是传统性质的,业务是可变化较大的,还是比较固话的,等等,当然可能...

    AustinDatabases
  • IDA解析so文件异常(Binary data is incorrect maximum possible value is xx)

    小小咸鱼YwY
  • Sensory&SYNTIANT合作发布边缘侧超低功耗多语言语音交互解决方案

    Syntiant,领先的人工智能芯片创业公司,为边缘侧提供智能语音解决方案(intelligent voice solutions)。

    用户6026865
  • 记1例MySQL 8.0.15版本Bug引起的风波

    2016年09月12日,对于数据库领域来说是一个重要的值得纪念的日子,MySQL第一个DM(development milestone)版本8.0.0发布,这是...

    用户6543014

扫码关注云+社区

领取腾讯云代金券