名詞解釋

什麼是模糊測試(fuzzing):大量餵入非預期輸入,找出自家軟體的缺陷

模糊測試會自動把非預期的輸入餵給軟體,找出錯誤與弱點。說明其運作方式,以及如何開始測試自己的程式碼。

發布於 2026-11-15 更新於 2026-11-15 閱讀時間 2 分鐘
本頁內容

模糊測試是一種測試技術,會自動把非預期的輸入餵給軟體,以找出缺陷。本頁說明其運作方式,以及如何開始測試自己的程式碼(不涵蓋測試他人的系統)。

什麼是模糊測試

OWASP 將模糊測試描述為一種軟體測試技術,目的是找出錯誤、弱點或非預期的行為。它會自動提供無效、非預期或部分無效的輸入,並觀察程式是否出現異常行為。NIST 詞彙表(引用 NIST SP 800-95)同樣將模糊測試描述為:由稱為 fuzzer 的工具,將各種輸入組合提交給測試目標,以揭示其反應方式。

它的優點在於對系統應有的行為做的假設很少。人工撰寫的測試只涵蓋撰寫者想到的情況,而模糊測試工具可能找出在無人設想的輸入下會失效的地方。

運作方式

1. 準備一些初始輸入(seed)
2. 模糊測試工具將它們變異,並分別傳給目標函式
↓ 執行,並觀察執行了哪些程式碼、行為如何
3. 儲存任何造成當機的輸入;將能觸及新路徑的輸入回饋至步驟 2
產生、執行、觀察、重複。覆蓋率導向的模糊測試工具會保留能觸及新路徑的輸入,並以此建立下一批輸入。

多數現代模糊測試工具都是覆蓋率導向的。它們會測量哪些程式碼被執行,保留能觸及新程式碼的輸入,並加以變異以產生下一批輸入。這樣能比單純的隨機輸入深入程式更多部分。LLVM 的 libFuzzer 文件將它描述為一種行程內、覆蓋率導向、演化式的模糊測試引擎,會連結到被測試的函式庫中。

常見工具

工具主要目標說明
libFuzzerC/C++ 及其他語言(LLVM)連結到目標程式中。根據其文件,原作者已轉向 Centipede 引擎,libFuzzer 現在只接收重要的錯誤修正
AFL++C/C++ 及其他語言廣泛使用的覆蓋率導向模糊測試工具
Go 內建模糊測試Go(1.18 或更新版本)使用 go test -fuzz 執行。造成失敗的輸入會儲存在 testdata 下,並由一般測試重播
OSS-Fuzz開源軟體Google 提供的免費持續模糊測試服務,使用多種引擎與 sanitizer

libFuzzer 的模糊測試目標是一個函式(LLVMFuzzerTestOneInput),會接收輸入的位元組及其長度。在 Go 中,你要撰寫名為 FuzzXxx 的測試函式,它接收 *testing.F,並以 f.Add 加入初始輸入。

如何開始測試自己的軟體

  1. 選擇一個解析輸入的函式(檔案格式解析器、設定載入器、協定處理器)
  2. 撰寫一個小型模糊測試目標,只把輸入傳給該函式。保持它快速且具決定性,呼叫之間不保留狀態
  3. 加入幾個典型的有效輸入作為初始種子
  4. 開啟 AddressSanitizer 等 sanitizer,並執行設定好的時間(在 Go 中,-fuzztime 用來設定長度)
  5. 將每個造成失敗的輸入轉為可重現的測試,並在修正後保留為回歸測試
  6. 若要持續進行,可在 CI 中執行短時段的測試;若是開源專案,可考慮加入 OSS-Fuzz

Go 的模糊測試每次執行有 1 秒的限制,而覆蓋率引導可在 AMD64 與 ARM64 上運作。請查閱官方文件,確認你的環境中的限制。

只對你管理的軟體進行模糊測試

