4.3 KiB
4.3 KiB
id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
| id | title | category | status | source_trust_level | verification_status | created_at | updated_at | tags | tech_stack | applied_in | aliases | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| testing-fuzzing-patterns | Fuzzing — 무작위 / 변형 / coverage 기반 | Coding | draft | B | conceptual | 2026-05-09 | 2026-05-09 |
|
|
|
Fuzzing
보안 / 안정성 강력. 무작위 / 변형 input → crash / hang / 잘못된 결과 찾기. Coverage-guided 가 진화 — 새 path 보면 keep. Parser / decoder / network 입력에 강.
📖 핵심 개념
- Random fuzzing: 완전 random.
- Mutation: seed 변형 (bit flip, splice).
- Coverage-guided: 새 path 가는 input 보존.
- Sanitizer: ASAN, UBSAN 같이 — undefined behavior 잡음.
💻 코드 패턴
Go fuzzing (built-in)
// parser_test.go
package parser
import "testing"
func FuzzParse(f *testing.F) {
f.Add([]byte(`{"a":1}`)) // seed
f.Add([]byte(`{}`))
f.Fuzz(func(t *testing.T, data []byte) {
result, err := Parse(data)
if err != nil { return }
// 속성: parse 성공 → reformat → 같은 결과
rendered := Format(result)
result2, err2 := Parse(rendered)
if err2 != nil || !equal(result, result2) {
t.Fail()
}
})
}
go test -fuzz=FuzzParse -fuzztime=10s
Rust fuzzing (cargo-fuzz)
// fuzz/fuzz_targets/parse.rs
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
let _ = parser::parse(data);
});
cargo fuzz run parse
TS fuzzing (jazzer.js)
import { instrument } from '@jazzer.js/instrumentor';
export function fuzz(data: Buffer) {
try {
JSON.parse(data.toString('utf8'));
} catch (e) {
if (e instanceof SyntaxError) return; // expected
throw e; // unexpected — fuzz 가 crash
}
}
jazzer fuzz.ts --fuzz=fuzz
Property + fuzzing
// fast-check 도 일종의 fuzzing
import fc from 'fast-check';
fc.assert(fc.property(fc.uint8Array(), (data) => {
const parsed = myParse(data);
if (parsed) {
const rendered = myFormat(parsed);
expect(myParse(rendered)).toEqual(parsed);
}
}), { numRuns: 10000 });
Corpus (seed)
fuzz/corpus/
empty
simple.json
large.json
malformed.json
edge_cases/
→ Fuzzer 가 시드에서 시작하여 변형.
CI fuzzing (Go example)
- name: Fuzz parse
run: go test -fuzz=FuzzParse -fuzztime=2m -run=^$ ./parser/
⚠️ 큰 fuzz time = 느림. PR 마다 X — nightly.
OSS-Fuzz (Google)
- Open source: 자동 fuzzing 무료.
- C/C++/Rust/Go/Python/Java/JS.
- 발견된 버그 reports + auto regression test.
Fuzz crash 분석
# Fuzzer 가 crash 한 input 저장
testdata/fuzz/FuzzParse/abc123 # 특정 input 재현
go test -run=FuzzParse/abc123 # 그 input 만 실행
→ Shrinking 으로 minimal reproduce.
보안 use case
parser: SQL injection / command injection 입력
network: 잘못된 packet → buffer overflow
crypto: 잘못된 signature / key
file format: pdf / image / zip 파싱
Sanitizer (C/C++/Rust)
# AddressSanitizer
clang -fsanitize=address fuzz.c
# UndefinedBehaviorSanitizer
clang -fsanitize=undefined
# 결합 = 강
🤔 의사결정 기준
| 적합 | 부적합 |
|---|---|
| Parser / decoder | Pure 비즈니스 |
| Network input handler | UI |
| File format | DB query |
| Crypto | Test framework |
| Compiler / interpreter | 단순 fetch wrapper |
| 보안 critical | Internal-only API |
❌ 안티패턴
- No corpus: 발견 느림. 의미 있는 seed.
- Crash 후 안 fix: 기록만, 다시 발생.
- CI 매 PR fuzz: 느림. nightly / weekly.
- Random 만 (coverage 무시): 같은 path 만.
- Fuzz target 가 setup 비싸 (DB): 매 input 마다 setup. mock.
- External call (HTTP): random — 외부 영향. mock.
- Deterministic input 만 OK 가정: 시간 / random / file 영향 — control.
🤖 LLM 활용 힌트
- Parser / decoder = 자연.
- Property + fuzzing 결합.
- OSS-Fuzz 같은 자동 plat 활용.