相信前端开发工程师对CSRF(Cross-site request forgery)跨站请求伪造这个概念都非常熟悉,有的时候也简写成XSRF,是一种对网站的恶意利用。

尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户的请求来利用受信任的网站。

CSRF攻击的防御方式有多种,最简单最易实现的一种思路就是在客户端向服务器发起的请求中放入攻击者无法伪造的信息,并且该信息没有存储于 cookie 之中。技术上来说,当客户端向服务器发起请求执行一些敏感操作之前(比如用HTTP post实现的转账,扣款等功能),服务器端随机产生一个token,返回给客户端。客户端接下来的操作,必须在HTTP请求中以参数的形式把这个服务器端颁发的token带上。同时服务器端在实现给客户端分配token的同时,也要加入一个token校验机制。如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。这个token我们一般称为CSRF token。

讲了这么多,是为了引入本文想要讨论的话题。假设我想用jMeter测试一个OOdata服务创建Service Ticket的性能。因为创建功能不像读操作,执行之后会对系统产生持久化影响(Persistence side-effect), 因此服务器端的实现加入了CSRF token的校验。这就是说,如果我们直接用jMeter构造并发的HTTP post请求,是没有办法完成测试的,这些请求因为没有包含CSRF token,会被服务器端直接拒绝掉。

根据前面描述的CSRF攻防原理,CSRF token是服务器端随机生成的,客户端无法用任何技术进行伪造,因为为了测试接口HTTP post操作进行Service Ticket的创建,我们必须构造一个它的前置HTTP GET请求,专门用于得到服务器返回的CSRF token,然后再构造真正用于性能测试的HTTP POST请求,把第一步GET请求获得的CSRF token附到POST请求的头部中去。

本文介绍在jMeter里如何维护并配置这种具有依赖关系的一组请求。

当然如果您不喜欢用jMeter,想自己写代码实现,也是可以的。可以参考我放在github上的Java代码实现。

用jMeter的好处是不需要编程,通过简单的配置就能实现这个性能测试需求,一般没有开发背景的测试人员也能独立完成。

First let us have a look how JMeter could archive the same without even one line of programming.

My project in JMeter is displayed with the following hierarchy. I have configured with “Number of 5 threads” in my thread group, so once executed, the response time of these 5 threads are displayed in result table together with average response time.

从下图能看出,因为拿CSRF token的HTTP GET在逻辑上必须先于实际需要测试性能的HTTP POST请求,这实际上构成了一个Transaction-事务,所以我使用jMeter里提供的Transaction Controller来管理。

Some key points for this JMeter project creation

(1) Since now one thread should cover both XSRF token fetch via HTTP get and Service request creation via HTTP post, so a transaction controller is necessary to include both request.

(2) Create the first HTTP request to fetch XSRF token. The setting could be found below: adding a http header field with name as
x-csrf-token and value as “fetch”:

在HTTP GET请求的头部加上一个名为x-csrf-token的字段,值赋成fetch。这样服务器接到这个请求,就知道这是客户端发起的CSRF token请求,于是服务器响应这个请求,把创建好的随机CSRF token通过HTTP response头部字段的方式返回给客户端。

下一个问题就是,服务器返回给客户端合法的CSRF token后,jMeter如何读取到这个token,并用于接下来的请求?

幸运的是,jMeter提供了正则表达式提取式,可以让我们很方便地从HTTP响应结构中提取出token来。

Create a Regular Expression Extractor to parse the XSRF token from response header and stored it to a variable named “jerrycsrftoken”.

下图构造了一个jMeter正则表达式提取器,工作于HTTP响应的头部字段,解析出的token值存储于变量jerrycsrftoken中。

Before you continue, please make sure that the XSRF token is correctly parsed from request header, which could be confirmed by printing it out in a debug sample:

这个请求构造完之后,我们先试着运行一次,确保在变量jerrycsrftoken里确实看到解析好的CSRF token。

(3) Create another HTTP request with type POST.

这时万事俱备,我们可以开始构造真正要进行性能测试的HTTP post,即Service Ticket的创建请求了。

请求的报文正文:
Just paste the following text to the tab “Body Data”:

--batch_1
Content-Type: multipart/mixed; boundary=changeset_1--changeset_1
Content-Type: application/http
Content-Transfer-Encoding: binaryPOST ServiceRequestCollection HTTP/1.1
Content-Length: 5000
Accept: application/json
Content-Type: application/json{"ServicePriorityCode": "2",
"Name": {"content": "Jerry Testing ticket creation via JMeter ${uuid} "},
"ServiceRequestDescription": [
{"Text": "Piston Rattling 1 - Generic OData Test Create",
"TypeCode": "10004"
},
{"Text": "Piston Rattling 2 - Generic OData Test Create",
"TypeCode": "10007"
}
]
}
--changeset_1----batch_1--

In the body text I use a user-defined variable ${uuid} which we could create it in last step. And for this post request, use the XSRF token fetched from previous HTTP get request.

前面说过,POST请求的头部需要加上合法的CSRF token,此处我们使用前面GET请求已经拿到的并且存储于变量jerrycsrftoken中的token值:

我希望最后通过并发测试生成的Service Ticket的描述信息的后缀是1到100的随机正整数,因此我使用jMeter里自带的一个随机数发生器:

(4) As the last step, create a user variable by using JMeter built-in function __Random, to create a random number between 1 ~ 100 as a fragment of created Service Request description.

Now execute the Thread group, and the execution detail for these three HTTP request could be reviewed separately in tree view:

