10P by neo 16일전 | favorite | 댓글 1개
  • 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-lintgo 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 공격 등의 잠재적 보안 결함을 찾는 데 매우 유용함
  • 많은 입력 조합이 자동으로 생성되므로 개발자가 수백, 수천 가지 입력 데이터 조합을 직접 고민할 필요가 없음
Hacker News 의견
  • govulncheck는 취약한 코드가 실제로 도달되는지를 확인하는 도구로, 프로그램의 의존성을 점검하는 것보다 유용함
  • Google의 capslock 프로젝트를 잊지 말고 참고할 필요가 있음
  • go vetgo test -race에 대한 유용한 팁이 포함되어 있음
  • Go는 메모리 안전하지 않지만, 다른 언어보다 안전하게 코딩하기 쉬움
    • Go의 명확한 구문 덕분에 함수의 동작과 데이터 구조를 쉽게 이해할 수 있음
    • AI 도구가 Go와 잘 작동하는 이유는 함수 내의 문맥이 명확하기 때문임
  • Semgrep은 정적 분석을 통해 언어와 공통 프레임워크에 대한 검사를 수행하는 훌륭한 도구임
    • Semgrep의 오픈 규칙을 GitHub에서 확인 가능함
  • Go의 보안 평판에 대한 의문이 제기됨
    • Go는 일반적으로 안전하고 안정적이라고 생각되며, .NET과 같은 다른 도구와 비슷한 수준임
  • gosec에 대해 새롭게 알게 되었음
  • 9년 동안 Go 앱을 유지보수하면서 Go 버전과 모듈을 쉽게 업그레이드할 수 있었음
    • GitHub가 자동으로 취약성을 알려주며, 99%의 경우 변경 없이 작동함
  • Go는 실제로 메모리 안전하지 않음
    • 원자성이 단어 크기 값에만 보장되며, 인터페이스 포인터나 슬라이스 같은 이중 단어 값은 동시성에서 메모리 안전성을 해칠 수 있음
  • Go는 좋지만, 최근 제네릭 사용이 증가하면서 코드 가독성이 떨어지고 있음
    • 이전의 제네릭을 거의 사용하지 않은 Go 코드보다 읽기 어려워짐