튜토리얼: GitLab에서 퍼즈 테스트 수행하기

상세정보: Tier: Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

커버리지 기반 퍼즈 테스트는 예상치 못한, 부적절한 또는 무작위 데이터를 귀하의 애플리케이션으로 보내고, 이후에 귀하의 애플리케이션을 불안정한 동작 및 충돌을 모니터링합니다.

이를 통해 다른 QA 프로세스에서 놓칠 수 있는 버그 및 잠재적 보안 문제를 발견할 수 있습니다.

퍼즈 테스트를 귀하의 자체 테스트 프로세스와 다른 보안 스캐너와 함께 사용해야 합니다. 만약 GitLab CI/CD를 사용하는 경우 CI/CD 워크플로우의 일부로 퍼즈 테스트를 실행할 수 있습니다.

이 튜토리얼에서는 JavaScript를 사용하여 커버리지 기반 퍼즈 테스트를 설정하고 구성하며 수행하는 방법에 대해 알아봅니다. 구체적으로,

  1. 프로젝트 템플릿 복제하여 퍼즈 테스트를 실행할 프로젝트를 생성합니다.
  2. 퍼즈 타겟 생성.
  3. 복제한 프로젝트에서 커버리지 기반 퍼즈 테스트 활성화를 설정합니다.
  4. 퍼즈 테스트 실행으로 보안 취약점을 식별합니다.
  5. 퍼즈 테스트에서 식별된 취약점을 수정합니다.

프로젝트 템플릿 복제

먼저, 퍼즈 테스트를 시도할 프로젝트를 만들기 위해 fuzz-testing 프로젝트 템플릿을 복제해야 합니다. 복제는 다음 단계를 따릅니다.

  1. fuzz-testing 프로젝트 템플릿을 엽니다.
  2. 프로젝트 템플릿을 복제합니다.
  3. 프로젝트 템플릿을 복제할 때:

fuzz-testing 프로젝트 템플릿을 성공적으로 복제했습니다. 퍼즈 테스트를 시작하기 전에 프로젝트 템플릿과 복제본 사이의 관계를 제거해야 합니다. 다음 단계를 따르세요.

  1. 왼쪽 사이드바에서 설정 > 일반을 선택합니다.
  2. 고급을 확장합니다.
  3. 포크 관계 제거 섹션에서 포크 관계 제거을 선택합니다. 요청 시 프로젝트 이름을 입력합니다.

프로젝트가 준비되었으므로 이제 퍼즈 테스트를 생성할 수 있습니다. 다음으로 퍼즈 타겟을 만들어보겠습니다.

퍼즈 타겟 생성

이제 퍼즈 테스트를 위한 프로젝트가 준비되었으므로, 퍼즈 타겟을 만들어야 합니다. 퍼즈 타겟은 테스트 대상 애플리케이션을 호출하는 입력이 주어졌을 때의 동작을 하는 함수 또는 프로그램입니다.

이 튜토리얼에서, 퍼즈 타겟은 무작위 버퍼를 매개변수로 사용하여 my-tools.js 파일의 함수를 호출합니다.

두 개의 퍼즈 타겟 파일을 만들려면 다음을 따르세요.

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하여 fuzz-testing-demo 프로젝트를 찾습니다.
  2. 프로젝트의 루트 디렉토리에 파일을 생성합니다.
  3. 파일의 이름을 fuzz-sayhello.js로 지정하고 다음 코드를 추가합니다.

     let tools = require('./my-tools')
    
     function fuzz(buf) {
       const text = buf.toString()
       tools.sayHello(text)
     }
    
     module.exports = {
       fuzz
     }
    

    또는 이 코드를 복사하여 fuzz-testing-demo/fuzzers/fuzz-sayhello.js 프로젝트 파일에서 붙여넣을 수 있습니다.

  4. 대상 브랜치의 이름을 add-fuzz-test로 지정하고 설명적인 커밋 메시지를 작성합니다.
    • 이 변경 사항으로 새로운 병합 요청을 시작하지 않는 옵션을 선택하지 마세요.
  5. 변경 사항 커밋을 선택합니다.
  6. 프로젝트의 루트 디렉토리로 돌아갑니다.
  7. add-fuzz-test 브랜치에 있는지 확인합니다.
  8. 두 번째 파일의 이름을 fuzz-readme.js로 지정하고 다음 코드를 추가합니다.

     let tools = require('./my-tools')
     function fuzz(buf) {
         const text = buf.toString()
         tools.readmeContent(text)
     }
     module.exports = {
         fuzz
     }
    

    또는 이 코드를 복사하여 fuzz-testing-demo/fuzzers/fuzz-readme.js 프로젝트 파일에서 붙여넣을 수 있습니다.

  9. 설명적인 커밋 메시지를 작성합니다.
  10. 대상 브랜치add-fuzz-test로 설정되어 있는지 확인합니다.
  11. 변경 사항 커밋을 선택합니다.

이제 테스트 중인 애플리케이션을 호출할 수 있는 두 개의 퍼즈 타겟이 준비되었습니다. 다음으로 퍼즈 테스트를 활성화합니다.

커버리지 기반 퍼즈 테스트 활성화

커버리지 기반 퍼즈 테스트를 활성화하려면 두 개의 퍼즈 타겟에서 gitlab-cov-fuzz CLI를 실행하는 CI/CD 파이프라인을 생성해야 합니다.