模糊測試會持續傳送大量格式錯誤的輸入。若對你沒有測試權限的服務或伺服器這樣做,可能構成未授權存取或服務中斷。請將測試範圍限制在你開發或管理、位於自己環境中的軟體。

能做什麼,不能做什麼

OWASP 指出,模糊測試是對人工程式碼審查與除錯的補充,而非取代。它也提到,模糊測試工具傾向找出較簡單的錯誤,而且在黑箱測試中,較難判斷發現的影響程度。

因此,模糊測試擅長的是「讓機器搜尋程式可能出錯的方式」,而對於設計層級的問題,例如缺少授權檢查,效果則較弱。對於這類問題,例如 IDOR,應依賴檢查預期規則的測試。

本站觀點:找到輸入只是一半的工作,還要保留為回歸測試

重點不只是執行模糊測試工具,而是把它找到的輸入保存為回歸測試。Go 內建的模糊測試會把造成失敗的輸入儲存在 testdata 下,並在一般測試中重播,就是遵循這個理念。它能避免已修正的錯誤在之後的變更中再次出現。如果你負責維護解析輸入的程式碼,一個務實的第一步是只對單一函式進行模糊測試。

主要來源

  • OWASP Community,《Fuzzing》— owasp.org(定義、特性、限制)
  • NIST CSRC 詞彙表,「fuzz testing」— csrc.nist.gov(來源:NIST SP 800-95)
  • LLVM,《libFuzzer》— llvm.org(運作方式、模糊測試目標、維護狀態)
  • Go,《Fuzzing》— go.dev(Go 1.18 或更新版本、執行方式、限制)
  • Google,《OSS-Fuzz》— google.github.io(概述、支援的引擎)。錯誤數量會隨時間變化,因此此處不引用數字。至於 AFL++,請查閱其官方文件以了解目前的用法

延伸閱讀

FAQ

Q什麼是模糊測試?
A

模糊測試是一種測試技術,會自動大量餵入無效或非預期的輸入給程式,並檢查是否當機或出現異常行為。OWASP 將它描述為一種軟體測試技術,目的是找出錯誤、弱點或非預期的行為。它也被稱為 fuzz testing。

Q模糊測試能找出哪些問題?
A

通常包括當機、記憶體損毀(例如越界讀取與寫入)、無限迴圈,以及非預期的例外狀況。它特別適合用於解析輸入的程式碼,例如影像、文件或協定的解析器。OWASP 指出,模糊測試工具傾向找出較簡單的錯誤,而且較難判斷其發現的影響程度。

Q什麼是覆蓋率導向的模糊測試?
A

模糊測試工具會測量每個輸入執行到哪些程式碼(覆蓋率),保留能觸及新程式碼的輸入,並加以變異以產生下一批輸入。相較於純粹隨機的輸入,這種方式能深入程式的更多部分。libFuzzer 的文件將它描述為一種行程內(in-process)、覆蓋率導向、演化式的模糊測試引擎。

Q開始模糊測試需要準備什麼?
A

需要一小段測試程式碼,稱為模糊測試目標(fuzz target),用來把產生的輸入傳給你想測試的函式。若使用 C/C++,可以採用 libFuzzer 或 AFL++;若使用 Go 1.18 或更新版本,則可使用標準工具(go test -fuzz)。常見做法是搭配 AddressSanitizer 等 sanitizer,以便立即發現記憶體誤用。

Q我可以對別人的服務進行模糊測試嗎?
A

不可以。未經許可,大量傳送格式錯誤的輸入給系統,可能構成未授權存取或服務中斷。請只對你開發或管理的軟體,在自己的環境中進行模糊測試。若是開源專案,請使用既有的管道,例如 OSS-Fuzz。

Q什麼是 OSS-Fuzz?
A

這是 Google 為開源軟體提供的免費模糊測試服務。根據其官方頁面,它於 2016 年推出,起因是 OpenSSL 的 Heartbleed 弱點;它使用 libFuzzer、AFL++、Honggfuzz 與 Centipede 等引擎,並會以非公開方式通知開發者所發現的錯誤。