GitLab Dogfooding 实践:Web API 模糊测试

news/2024/11/8 17:13:36/

本文来源:about.gitlab.com

作者:Eugene Lim,Mike Eddington

译者:极狐(GitLab) 市场部内容团队

在极狐GitLab/GitLab 内部,我们用 Dogfooding 文化来帮助更好地理解产品、解决痛点以及配置错误,构建一个更高效、功能更丰富、用户体验更好的平台。本文将聚焦在「API 模糊测试」的 Dogfooding 实践上。

什么是 Web API 模糊测试


Web API 模糊测试(Web API Fuzz Testing)主要通过生成大量随机但符合一定语法规则的输入,来对 Web API 进行测试。这种 “随机输入” 可能会触发 API 的一些意料之外的执行路径或错误,从而发现 API 设计或实现中的某些漏洞或错误。

通过分析这些错误,可以发现缺陷和潜在安全问题,而这些问题可能是聚焦特定漏洞的安全扫描工具所遗漏的。极狐GitLab/GitLab Web API 测试是其他安全手段,如静态应用程序安全测试(SAST)、动态应用程序安全测试(DAST)等的有效补充。

自动生成 OpenAPI 规范


运行 Web API 模糊测试分析器,需具备以下条件之一:

  • OpenAPI 规范 - v2 或 v3;

  • GraphQL 模式;

  • HTTP 存档 (HAR);

  • Postman Collection - v2.0 或 v2.1。

在 API 模糊测试项目初始阶段,API Vision 工作组也在研究「如何在 OpenAPI 规范中自动生成 GitLab REST API endpoint」。因为 GitLab 使用 Grape API 框架,我们已经识别并测试了 grape-swagger gem,它可以基于既有 grape 注释自动生成 OpenAPI v2 规范。

例如,以下 API 端点代码:

 Class.new(Grape::API) doformat :jsondesc 'This gets something.'get '/something' do{ bla: 'something' }endadd_swagger_documentationend

会被 grape-swagger 解析为:

{// rest of OpenAPI v2 specification…"paths": {"/something": {"get": {"description": "This gets something.","produces": ["application/json"],"operationId": "getSomething","responses": {"200": {"description": "This gets something."}}}}}
}

然而,由于有 2000 多个不同的需求和格式的 API 操作,需要做大量额外工作来解决不满足 grape-swagger 需求或 OpenAPI 格式的边缘例子。一个最简单的例子就是接受文件参数的 API 端点,比如上传指标图片端点(metric image endpoint)。极狐GitLab/GitLab 使用 Workhorse 智能反向代理来处理 “大型” HTTP 请求,如文件上传

在这种情况下,文件参数必须是 WorkhorseFile 类型:

namespace ':id/issues/:issue_iid/metric_images' do…desc 'Upload a metric image for an issue' dosuccess Entities::IssuableMetricImageendparams dorequires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The image file to be uploaded'optional :url, type: String, desc: 'The url to view more metric info'optional :url_text, type: String, desc: 'A description of the image or URL'endpost dorequire_gitlab_workhorse!

因为 grape-swagger 并不能识别 WorkhorseFile 对应的 OpenAPI 类型,它会将该参数从输出中排除。我们通过在生成过程中添加特定的 grape-swagger 文档来修复该问题:

requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: \
'The image file to be uploaded', documentation: { type: 'file' }