试着运行一下,发现这个POST操作确实按照我们期望的那样,在HTTP头部字段里加上了正确合法的CSRF token:

For example, the XSRF token is successfully fetched in the first request: rdPy7zNj_uKDYvQLgfQCFA==
And used as one header field in second HTTP Post request as expected:

And finally in UI we could find the created Service request with random number between 1 ~ 100 as postfix:

在UI上观测到我构造的5个并发请求创建的Service Ticket,说明CSRF token在服务器端的校验成功,同时发现描述信息都带上了随机数,说明我的jMeter随机数生成器的用法也正确。

希望本文对大家的工作有所帮助。

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

使用jMeter构造逻辑上有依赖关系的一系列并发请求相关推荐

  1. 类与类之间的关系:依赖关系和关联关系及继承关系中self是什么? 类里面的特殊成员...

    类与类之间的关系 ⼤千世界, 万物之间皆有规则和规律. 我们的类和对象是对⼤千世界中的所有事物进行归 类. 那事物之间存在着相对应的关系. 类与类之间也同样如此. 在⾯向对象的世界中. 类与类 中存在 ...

  2. 如何使用jMeter发送两个逻辑上相关的HTTP请求

    在前一篇文章使用jMeter构造大量并发的随机HTTP请求里我通过jMeter构造了大量的HTTP GET并发请求,对服务器产生了大量读操作. 现在我有另一个需求场景:假设我开发了一个创建Servic ...

  3. 90%的人都不知道的Node.js 依赖关系管理(上)

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 引言 Node.js中的一个重要概念是依赖关系管理.本文就将带大家了解依赖管理的各种模式以及Node.js如 ...

  4. Ubuntu上安装gtk2.0不能安装的问题,“下列的软件包有不能满足的依赖关系”

    zez@localhoss:~$ sudo apt-get install libgtk2.0-dev 正在读取软件包列表... 完成 正在分析软件包的依赖关系树        正在读取状态信息... ...

  5. java看不起c语言,为什么我感觉Java比C语言难呢?总觉得逻辑上没有C语言好理解。比如各种继承介面。包之间的关系。...

    为什么我感觉Java比C语言难呢?总觉得逻辑上没有C语言好理解.比如各种继承介面.包之间的关系.以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我 ...

  6. 【软件项目管理】任务(活动)之间的排序依据主要有:强制性依赖关系、软逻辑关系、外部依赖关系

    任务(活动)之间的排序依据主要有:强制性依赖关系.软逻辑关系.外部依赖关系. 项目各项任务(活动)之间存在相互联系与相互依赖关系,根据这些关系安排各项活动的先后顺序.确定任务(活动)之间关联关系的依据 ...

  7. RPM软件包管理 软件依赖关系 Yum软件的使用 上传与下载 时间设置 命令补充 zip归档工具

    环境准备 1.光盘文件放入挂载光驱设备 2.挂载光驱设备(临时挂载) mount /dev/cdrom /mnt ls /mnt ls /mnt/Packags 软件包一般都会以.rpm结尾 RPM软 ...

  8. 类继承和依赖注入的关系_管理类依赖关系:依赖关系注入,服务定位符和工厂简介,第1部分...

    类继承和依赖注入的关系 Let's face it: for good or bad, OOP has been actively drilling deep holes in the soil of ...

  9. 韩老师设计模式1:7原则。依赖关系3种方法。UML类图6关系。

    面试 1. 原型模式 1)有请使用UML类图画出原型模式核心角色2) 原型设计模式的深拷贝和浅拷贝是什么,并写出深拷贝的两种方式的源码(重写 clone方法实现深拷贝. 使用序列化来实现深拷贝)3) ...

最新文章

  1. Linux_RAID
  2. python创造者_python 设计模式-建造者模式
  3. SAP物料主数据采购视图采购价值代码设置
  4. mybatis-plus的代码生成器
  5. javafx按钮设计风格_Java,JavaFX的流畅设计风格按钮,切换按钮和工具提示
  6. 打卡学习 | Redis原理应用-线程IO模型
  7. Docker下安装GitLab
  8. ubuntu 修改默认用户名_Tars框架在Ubuntu上的部署小结
  9. 微服务注册中心为什么要使用Consul替代Eureka?
  10. js基础知识汇总01
  11. 计算机工程 目录 2014年第1期 pdf,2013科技核心期刊目录有效期至2014年).pdf
  12. 谈谈对三大框架的理解
  13. 如何快速的把JSON转Excel怎么转?
  14. python如何打开文件选择框_python文件选择对话框的操作方法
  15. 文献调研之如何查找文献及源码
  16. 嬴彻科技完成2.7亿美元融资 京东物流、美团、太盟投资集团联合领投
  17. 2020扁皮筋排名_CSCC2020赛季竞赛规则
  18. matlab 股票分时图_MATLAB怎样获取实时股市行情数据
  19. 新工作开始还是原来工作延续
  20. YzmCMS 5.2.X 文章发布模块及使用说明

热门文章

  1. Flying框架思路与感想
  2. JVM调优总结(七)-典型配置举例1
  3. PyTorch基础(part2)
  4. 分布式与人工智能课程(part11)--绘制词云图
  5. 文献记录(part54)--软件缺陷预测中基于聚类分析的特征选择方法
  6. Tableau研学小课堂(part1)--商业智能概述
  7. 精选6种制作酷炫动图的方法,收藏!
  8. 介绍一种找bug的方法
  9. SAP 电商云 Spartacus UI 代码提交的 commit 信息规范
  10. SAP Spartacus UI TabParagraphContainerComponent 的工作原理