- Go 코드를 작성할 때 보안을 고려하는 것은 복잡한 작업
- 몇 가지 구체적인 실천 방법을 제시하여 지속적으로 적용할 경우 견고하고 안전하며 성능이 뛰어난 코드를 작성할 수 있도록 도움을 줌
Go 버전 최신 상태 유지
- 프로젝트에서 사용하는 Go 버전을 최신으로 유지해야 함
- 최신 언어 기능을 사용하지 않더라도 Go 버전을 올리면 발견된 취약점에 대한 모든 보안 패치를 받을 수 있음
- 새로운 Go 버전은 최신 의존성과의 호환성도 보장함
- Go 릴리즈 히스토리 사이트에서 어떤 Go 릴리즈에서 어떤 보안 이슈와 CVE가 해결되었는지 확인하고 프로젝트의
go.mod
파일에서 최신 버전으로 업데이트할 수 있음
- Go 버전을 업그레이드한 후에는 호환성 및 의존성 문제가 발생하지 않는지 확인해야 함
- 정적 코드 분석기를 사용하여 코드 품질과 보안을 평가할 수 있음
vet
- Go 자체 제공
go vet
명령어로 Go 코드 분석 가능
-
go vet
명령어는 인수 없이 실행하면 기본 허용된 모든 옵션으로 실행됨
- 소스 코드를 스캔하고 잠재적 이슈를 보고함
- 가장 일반적인 이슈로는 고루틴 실수, 사용하지 않는 변수, 도달할 수 없는 코드 영역 등이 있음
staticcheck
- 서드파티 린터인 Staticcheck은 버그를 찾고 성능 문제를 탐지하며 Go 언어 스타일도 적용함
- 발견된 이슈를 설명하고 예제와 함께 수정사항을 제안함
- CI 파이프라인에서 실행하는 것 외에도 독립 실행 파일로 설치해 로컬에서 코드 스캔 가능
- 설치한 버전을 확인하고 스캔 실행 준비가 되었는지 확인
- 인수 없이 실행하면 기본적으로 모든 코드 분석기 호출
-
NGINX Agent GitHub 저장소에서 어떤 것을 찾을 수 있는지 예시 보기
- 스캔 결과는 deprecated 패키지/메서드/함수, 사용하지 않는 변수/필드, 코드 품질 관련 문제 등 3가지로 분류할 수 있음
golangci-lint
-
golangci-lint
는 go install
명령어로 설치 가능
- 설치가 잘 되었는지 버전을 확인
- 인수 없이 호출하면 모든 린터가 실행됨
- 이전에 복제한
agent
저장소에서 어떤 경고와 제안사항을 보여주는지 확인
- 린터가 정확한 파일과 라인을 가리킴
- 코드를 평가하고 변경한 다음 린터를 다시 실행하고 모든 단위 테스트 실행
- 테스트가 통과되면 업데이트된 코드를 커밋하고 원격으로 push
경쟁 상태(Race Condition) 탐지
- 여러 고루틴이 동시에 리소스에 액세스하려고 할 때 경쟁 상태가 발생할 수 있음
- 적어도 하나의 고루틴이 리소스를 변경하려고 할 때 탐지됨
- Go는
-race
인수와 함께 test
도구를 사용하여 이러한 상태를 테스트하는 것을 기본적으로 지원함
- 경쟁 탐지기는 실행된 코드만 평가하고 실행되지 않은 코드 경로는 무시하므로 데드 코드가 없는지 정적 코드 분석기를 먼저 실행해야 함
- 테스트를 병렬로 실행하면 동시성 문제를 탐지할 가능성이 높아짐
취약점 소스 코드 스캔
govulncheck
-
CVEs 데이터베이스에 나열된 알려진 취약점에 대해 코드 베이스를 스캔하는 도구
- Go 팀에서 개발하며 Go 취약점 전용 데이터베이스가 스캐너에 정보를 제공함
- 최신 버전 설치 후 기본 기능 시도
-
habit 저장소 복제 후 루트 디렉터리에서 도구 실행
- 취약점이 발견되지 않음
- 이진 파일을 스캔하면 다른 취약점이 발견될 수 있음
- Go 버전을 최신으로 업그레이드하고 의존성을 가져온 다음 소프트웨어와 의존성에 CVE가 없는지 확인
gosec
- 안전하지 않은 코드 구성을 찾는 데 도움이 되는 정적 코드 분석기
- 로컬 시스템이나 GitHub Action으로 CI 파이프라인에서 실행 가능
- 스캔 구성을 위한 옵션과 규칙 목록이 다양함
- 스캔할 Go 코드가 있는 GitHub 저장소 복제 후 루트 디렉터리에서 스캔 시작
- 스캔 보고서에서 심각도와 신뢰도별로 정렬된 잠재적 문제 목록 확인 가능
- 리포트된 CWE를 확인하고 나열된 약점에 대한 자세한 내용 학습
퍼징
- 코드 품질을 확인하고 취약점을 발견하는 마지막 방법
- 코드 테스트 적용 범위를 사용하여 무작위로 생성된 입력 데이터를 조작하는 자동화된 특수 테스트
- 버퍼 오버플로, SQL 인젝션, DoS 공격, XSS 공격 등의 잠재적 보안 결함을 찾는 데 매우 유용함
- 많은 입력 조합이 자동으로 생성되므로 개발자가 수백, 수천 가지 입력 데이터 조합을 직접 고민할 필요가 없음