파이프라인 파일을 만들려면 다음을 따르세요.

  1. add-fuzz-test 브랜치에 있는지 확인합니다.
  2. fuzz-testing-demo 프로젝트의 루트 디렉토리에 새 파일을 생성합니다.
  3. 파일의 이름을 .gitlab-ci.yml로 지정하고 다음 코드를 추가합니다.

     image: node:18
    
     stages:
       - fuzz
    
     include:
       - template: Coverage-Fuzzing.gitlab-ci.yml
    
     readme_fuzz_target:
       extends: .fuzz_base
       tags: [saas-linux-large-amd64] # Optional
       variables:
         COVFUZZ_ADDITIONAL_ARGS: '--fuzzTime=60'
       script:
         - npm config set @gitlab-org:registry https://gitlab.com/api/v4/packages/npm/ && npm i -g @gitlab-org/jsfuzz
         - ./gitlab-cov-fuzz run --engine jsfuzz -- fuzz-readme.js
    
     hello_fuzzing_target:
       extends: .fuzz_base
       tags: [saas-linux-large-amd64] # Optional
       variables:
         COVFUZZ_ADDITIONAL_ARGS: '--fuzzTime=60'
       script:
         - npm config set @gitlab-org:registry https://gitlab.com/api/v4/packages/npm/ && npm i -g @gitlab-org/jsfuzz
         - ./gitlab-cov-fuzz run --engine jsfuzz -- fuzz-sayhello.js
    

    이 단계에서 파이프라인에 다음을 추가합니다: - 템플릿을 사용하는 fuzz 단계. - readme_fuzz_targethello_fuzzing_target 두 작업으로, 각 작업은 jsfuzz 엔진을 사용하여 실행되며, 이 엔진은 처리되지 않은 예외를 충돌로 보고합니다.

  4. 설명적인 커밋 메시지를 작성합니다.
  5. 대상 브랜치add-fuzz-test로 설정되어 있는지 확인합니다.
  6. 변경 사항 커밋을 선택합니다.

커버리지 기반 퍼즈 테스트를 성공적으로 활성화했습니다. 이제 방금 만든 파이프라인을 사용하여 퍼즈 테스트를 실행할 차례입니다.

Fuzz(퍼즈) 테스트 실행

퍼즈(퍼즈) 테스트를 실행하려면 다음 단계를 따르세요:

  1. 왼쪽 사이드바에서 코드 > 병합 요청을 선택하세요.
  2. 새 병합 요청을 선택하세요.
  3. 소스 브랜치 섹션에서 add-fuzz-test 브랜치를 선택하세요.
  4. 대상 브랜치 섹션에서 본인의 네임스페이스와 main 브랜치가 선택되어 있는지 확인하세요.
  5. 브랜치 비교 및 계속을 선택하세요.
  6. 병합 요청을 생성하세요.

병합 요청을 생성하면 새로운 파이프라인이 트리거되어 퍼즈 테스트를 실행합니다. 파이프라인 실행이 완료되면 병합 요청 페이지에서 보안 취약점 경고를 확인할 수 있어야 합니다.

각 취약점에 대한 자세한 정보를 보려면 개별 Uncaught-exception 링크를 선택하세요.

퍼즈 테스트를 성공적으로 실행하고 수정해야 할 취약점을 식별했습니다.

취약점 수정

퍼즈 테스트에서 두 가지 보안 취약점을 확인했습니다. 이러한 취약점을 수정하려면 my-tools.js 라이브러리를 사용합니다.

my-tools.js 파일을 만들려면 다음 단계를 따르세요:

  1. 프로젝트의 add-fuzz-test 브랜치에 있는지 확인하세요.
  2. 프로젝트의 루트 디렉토리로 이동하여 my-tools.js 파일을 엽니다.
  3. 이 파일의 내용을 다음 코드로 대체하세요:

    const fs = require('fs')
    
    function sayHello(name) {
      if(name.includes("z")) {
        //throw new Error("😡 error name: " + name)
        console.log("😡 error name: " + name)
      } else {
        return "😀 hello " + name
      }
    }
    
    function readmeContent(name) {
    
      let fileName = name => {
        if(name.includes("w")) {
          return "./README.txt"
        } else {
          return "./README.md"
        }
      }
    
      //const data = fs.readFileSync(fileName(name), 'utf8')
      try {
        const data = fs.readFileSync(fileName(name), 'utf8')
        return data
      } catch (err) {
        console.error(err.message)
        return ""
      }
    
    }
    
    module.exports = {
      sayHello, readmeContent
    }
    

    또는 fuzz-testing-demo/javascript/my-tools.js 프로젝트 파일에서 코드를 복사할 수 있습니다.

  4. 변경 사항 커밋을 선택하세요. 이렇게 하면 다른 퍼즈 테스트를 실행하는 또 다른 파이프라인이 트리거됩니다.
  5. 파이프라인이 완료되면 병합 요청 개요 페이지를 확인하세요. 새로운 잠재적 취약점이 감지되지 않았다는 보안 스캔 결과를 확인할 수 있어야 합니다.
  6. 변경 사항을 병합하세요.

축하합니다! 퍼즈 테스트를 성공적으로 실행하고 식별된 보안 취약점을 수정했습니다!

자세한 내용은 커버리지 기반 퍼즈 테스트를 참조하세요.