Golang HTTP服务的模糊测试实践指南

Golang HTTP服务的模糊测试实践指南 我们最新的文章展示了如何在 Go 中进行模糊测试,特别是针对 HTTP 服务。你使用模糊测试吗?如果使用,你用它测试什么?

Fuzz Testing Go HTTP Services

Fuzz Testing Go HTTP Services

作为开发者,你无法预见到你的程序或函数可能接收到的所有可能的输入。


更多关于Golang HTTP服务的模糊测试实践指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang HTTP服务的模糊测试实践指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,我经常在Go项目中使用模糊测试,特别是在测试HTTP服务时。Go 1.18引入的内置模糊测试功能非常强大,我主要用它来测试HTTP请求处理函数,特别是那些处理用户输入的端点。

以下是一个针对HTTP处理函数进行模糊测试的示例:

package main

import (
    "net/http"
    "net/http/httptest"
    "testing"
)

func FuzzHandleRequest(f *testing.F) {
    // 添加种子语料库
    f.Add("normal input")
    f.Add("")
    f.Add("special chars !@#$%^&*()")
    f.Add("very long string " + string(make([]byte, 10000)))

    f.Fuzz(func(t *testing.T, input string) {
        // 创建测试请求
        req := httptest.NewRequest("GET", "/test?input="+input, nil)
        w := httptest.NewRecorder()
        
        // 调用处理函数
        handleRequest(w, req)
        
        // 验证响应状态码
        if w.Code != http.StatusOK && w.Code != http.StatusBadRequest {
            t.Errorf("Unexpected status code: %d for input: %q", w.Code, input)
        }
        
        // 验证响应体不为空(根据具体需求调整)
        if w.Body.Len() == 0 {
            t.Errorf("Empty response body for input: %q", input)
        }
    })
}

// 实际的HTTP处理函数
func handleRequest(w http.ResponseWriter, r *http.Request) {
    input := r.URL.Query().Get("input")
    // 处理输入...
    if input == "" {
        w.WriteHeader(http.StatusBadRequest)
        w.Write([]byte("Bad request"))
        return
    }
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Processed: " + input))
}

对于JSON API的模糊测试:

func FuzzHandleJSON(f *testing.F) {
    // 添加JSON种子数据
    f.Add(`{"name":"test","age":25}`)
    f.Add(`{"name":"","age":-1}`)
    f.Add(`{"name":null,"age":null}`)
    f.Add(`invalid json`)

    f.Fuzz(func(t *testing.T, jsonInput string) {
        req := httptest.NewRequest("POST", "/api/user", 
            strings.NewReader(jsonInput))
        req.Header.Set("Content-Type", "application/json")
        
        w := httptest.NewRecorder()
        handleJSONRequest(w, req)
        
        // 验证响应
        if w.Code >= http.StatusInternalServerError {
            t.Errorf("Server error for input: %q", jsonInput)
        }
    })
}

对于路径参数的模糊测试:

func FuzzHandlePathParam(f *testing.F) {
    f.Add("123")
    f.Add("abc")
    f.Add("123-456")
    f.Add("../../etc/passwd")
    f.Add(string(make([]byte, 1000)))

    f.Fuzz(func(t *testing.T, id string) {
        req := httptest.NewRequest("GET", "/users/"+id, nil)
        w := httptest.NewRecorder()
        
        // 这里需要模拟路由解析,或者使用实际的router
        handleUserRequest(w, req, id)
        
        if w.Code == http.StatusInternalServerError {
            t.Errorf("Internal error for ID: %q", id)
        }
    })
}

运行模糊测试:

go test -fuzz=FuzzHandleRequest -fuzztime=30s

我主要用模糊测试来发现以下问题:

  1. 缓冲区溢出或内存泄漏
  2. 未处理的边界情况
  3. SQL注入漏洞
  4. 路径遍历漏洞
  5. 整数溢出
  6. 未预期的panic或崩溃

模糊测试特别适合测试那些处理复杂输入(如JSON、XML、查询参数)的HTTP端点,它能发现手动测试难以覆盖的边缘情况。

回到顶部