但是,并不是所有边缘例子都能够在 grape 注释中通过简单匹配替换来解决。比如,Ruby on Rails 主要支持通配符片段参数,像路由 books/*section/:title 会匹配到 books/some/section/last-words-a-memoir

此外,URL 将会被解析,以便成 section 路径参数的值为 some/section 且 title 路径参数的值为 last-words-a-memoir

当前,grape-swagger 不能将这些通配片段识别为路径参数,上述路由会生成:

"paths": {"/api/v2/books/*section/{title}": {"get": {..."parameters": [{"in": "query", "name": "*section"...}
}

而不是期望的:

"paths": {"/api/v2/books/{section}/{title}": {"get": {..."parameters": [{"in": "path", "name": "section"...}
}

因此,我们依旧需要为 grape-swagger 打几次补丁。目前,已经可以实现为绝大多数端点自动生成 OpenAPI 规范。

性能调优


有了 OpenAPI 规范,现在可以开始 API 模糊测试了。极狐GitLab/GitLab 使用 Review App 功能为某些特性变更生成测试环境,提供可用的模糊测试目标。

但对于大量给定端点,不能期望一个标准共享 Runner 能在单个 Job 中完成模糊测试。Web API 模糊测试文档包含了性能调优部分,推荐以下操作:

➤ 使用多 CPU Runner

通过使用一个专用模糊测试 Runner 来实现。例如大型计划中的模糊测试工作流,特别是选择了 Long-100 模糊测试配置文件。

➤ 排除慢操作

通过检查 Job 日志中每个操作所花费的时间,借此排除慢操作。在这个过程中,还可以识别其他需要排除的端点,例如过早结束模糊测试会话的撤销令牌端点。

➤ 将测试分割为多个 Job

由于 OpenAPI 格式要求,将测试拆分为多个 Job 花费了最多的精力。

每个 OpenAPI 文档都包含了一系列必填对象和字段,因此不仅仅是根据固定行数进行简单拆分,每个操作还对定义对象中的条目有依赖,需要确保在拆分 OpenAPI 规范时,需要包含端点所需条目。因此,我们编写了一个快速脚本,用来将自测试环境中的实际数据填入示例参数数据,比如项目 ID。

➤ 排除特性分支而非默认分支中的操作

虽然可以在本地运行这些脚本,将拆分作业和 OpenAPI 规范推送到存储库,但每次更新原始 OpenAPI 规范时都会产生大量更改。因此,我们调整了工作流以使用动态生成的子管道,这些管道将在 CI 作业中拆分 OpenAPI 文档,然后为每个拆分文档生成一个包含作业的子管道。这使得迭代变得容易许多而且更加敏捷。我们已经将脚本和流水线配置进行了上传,欢迎参阅。

通过调整并行作业的数量和模糊测试配置,最终我们在可接受的时间范围内,实现了相当全面的模糊测试会话。

对 API 模糊测试结果进行分级处理


完成模糊测试后,现在需要面对数百个发现结果。不同于检测特定漏洞的 DAST 分析器,Web API 模糊测试找寻测试非期望的行为和错误,它们不一定是漏洞。这也就是为什么由 API 模糊测试分析器发现的错误,严重等级会被标记为"Unknow",等待更深入的分级处理。

幸运的是,Web API 模糊测试会在漏洞页面中将 Postman 集合以制品形式输出。这些集合允许用户快速重复在模糊测试期间触发故障的请求。在模糊测试工作流阶段,建议设置一个应用程序本地实例,以便轻松查看日志和调试特定故障。

很多故障的发生都是因为缺乏对意外输入的处理。我们可以从漏洞报告界面直接创建 Issue,并且如果发现特定故障和之前处理过的故障有相同根因时,可以将此漏洞直接链接到原始 Issue 上。

我们学到了什么


API 模糊测试 Dogfooding 项目被证明是一项富有成效的实践:

  • 使极狐GitLab/GitLab 其他工作流程受益,诸如 API 文档项目;

  • 调优和分级处理,帮助识别和改进了流程痛点;

  • 即使有 OpenAPI,自动地生成 API 文档也是困难的,特别是针对一个存在时间很长的代码库。极狐GitLab/GitLab 的既有注释及测试通过跨多个团队之间的分布式、异步协作加速了文档编制速度;

  • 很多极狐GitLab/GitLab 功能特性,诸如 Review App、漏洞报告以及动态生成子流水线帮助构建起了一个健壮的模糊测试工作流。

针对工作流依旧还有可以改进的地方。迁移到 OpenAPI v3 可以提高 endpoint 的覆盖率;安全团队也在写一个 HAR Recorder 的工具来帮助实时生成 HAR 文件,而不仅仅依赖静态文档等。

对于已经实施多层静态和动态检查并希望采取进一步措施来增加覆盖率的团队,建议尝试将 Web API 模糊测试,以此来验证假设并发现代码中的 “unknow unkonw”。


http://www.ppmy.cn/news/85179.html

相关文章

数据库学习2

加密函数 SELECT USER() FROM DUAL;--用户ip地址 SELECT DATABASE();--查看当前数据库名称 SELECT MD5(hsp) FROM DUAL;--为字符串算出32字符串,常用加密 SELECT LENGTH(MD5(hsp)) FROM DUAL; CREATE TABLE hsp_user( id INT, name VARCHAR(32) NOT NULL DEFAULT ,…

ES6:var 、const、let的使用和区别

前言 本文主要介绍了ES6中var、const、let的使用和区别 基本介绍 let let声明变量 const const :声明常量const声明的常量可以修改,但不能重新赋值 如:以下代码是正确的: //引用数据类型 const info {name:Candy }; info.nameJune;而下面的代码是…

AWS设备自定义身份认证

AWS设备自定义身份认证需要通过lambda服务实现,具体来说,首先需要创建一个lambda函数,在函数中实现具体的认证逻辑,然后Iot在调用授权方时,将触发lambda函数,返回认证结果。 1.输入参数说明 授权方在调用…

[论文评析]mixup: B EYOND E MPIRICAL R ISK M INIMIZATION, ICLR 2018,

mixup: B EYOND E MPIRICAL R ISK M INIMIZATION 介绍MixupMixup的提出动机Mixup与常规数据增广方法的区别References 介绍 采用ERM训练的模型往往存在泛化能力差的情形-可能是在简单的记忆样本, 对于噪声干扰的鲁棒性很差. 这篇论文提出了一种新的数据增广方法-Mixup, 这里主…

字符串、字符串列表,倒序生成字典。

带数字的字符串以数字为key倒序生成字典,字符串列表按其元素索引为key倒序生成字典。 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简…

飞鲨展览:2023山东老博会,11月移师济南黄河国际会展中心

新展馆、新起点、新征程-CSOLDE2023第5届中国(济南)国际养老服务业展览会2023 Fifth China (Jinan) International Old-age Services Exhibition,移师济南黄河国际会展中心举办的通告 尊敬的参展商、观众、媒体及行业人士: 为了更…

二进制部署高可用k8s集群

第一章、前置知识点 1.1 生产环境部署K8S集群的两种方式 kubeadm Kubeadm是一个K8S部署工具,提供kubeadm init 和 kubeadm join,用于快速部署Kubernetes集群。 二进制包 从GitHub下载发行版的二进制包,手动部署每个组件,组成…

day05 java_Spring IoC 和 DI

为什么使用spring框架 1.解耦代码(每次使用都要new一个对象) 2.解决事务繁琐问题(创建对象----初始化----调用方法销毁对象) 3.使用第三方框架麻烦的问题 总结:spring是一个轻量级的Ioc,Di和AOP容器 轻量级:简洁,高效,低依赖 **容器:**创建对象并将对象存储对象,同时管理…