웹 API 퍼즈 테스팅
GitLab v19.5Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
요약
웹 API 퍼즈 테스팅은 API 동작 파라미터에 예상치 못한 값을 전달해 백엔드에서 예기치 않은 동작과 오류를 일으킵니다. 퍼즈 테스팅은 GitLab Secure의 다른 보안 스캐너 및 자체 테스트 프로세스에 더해 사용해야 합니다.
웹 API 퍼즈 테스팅은 API 동작 파라미터에 예상치 못한 값을 전달해 백엔드에서 예기치 않은 동작과 오류를 일으킵니다. 퍼즈 테스팅으로 다른 QA 프로세스가 놓칠 수 있는 버그와 잠재적 취약점을 찾아냅니다.
퍼즈 테스팅은 GitLab Secure의 다른 보안 스캐너 및 자체 테스트 프로세스에 더해 사용해야 합니다. GitLab CI/CD를 사용한다면 CI/CD 워크플로의 일부로 퍼즈 테스트를 실행할 수 있습니다.
개요는 Web API fuzzing - Advanced Security Testing을 참고합니다.
시작하기#
CI/CD 구성을 편집해 API 퍼징을 시작합니다.
필수 조건:
-
지원되는 API 유형 중 하나를 사용하는 웹 API:
- REST API
- SOAP
- GraphQL
- 폼 본문, JSON 또는 XML
-
다음 형식 중 하나로 된 API 사양:
- OpenAPI v2 또는 v3 사양
- GraphQL 스키마
- HTTP Archive(HAR)
- Postman Collection v2.0 또는 v2.1
-
Linux/amd64에서
docker실행기를 사용하는 가용 GitLab Runner. -
배포된 대상 애플리케이션.
-
deployStage 다음에fuzzStage가 CI/CD 파이프라인 정의에 추가되어 있어야 합니다:stages: - build - test - deploy - fuzz
API 퍼징을 활성화하려면:
-
웹 API 퍼징 구성 양식을 사용합니다.
이 양식에서는 가장 일반적인 API 퍼징 옵션의 값을 선택할 수 있으며, GitLab CI/CD 구성에 붙여넣을 YAML 스니펫을 생성합니다.
결과 이해하기#
보안 스캔의 출력을 확인하려면:
- 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
- 왼쪽 사이드바에서 Build > Pipelines를 선택합니다.
- 파이프라인을 선택합니다.
- Security 탭을 선택합니다.
- 취약점을 선택해 다음을 포함한 세부 정보를 확인합니다:
- Status: 취약점이 분류되었는지 또는 해결되었는지를 나타냅니다.
- Description: 취약점의 원인, 잠재적 영향, 권장 조치 단계를 설명합니다.
- Severity: 영향도에 따라 여섯 단계로 분류됩니다. 자세한 내용은 심각도 수준을 참고합니다.
- Scanner: 해당 취약점을 탐지한 분석기를 식별합니다.
- Method: 취약한 서버 상호 작용 유형을 확인합니다.
- URL: 취약점의 위치를 표시합니다.
- Evidence: 해당 취약점의 존재를 증명하는 테스트 케이스를 설명합니다
- Identifiers: CWE 식별자처럼 취약점을 분류하는 데 사용한 참조 목록.
보안 스캔 결과를 다운로드할 수도 있습니다:
- 파이프라인의 Security 탭에서 Download results를 선택합니다.
자세한 내용은 파이프라인 보안 보고서를 참고합니다.
결과는 기능 브랜치에서 생성됩니다. 기본 브랜치에 머지되면 취약점이 됩니다. 이 구분은 보안 상태를 평가할 때 중요합니다.
최적화#
API 퍼징을 최대한 활용하려면 다음 권장 사항을 따릅니다:
-
최신 버전의 분석기를 실행하려면
pull_policy: always를 사용하도록 러너를 구성합니다. -
기본적으로 API 퍼징은 파이프라인의 이전 job 이 정의한 모든 아티팩트를 다운로드합니다. API 퍼징 job 이 테스트 대상 URL을 정의하는
environment_url.txt나 이전 job 이 생성한 다른 파일에 의존하지 않는다면 아티팩트를 다운로드하지 않아야 합니다.아티팩트 다운로드를 피하려면 분석기 CI/CD job을 확장해 의존성이 없음을 지정합니다. 예를 들어 API 퍼징 분석기라면
.gitlab-ci.yml파일에 다음을 추가합니다:apifuzzer_fuzz: dependencies: []
애플리케이션 배포 옵션#
API 퍼징에는 스캔할 수 있도록 배포된 애플리케이션이 필요합니다.
대상 애플리케이션의 복잡도에 따라 API 퍼징 템플릿을 배포하고 구성하는 방법은 몇 가지가 있습니다.
리뷰 앱#
리뷰 앱은 API 퍼징 대상 애플리케이션을 배포하는 방법 중 가장 손이 많이 가는 방식입니다. 이 과정을 돕기 위해 GitLab은 Google Kubernetes Engine(GKE)을 사용하는 리뷰 앱 배포를 만들었습니다. 이 예제는 Review apps - GKE 프로젝트에서 확인할 수 있으며, DAST에서 리뷰 앱을 구성하는 자세한 지침도 함께 제공합니다.
Docker 서비스#
애플리케이션이 Docker 컨테이너를 사용한다면 API 퍼징으로 배포하고 스캔하는 또 다른 방법이 있습니다. Docker 빌드 job 이 완료되고 이미지가 컨테이너 레지스트리에 추가된 뒤에는 그 이미지를 서비스로 사용할 수 있습니다.
.gitlab-ci.yml의 서비스 정의를 사용하면 DAST 분석기로 서비스를 스캔할 수 있습니다.
job에 services 섹션을 추가할 때 alias는 해당 서비스에 접근할 때 사용할 호스트 이름을 정의합니다. 다음 예제에서 dast job 정의의 alias: yourapp 부분은 배포된 애플리케이션의 URL 이 yourapp을 호스트 이름으로 사용한다는 의미입니다: https://yourapp/.
stages:
- build
- fuzz
include:
- template: API-Fuzzing.gitlab-ci.yml
# Deploys the container to the GitLab container registry
deploy:
services:
- name: docker:dind
alias: dind
image: docker:20.10.16
stage: build
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $CI_REGISTRY_IMAGE:latest || true
- docker build --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
apifuzzer_fuzz:
services: # use services to link your app container to the dast job
- name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
alias: yourapp
variables:
FUZZAPI_TARGET_URL: https://yourapp
대부분의 애플리케이션은 데이터베이스나 캐시 서비스 같은 여러 서비스에 의존합니다. 기본적으로 services 필드에 정의된 서비스는 서로
통신할 수 없습니다. 서비스 간 통신을 허용하려면 FF_NETWORK_PER_BUILD 기능 플래그를 활성화합니다.
variables:
FF_NETWORK_PER_BUILD: "true" # enable network per build so all services can communicate on the same network
services: # use services to link the container to the dast job
- name: mongo:latest
alias: mongo
- name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
alias: yourapp
배포#
웹 API 퍼징은 CI/CD 파이프라인의 fuzz Stage에서 실행됩니다. API 퍼징이 최신 코드를 스캔하도록
하려면 CI/CD 파이프라인이 fuzz Stage 이전의 Stage 중 하나에서 테스트 환경에 변경 사항을
배포해야 합니다.
파이프라인이 실행할 때마다 같은 웹 서버에 배포하도록 구성되어 있다면, 다른 파이프라인이 아직 실행 중인 상태에서 파이프라인을 실행할 경우 한 파이프라인이 다른 파이프라인의 코드를 덮어쓰는 경쟁 조건이 발생할 수 있습니다. 스캔 대상 API는 퍼징 스캔이 진행되는 동안 변경에서 제외해야 합니다. 스캔 중 API에 가해지는 변경은 퍼징 스캐너에 의한 것뿐이어야 합니다. 스캔 중 API에 발생한 변경(예: 사용자, 예약 작업, 데이터베이스 변경, 코드 변경, 다른 파이프라인, 다른 스캐너에 의한 변경)은 부정확한 결과로 이어질 수 있습니다.
다음 방법으로 웹 API 퍼징 스캔을 실행할 수 있습니다:
- OpenAPI 사양(버전 2 및 3)
- GraphQL 스키마
- HTTP 아카이브(HAR)
- Postman 컬렉션(버전 2.0 및 2.1)
API 퍼징 프로젝트 예제#
- OpenAPI v2 사양 예제 프로젝트
- HTTP 아카이브(HAR) 예제 프로젝트
- Postman Collection 예제 프로젝트
- GraphQL 예제 프로젝트
- SOAP 예제 프로젝트
- Selenium을 사용한 인증 토큰
지원 받기 또는 개선 요청하기#
특정 문제에 대한 지원이 필요하면 도움받기 채널을 이용합니다.
GitLab.com의 GitLab 이슈 트래커는 API 보안 및 API 퍼징에 관한 버그와 기능 제안을 올리기에 적합한 곳입니다.
API 퍼징에 관한 새 이슈를 열 때 ~"Category:API Security" 레이블을 사용하면 적임자가 빠르게 검토합니다.
직접 이슈를 제출하기 전에 이슈 트래커에서 비슷한 항목을 검색합니다. 다른 사람이 같은 이슈나 기능 제안을 이미 올렸을 가능성이 높습니다. 이모지 반응으로 지지를 표시하거나 논의에 참여할 수 있습니다.
기대한 대로 동작하지 않는 상황을 겪었다면 다음과 같은 컨텍스트 정보를 함께 제공하는 것을 고려합니다:
- GitLab Self-Managed 인스턴스를 사용하는 경우 GitLab 버전.
.gitlab-ci.ymljob 정의.- 전체 job 콘솔 출력.
gl-api-security-scanner.log라는 job 아티팩트로 제공되는 스캐너 로그 파일.
이슈를 제출할 때 민감한 정보를 포함하지 않습니다. 비밀번호, 토큰, 키와 같은 자격 증명은 제거합니다.
용어집#
- Assert: 어설션은 결함을 유발하기 위해 체크가 사용하는 탐지 모듈입니다. 다수의 어설션에는 설정이 있습니다. 하나의 체크는 여러 어설션을 사용할 수 있습니다. 예를 들어 로그 분석, 응답 분석, 상태 코드는 체크가 함께 사용하는 일반적인 어설션입니다. 여러 어설션을 사용하는 체크는 각 어설션을 켜고 끌 수 있습니다.
- Check: 특정 유형의 테스트를 수행하거나 특정 취약점 유형을 점검합니다. 예를 들어 JSON 퍼징 체크는 JSON 페이로드의 퍼즈 테스팅을 수행합니다. API 퍼저는 여러 체크로 구성됩니다. 체크는 프로필에서 켜고 끌 수 있습니다.
- Fault: 퍼징 중 어설션이 식별한 실패를 결함이라고 합니다. 결함은 보안 취약점인지, 보안과 무관한 이슈인지, 거짓 양성인지 판단하기 위해 조사합니다. 결함은 조사하기 전까지 알려진 취약점 유형이 없습니다. 취약점 유형의 예로는 SQL 인젝션과 서비스 거부가 있습니다.
- Profile: 구성 파일에는 하나 이상의 테스팅 프로필, 즉 하위 구성이 있습니다. 기능 브랜치용 프로필과 main 브랜치용 추가 테스팅 프로필을 따로 둘 수 있습니다.