0
0
Lập trình
Admin Team
Admin Teamtechmely

Hướng Dẫn Kiểm Thử Mờ (Fuzzing) Dịch Vụ HTTP Trong Golang: Phát Hiện Lỗi Ẩn

Đăng vào 3 ngày trước

• 4 phút đọc

Chủ đề:

development

Giới Thiệu

Trong công việc lập trình, các lập trình viên thường không thể dự đoán hết các đầu vào mà chương trình hoặc hàm của họ có thể nhận được. Mặc dù họ có thể xác định được một số trường hợp đặc biệt, nhưng không có gì đảm bảo rằng những tình huống bất ngờ sẽ không xuất hiện. Chính vì lý do này, việc phát hiện lỗi thường chỉ dừng lại ở những gì lập trình viên dự đoán và mong đợi.

Để vượt qua thách thức này, phương pháp kiểm thử mờ (fuzzing) đã ra đời. Trong bài viết này, chúng ta sẽ khám phá cách thực hiện kiểm thử mờ trong Golang để phát hiện những lỗi ẩn.

Fuzz Testing Là Gì?

Fuzzing là một kỹ thuật kiểm thử phần mềm tự động, cho phép bạn gửi một khối lượng lớn dữ liệu ngẫu nhiên hợp lệ, gần như hợp lệ hoặc không hợp lệ đến một chương trình và theo dõi hành vi của nó. Mục tiêu của fuzzing là làm rõ lỗi, sự cố và lỗ hổng an ninh trong mã mà bạn não chưa thể nhận ra bằng các phương pháp kiểm thử truyền thống.

Ví dụ về một mã Golang có thể bị lỗi:

go Copy
func Equal(a []byte, b []byte) bool {
    for i := range a {
        // có thể xảy ra panic với lỗi runtime: chỉ mục ngoài phạm vi.
        if a[i] != b[i] {
            return false
        }
    }
    return true
}

Hàm trên hoạt động tốt miễn là độ dài của hai slice bằng nhau, nhưng nó sẽ gặp lỗi khi slice đầu tiên dài hơn slice thứ hai.

Tích Hợp Fuzzing Trong Quy Trình Phát Triển

Việc tích hợp fuzzing vào quá trình phát triển phần mềm (SDLC) là một thực hành tốt. Microsoft, ví dụ, sử dụng fuzzing như một bước trong SDLC để tìm ra các lỗi và lỗ hổng tiềm ẩn.

Các Bước Thực Hiện Kiểm Thử Mờ Trong Golang

Với Go 1.18, fuzzing đã trở thành một phần của thư viện chuẩn, giúp việc thực hiện fuzzing trở nên dễ dàng hơn. Dưới đây là các bước để tạo fuzz test trong Golang:

  1. Tạo một hàm mới trong tệp *_test.go bắt đầu bằng từ khóa Fuzz, nhận đối số là *testing.F.
  2. Thêm các hạt giống corpus bằng cách sử dụng f.Add() để fuzzer có thể tạo dữ liệu từ đó.
  3. Gọi hàm fuzz target bằng f.Fuzz() và truyền vào các đối số mà hàm của bạn chấp nhận.
  4. Khởi động fuzzing bằng lệnh go test, kèm theo cờ –fuzz=Fuzz.

Ví Dụ Về Fuzz Test Đơn Giản

go Copy
// Fuzz test
func FuzzEqual(f *testing.F) {
  f.Add([]byte{'f', 'u', 'z', 'z'}, []byte{'t', 'e', 's', 't'})

  f.Fuzz(func(t *testing.T, a []byte, b []byte) {
    Equal(a, b)
  })
}

Khi chạy lệnh fuzz, nếu có lỗi xảy ra, thông tin sẽ được ghi lại trong thư mục testdata, cho phép bạn xem lại và tái hiện đầu vào gây ra lỗi đó.

Fuzzing Dịch Vụ HTTP Trong Golang

Chúng ta cũng có thể thực hiện fuzz testing cho các dịch vụ HTTP bằng cách sử dụng httptest từ Golang. Một ví dụ thực tế là xây dựng một HTTP handler chấp nhận một yêu cầu JSON với các trường limitoffset.

Định Nghĩa Cấu Trúc Yêu Cầu

go Copy
type Request struct {
  Limit  int `json:"limit"`
  Offset int `json:"offset"`
}

Triển Khai Hàm Xử Lý

go Copy
func ProcessRequest(w http.ResponseWriter, r *http.Request) {
 // ... (mã chi tiết xử lý yêu cầu)
}

Hàm này có thể gặp lỗi nếu người dùng nhập vào các giá trị không hợp lệ. Việc thực hiện fuzzing trong hàm xử lý này sẽ giúp phát hiện những vấn đề này.

Triển Khai Fuzz Test Cho HTTP Handler

go Copy
func FuzzProcessRequest(f *testing.F) {
 // ... (chuẩn bị fuzz test)
}

Chạy Fuzz Testing

Khi fuzzing các dịch vụ HTTP, chúng ta cần chú ý điều chỉnh số lượng worker song song để tránh quá tải máy chủ kiểm thử. Ví dụ:

Copy
go test --fuzz=Fuzz -fuzztime=10s -parallel=1

Kết Luận

Việc viết fuzz test cho bất kỳ dịch vụ nào trong ứng dụng của bạn là một cách hiệu quả để phát hiện lỗi. Fuzzers giúp tiết lộ những lỗi tiềm ẩn chỉ xuất hiện với đầu vào bất ngờ. Chúng tích hợp tốt với các bài kiểm tra thông thường trong Golang, đóng góp vào việc cải thiện chất lượng mã nguồn.

Với những kiến thức này, bạn có thể bắt đầu triển khai fuzz testing cho các ứng dụng Golang của mình ngay hôm nay.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào