Skip to content

Latest commit

Β 

History

History
91 lines (80 loc) Β· 3.34 KB

Fuzzing.md

File metadata and controls

91 lines (80 loc) Β· 3.34 KB

Fuzzing

golang version 1.18μ—μ„œ μΆ”κ°€λœ κΈ°λŠ₯ 쀑 ν•˜λ‚˜μ˜ κΈ°λŠ₯이며,
Fuzzing(Fuzz testing)은 μ†Œν”„νŠΈμ›¨μ–΄ ν…ŒμŠ€νŠΈ κΈ°λ²•μœΌλ‘œ λ¬΄μž‘μœ„ ν…ŒμŠ€νŠΈ 방식

κ°œλ…

  • ν•˜λ“œμ›¨μ–΄λ‚˜ μ†Œν”„νŠΈμ›¨μ–΄ ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•œ λ¬΄μž‘μœ„ ν…ŒμŠ€νŠΈ λ°©μ‹μœΌλ‘œ, μœ νš¨ν•˜λ©΄μ„œ μ˜ˆμƒμΉ˜μ•Šμ€ λ¬΄μž‘μœ„ 데이터λ₯Ό μž…λ ₯ν•˜λŠ” 방법

    • κ°œλ°œμžκ°€ μƒκ°μΉ˜ λͺ»ν•œ 버그가 μžˆλŠ” 엣지 μΌ€μ΄μŠ€λ₯Ό μ°ΎλŠ” 데에 μ‚¬μš©ν•˜λŠ” ν…ŒμŠ€νŠΈ 기법
  • 주둜 μ†Œν”„νŠΈμ›¨μ–΄λ‚˜ 컴퓨터 μ‹œμŠ€ν…œλ“€μ˜ λ³΄μ•ˆ 문제λ₯Ό ν…ŒμŠ€νŠΈν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ¨

μ‚¬μš©λ²•

  • κΈ°μ‘΄ λ‹¨μœ„ν…ŒμŠ€νŠΈμ™€μ˜ ꡬ문 차이

    • κΈ°μ‘΄ go test λ‹¨μœ„ ν…ŒμŠ€νŠΈ

      • ν•¨μˆ˜λͺ…에 "Test"λ₯Ό λΆ™μ—¬μ€¬μŒ
      • μž…λ ₯ νŒŒλΌλ―Έν„°λ‘œ "t *testing.T" μ‚¬μš©
      • "go test -run=ν•¨μˆ˜λͺ…"으둜 νŠΉμ • ν•¨μˆ˜μ— λŒ€ν•΄ ν…ŒμŠ€νŠΈ 진행
    • Fuzzing ν…ŒμŠ€νŠΈ

      • "Fuzz"λ₯Ό ν•¨μˆ˜λͺ…에 λΆ™μ—¬μ€˜μ•Ό 함
      • μž…λ ₯ νŒŒλΌλ―Έν„°λ‘œ "f *testing.F" μ‚¬μš©
      • "go test -fuzz=Fuzz"둜 퍼징 ν…ŒμŠ€νŠΈ μ‹€ν–‰
        -fuzztime ν”Œλž˜κ·Έλ₯Ό 톡해 퍼징 ν…ŒμŠ€νŠΈμ— κ±Έλ¦¬λŠ” μ‹œκ°„μ„ μ œν•œν•  수 있음

예제

  • 예제1) Reverse() ν•¨μˆ˜

    // Reverse() : λ¬Έμžμ—΄ μ—­μˆœμœΌλ‘œ λ³€ν™˜ν•˜λŠ” ν•¨μˆ˜   
    func Reverse(s string) (string, error) {
          if !utf8.ValidString(s) {
          return s, errors.New("input is not valid UTF-8")
      }
      b := []byte(s)
      for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
          b[i], b[j] = b[j], b[i]
      }
      return string(b), nil
    }
    
    // TestReverse() : Reverse ν•¨μˆ˜μ— λŒ€ν•œ λ‹¨μœ„ ν…ŒμŠ€νŠΈ
    // tc 3κ°€μ§€μ˜ κ²½μš°μ— λŒ€ν•΄ κ²°κ³Όκ°’ 체크   
    func TestReverse(t *testing.T) {
      testcases := []struct {
          in, want string
      }{
          {"Hello, world", "dlrow ,olleH"},
          {" ", " "},
          {"!12345", "54321!"},
      }
      for _, tc := range testcases {
          rev := Reverse(tc.in)
          if rev != tc.want {
                  t.Errorf("Reverse: %q, want %q", rev, tc.want)
          }
      }
    }
    
    // FuzzReverse() : Reverse ν•¨μˆ˜μ— λŒ€ν•œ 퍼징 ν…ŒμŠ€νŠΈ
    // 랜덀 string값을 λ¬΄μž‘μœ„ λŒ€μž…   
    func FuzzReverse(f *testing.F) {
      testcases := []string{"Hello, world", " ", "!12345"}
      for _, tc := range testcases {
          f.Add(tc)  // Use f.Add to provide a seed corpus
      }
      f.Fuzz(func(t *testing.T, orig string) {
          rev := Reverse(orig)
          doubleRev := Reverse(rev)
          if orig != doubleRev {
              t.Errorf("Before: %q, after: %q", orig, doubleRev)
          }
          if utf8.ValidString(orig) && !utf8.ValidString(rev) {
              t.Errorf("Reverse produced invalid UTF-8 string %q", rev)
          }
      })
    }
    
  • 예제1)의 3번째 퍼징 ν…ŒμŠ€νŠΈ κ²°κ³Ό 해석

    • Failing input written to testdata/fuzz/FuzzReverse/af692587... λ””λ ‰ν„°λ¦¬μ˜ 파일 확인해보면, μ‹€νŒ¨μ˜ 경우 μž…λ ₯κ°’ κΈ°μž…λ˜μ–΄μžˆμŒ
      • string("泃") 에 λŒ€ν•΄ 였λ₯˜ λ°œμƒ
      • ν•΄λ‹Ήν•˜λŠ” 泃 μœ λ‹ˆμ½”λ“œ λ¬ΈμžλŠ” utf-8μ—μ„œ ν•œκΈ€μžμ§€λ§Œ, 2byteμ΄μƒμ˜ 곡간을 μ°¨μ§€ν•˜λ―€λ‘œ.. []byte κΈ°μ€€μœΌλ‘œ μ•žλ’€λ₯Ό λ’€μ§‘μœΌλ©΄ μ˜ˆμƒμΉ˜ λͺ»ν•œ 값이 λ˜μ–΄λ²„λ¦Ό
      • λ”°λΌμ„œ νŠΉμ • 엣지 μΌ€μ΄μŠ€λ₯Ό μ°Ύμ•„λ‚΄λŠ” 데에 도움이 λ˜λŠ” ν…ŒμŠ€νŠΈ κΈ°λ²•μž„

μ°Έκ³