干货!GitLab Dogfooding实践

GitLab Dogfooding 实践:Web API 模糊测试

在极狐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) do
   format :json
   desc 'This gets something.'
   get '/something' do
     { bla: 'something' }
   end
   add_swagger_documentation
 end

会被 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' do
              success Entities::IssuableMetricImage
            end
            params do
              requires :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'
            end
            post do
              require_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 文档,然后为每个拆分文档生成一个包含作业的子管道。这使得迭代变得容易许多而且更加敏捷。我们已经将脚本和流水线配置进行了上传,欢迎参阅。

上传的脚本和流水线配置:

https://gitlab.com/eugene_lim/api-fuzzing-dogfooding/?_gl=1%2aj5vaiv%2a_ga%2aMTA1MjA4NTY0LjE2MzQ4MDA1NDU.%2a_ga_ENFH3X7M5Y%2aMTY4NDc0MzYxNy4zNDUuMS4xNjg0NzQ0Njc1LjAuMC4w

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

对 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”。

本文来源:about.gitlab.com

作者:Eugene Lim,Mike Eddington

#极狐Gitlab##技术栈##开发##我的成功项目解析#
全部评论

相关推荐

不愿透露姓名的神秘牛友
05-29 22:21
Offer1:小马智行,深圳,测试开发工程师,17.0k*16.0,Offer2:追觅科技,深圳,嵌入式工程师,18.0k*15.0,
嵌软狗都不学:各位base深圳的同事,作为也是并肩作战的一员,今天想站在管理视角,和大家开诚布公地聊一聊:从近几个月的上下班数据对比看来,我们发现一个明显的差异:深圳同事的在岗时间普遍比苏州同事短。很多深圳同事早上9点之后才到公司,晚上不到 20 点就下班了;而总部那边,20点半甚至 22 点后还有不少同事在办公室忙碌,特别是研发团队,加班更是常态。相信去过苏州的同事,对这种场景都不陌生。我很好奇,这是因为苏州工作任务太重还是咱们深圳同事效率真的高到能在更短时间内完成工作?MOVA在深圳成立分公司是为了吸引更优秀的人才贡献更多更高质的价值,公司管理层给我反馈的是深圳招到的多是行业的专家大拿,大部分都是薪资比苏州高的,而且我们办公的租金等也远高于苏州的..MOVA虽脱胎于强壮的集团母体不久,各业务板块尚未实现全面盈利,虽说公司管理层目光长远,不纠结当下的人才投入,但行业内的普遍标准是,员工创造的价值要达到公司雇佣成本的 15 倍以上。大家不妨自我审视一下,自己是否达到了这个标准?如果是抱着划水、按时打卡走人拿毛爷爷的心态那不适合来MOVA,那样过下去不但自己过得尴尬也会影响MOVA这个大船的攻城略地的速度.我并非鼓励大家盲目加班,而是倡导高效工作,拒绝无效忙碌,不要让项目进度因低效受影响,也别把精力浪费在和苏州同事拼打卡时长上,提倡更高的人效比;考虑到两地地域和交通差异,相信大家会找最适合自己发挥的工作方式(比如按时下班后1小时到家晚饭后继续未竟工作等..)大家在遵守公司规章的情况下尽情地体现自己的能力价值,为MOV!和深圳公司争光我们在这边才能更安心更有信心的工作下去;请客BU长、名部门长、项目管理和各业务单元负责人,全面梳理团队情况,及时评估成员工作负荷与成果质量,坚决清退划水害虫痕疫,践行公司价值观,相互监督,防止管理漏洞及渎职。感谢人家的理解,也请人家多担待我的直言不讳……
点赞 评论 收藏
分享
求实习的小白1213:华科去这 你是真敢去啊
点赞 评论 收藏
分享
你背过凌晨4点的八股文么:简历挂了的话会是流程终止,像我一样
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务