---
name: secure-fuzz-testing
description: "Expert-level skill for writing and integrating coverage-guided fuzz tests in Python, Rust, and Go for secure code validation in English and Indonesian."
author: "Roedy Rustam"
---
# Secure Fuzz Testing
[English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
---
## English
### Description
Expert-level guidance for writing, running, and integrating coverage-guided fuzz tests (fuzzing) to identify security vulnerabilities, memory leaks, and input-validation issues in software applications. This skill covers writing fuzz targets in **Python**, **Rust**, and **Go**, configuring compilers with sanitizers (ASan, MSan, UBSan), and setting up automated CI/CD security pipelines.
### Trigger Conditions
- Use when designing or reviewing data parsers, serialization/deserialization logic, or file formats.
- Use when writing libraries that process untrusted network input or binary data streams.
- Use when integrating automated security testing into a DevSecOps pipeline (CI/CD).
- Use when troubleshooting complex memory bugs, edge-case crashes, or unhandled exceptions.
### Writing Fuzz Targets
Coverage-guided fuzzers need a target function that accepts a stream of bytes and processes it.
#### 1. Python Fuzzing (Atheris)
`Atheris` is a coverage-guided fuzzer for Python. It can fuzz Python code and native extensions:
```python
import sys
import atheris
with atheris.instrument_imports():
import our_parser # Import target module inside instrument_imports
def TestOneInput(data):
if len(data) < 4:
return
try:
# Decode and parse the byte data
text = data.decode("utf-8", errors="ignore")
our_parser.parse_config(text)
except our_parser.ParseException:
# Expected exceptions should be caught to avoid false positives
pass
atheris.Setup(sys.argv, TestOneInput)
atheris.Fuzz()
```
#### 2. Rust Fuzzing (cargo-fuzz & libFuzzer)
Rust has first-class fuzzing support via `cargo-fuzz` which wraps `libFuzzer`:
```rust
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
if let Ok(input_str) = std::str::from_utf8(data) {
let _ = our_crate::parse_config(input_str);
}
});
```
- **Run Fuzzer**: Execute `cargo +nightly fuzz run `.
#### 3. Go Fuzzing (Native Go Fuzz)
Go supports native fuzzing in its standard library (`testing` package):
```go
package main
import (
"testing"
"ourmodule/parser"
)
func FuzzParseConfig(f *testing.F) {
// Add seed corpus for initial coverage guidance
f.Add([]byte("config_key = value"))
f.Fuzz(func(t *testing.T, data []byte) {
_, err := parser.ParseConfig(data)
if err != nil {
t.Skip() // Skip expected/graceful errors
}
})
}
```
- **Run Fuzzer**: Run `go test -fuzz=FuzzParseConfig -fuzztime=10m`.
### Diagnostics & Sanitizers
Use compiler instrumentation flags to expose hidden bugs:
- **AddressSanitizer (ASan)**: Detects out-of-bounds access, use-after-free, and memory leaks.
- **UndefinedBehaviorSanitizer (UBSan)**: Detects integer overflows, alignment issues, and division by zero.
- **ThreadSanitizer (TSan)**: Finds data races in multithreaded environments.
### DevSecOps & CI Integration
- **OSS-Fuzz**: For open-source projects, integrate with Google's OSS-Fuzz for continuous fuzzing infrastructure.
- **GitHub Actions**: Run fuzz targets on pull requests with short run times (`fuzztime=5m`) to catch regression errors without blocking pipelines.
---
### Troubleshooting & Common Gotchas
- **False Positives**: Ensure expected API errors and clean validation errors do not cause the fuzzer to abort. Catch expected exceptions or use `t.Skip()` where appropriate.
- **State Pollution**: Fuzz targets must be stateless. Avoid sharing mutable global states between iterations.
- **Infinite Loops**: Guard against code that hangs. Configure timeouts (`-timeout=25` in libFuzzer) to automatically crash long-running executions.
---
## Bahasa Indonesia
### Deskripsi
Panduan tingkat ahli untuk menulis, menjalankan, dan mengintegrasikan pengujian berbasis cakupan (*coverage-guided fuzzing*) untuk mengidentifikasi celah keamanan, kebocoran memori, dan kesalahan validasi input dalam aplikasi perangkat lunak. Skill ini mencakup penulisan target fuzzing dalam bahasa **Python**, **Rust**, dan **Go**, konfigurasi compiler dengan sanitizer (ASan, MSan, UBSan), serta penyiapan pipa otomatisasi keamanan CI/CD.
### Kondisi Pemicu
- Gunakan saat merancang atau memeriksa parser data, logika serialisasi/deserialisasi, atau pemroses format berkas.
- Gunakan saat menulis pustaka (*library*) yang memproses input jaringan yang tidak tepercaya atau aliran data biner.
- Gunakan saat mengintegrasikan pengujian keamanan otomatis ke dalam alur kerja DevSecOps (CI/CD).
- Gunakan saat mendiagnosis bug memori yang kompleks, crash pada kasus ekstrem (*edge-cases*), atau *exception* yang tidak ditangani.
### Penulisan Target Fuzzing
Fuzzer berbasis cakupan memerlukan fungsi target yang menerima aliran byte untuk kemudian diproses secara dinamis.
#### 1. Fuzzing Python (Atheris)
`Atheris` adalah fuzzer berbasis cakupan untuk kode Python dan ekstensi native (C/C++):
```python
import sys
import atheris
with atheris.instrument_imports():
import our_parser # Impor modul target di dalam instrument_imports
def TestOneInput(data):
if len(data) < 4:
return
try:
# Dekode data byte menjadi teks
text = data.decode("utf-8", errors="ignore")
our_parser.parse_config(text)
except our_parser.ParseException:
# Tangkap exception yang diharapkan agar tidak dianggap crash palsu
pass
atheris.Setup(sys.argv, TestOneInput)
atheris.Fuzz()
```
#### 2. Fuzzing Rust (cargo-fuzz & libFuzzer)
Rust memiliki dukungan fuzzing kelas satu melalui utilitas `cargo-fuzz` yang menggunakan pustaka `libFuzzer`:
```rust
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
if let Ok(input_str) = std::str::from_utf8(data) {
let _ = our_crate::parse_config(input_str);
}
});
```
- **Jalankan Fuzzer**: Eksekusi perintah `cargo +nightly fuzz run `.
#### 3. Fuzzing Go (Native Go Fuzz)
Go mendukung pengujian fuzzing secara native dalam pustaka standarnya (`testing` package):
```go
package main
import (
"testing"
"ourmodule/parser"
)
func FuzzParseConfig(f *testing.F) {
// Tambahkan seed corpus awal sebagai panduan awal cakupan fuzzer
f.Add([]byte("config_key = value"))
f.Fuzz(func(t *testing.T, data []byte) {
_, err := parser.ParseConfig(data)
if err != nil {
t.Skip() // Lewati error yang memang diharapkan (ditangani dengan aman)
}
})
}
```
- **Jalankan Fuzzer**: Eksekusi perintah `go test -fuzz=FuzzParseConfig -fuzztime=10m`.
### Diagnosis & Sanitizer
Gunakan tanda instrumentasi kompiler untuk mendeteksi bug tersembunyi secara dini:
- **AddressSanitizer (ASan)**: Mendeteksi akses memori di luar batas (*out-of-bounds*), penggunaan setelah dibebaskan (*use-after-free*), dan kebocoran memori (*memory leak*).
- **UndefinedBehaviorSanitizer (UBSan)**: Mendeteksi overflow integer, masalah penyelarasan memori (*alignment*), dan pembagian dengan nol.
- **ThreadSanitizer (TSan)**: Menemukan perebutan data (*data race*) pada eksekusi multithread.
### Integrasi DevSecOps & CI
- **OSS-Fuzz**: Untuk proyek open-source, integrasikan dengan platform OSS-Fuzz dari Google untuk pemantauan berkelanjutan.
- **GitHub Actions**: Jalankan target fuzzing pada pull request dengan batasan waktu yang singkat (`fuzztime=5m`) untuk menangkap regresi kode tanpa menghambat alur build.
---
### Pemecahan Masalah & Kesalahan Umum
- **Crash Palsu (False Positives)**: Pastikan error API yang ditangani dengan aman tidak membuat fuzzer berhenti. Tangkap exception tersebut atau gunakan `t.Skip()` pada Go.
- **Polusi State (State Pollution)**: Pastikan target fuzzing bersifat stateless. Jangan biarkan state global mutable dibagikan antar iterasi pengujian.
- **Loop Tak Terbatas**: Waspadai kode yang mengalami hang. Konfigurasikan batas waktu (`-timeout=25` pada libFuzzer) agar eksekusi yang macet secara otomatis dilaporkan sebagai crash.