보안 소스 코드

1. 개요

안전한 소스 코드 기법은 소스 코드의 보안을 개선하는 데 사용할 수 있는 일련의 방법입니다. 이러한 기술은 소스 코드의 취약점을 식별 및 수정하고 소스 코드에 대한 무단 액세스를 방지하며 소스 코드가 수정되지 않도록 보호하는 데 도움이 될 수 있습니다.

몇 가지 일반적인 보안 소스 코드 기법은 다음과 같습니다.

  • 린팅: 린트는 소스 코드에 오류 및 스타일 문제가 있는지 확인하는 프로세스입니다. 이 작업은 소스 코드를 분석하고 잠재적인 문제를 식별하는 프로그램인 린트 도구를 사용하여 수행됩니다. 린트 도구를 사용하여 구문 오류, 의미 오류, 스타일 오류, 보안 취약점을 비롯한 다양한 오류를 검사할 수 있습니다.
  • 정적 애플리케이션 보안 테스트 (SAST): SAST는 소스 코드, 바이너리 코드, 바이트 코드를 분석하여 보안 취약점을 식별하는 보안 테스트 유형입니다. SAST 툴은 Go, Java, Python, C++, C# 등 다양한 프로그래밍 언어의 취약점을 찾는 데 사용될 수 있습니다.
  • 라이선스 스캔: 라이선스 스캔은 소프트웨어 애플리케이션에 사용된 서드 파티 소프트웨어 구성요소의 라이선스를 식별하는 프로세스입니다. 이는 애플리케이션이 라이선스 약관을 준수하는지 확인하여 법적 문제를 방지하는 데 도움이 되므로 중요합니다.

이러한 기술은 소프트웨어 개발 수명 주기의 모든 단계에서 소스 코드의 보안을 개선하는 데 사용할 수 있습니다. 린트는 개발 프로세스 초기에 오류를 식별하는 데 사용할 수 있고, SAST를 사용하여 코드를 컴파일하거나 배포하기 전에 취약점을 찾을 수 있으며, 라이선스 스캔을 사용하여 애플리케이션이 라이선스 약관을 준수하는지 확인할 수 있습니다.

이러한 기법을 사용하면 소스 코드의 보안을 강화하고 보안 침해의 위험을 줄이는 데 도움이 될 수 있습니다.

학습할 내용

이 실습에서는 소프트웨어 소스 코드를 보호하는 도구와 기법에 중점을 둡니다.

  • 린트 작업
  • 정적 애플리케이션 보안 테스트
  • 라이선스 스캔

이 실습에서 사용되는 모든 도구와 명령어는 Cloud Shell에서 실행됩니다.

2. 설정 및 요구사항

자습형 환경 설정

  1. Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
  • 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔이 고유한 문자열을 자동으로 생성합니다. 보통은 그게 뭔지 상관하지 않습니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로 PROJECT_ID로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 무작위로 다른 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다.
  • 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
  1. 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스를 삭제하거나 전체 프로젝트를 삭제하면 됩니다. Google Cloud 새 사용자에게는 미화 $300 상당의 무료 체험판 프로그램에 참여할 수 있는 자격이 부여됩니다.

Cloud Shell 편집기 시작

이 실습은 Google Cloud Shell 편집기에서 사용할 수 있도록 설계 및 테스트되었습니다. 편집기에 액세스하려면

  1. https://console.cloud.google.com에서 Google 프로젝트에 액세스합니다.
  2. 오른쪽 상단에서 Cloud Shell 편집기 아이콘을 클릭합니다.

8560cc8d45e8c112.png

  1. 창 하단에 새 창이 열립니다.
  2. 편집기 열기 버튼을 클릭합니다.

9e504cb98a6a8005.png

  1. 편집기가 오른쪽에 탐색기가 표시되고 중앙에 편집기가 열립니다.
  2. 화면 하단에서 터미널 창도 사용할 수 있습니다.
  3. 터미널이 열려 있지 않으면 `ctrl+` 키 조합을 사용하여 새 터미널 창을 엽니다.

환경 설정

GOPATH를 단일 디렉터리로 설정하여 이 실습에서 사용하는 명령어를 단순화합니다.

export GOPATH=$HOME/gopath

작업을 저장할 디렉터리 만들기

mkdir -p workspace
cd workspace

소스 코드 저장소 클론

git clone https://gitlab.com/gcp-solutions-public/shift-left-security-workshop/source-code-lab.git
cd source-code-lab
export WORKDIR=$(pwd)

3. 린트 작업

린트는 구문과 관련된 일반적인 스타일 기반 실수 또는 결함을 검사하는 데 사용됩니다. 린트는 여러 팀에 공통적인 구문 패턴을 제공하여 코드 검토, 지식 공유, 코드 명확성을 높여주므로 보안을 지원합니다.

또한 Linting은 라이브러리 또는 핵심 API의 부적절하거나 비효율적인 사용과 같은 일반적인 취약점으로 이어질 수 있는 일반적인 구문 실수를 식별합니다.

staticcheck 연결 도구 설치

 go get honnef.co/go/tools/cmd/staticcheck@latest

프로젝트 루트 디렉터리에서 Go 린터 (staticcheck)를 실행합니다.

 staticcheck

출력 검토

main.go:42:29: unnecessary use of fmt.Sprintf (S1039)

http.ListenAndServe()가 문자열을 허용하고 현재 코드는 문자열에 변수를 전달하지 않고 Sprintf를 사용하기 때문에 오류가 발생합니다.

명령어 종료 상태를 검토합니다.

echo $?

이 경우에는 명령으로 인해 오류가 발생했으므로 종료 상태가 1 이상이 됩니다. CI/CD 파이프라인에서 도구의 성공/실패를 판단하는 데 사용할 수 있는 한 가지 방법입니다.

main.go 파일을 수정하고 코드를 수정합니다.

  • 선행 슬래시(//)를 추가하여 main() 메서드 내에서 LINTING - Step 1 아래 줄을 주석 처리합니다.
  • main() 메서드 내에서 LINTING - Step 2 바로 아래에 있는 두 줄의 주석 처리를 삭제합니다. 이때 선행 슬래시를 삭제합니다.

프로젝트 루트 디렉터리에서 staticcheck를 다시 실행합니다.

staticcheck

이 명령어는 결과 (즉, 빈 줄)를 반환해서는 안 됩니다.

명령어의 종료 상태를 검사합니다.

  echo $?

이 경우 명령어로 오류가 발생하지 않았으므로 종료 상태는 0이 됩니다.

4. 정적 애플리케이션 보안 테스트

AST/정적 보안 테스트 - 일반적인 약점과 노출을 찾는 정적 코드 분석 제공 ( CWE)

AST 도구 (gosec) 설치

    export GOSEC_VERSION="2.15.0"
    curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | \
          sh -s -- -b $(go env GOPATH)/bin v${GOSEC_VERSION}

소스 코드에 대해 정책 파일로 gosec를 실행합니다.

gosec -conf policies/gosec-policy.json -fmt=json ./...

출력은 다음과 비슷해야 합니다.

{
    "Golang errors": {},
    "Issues": [
        {
            "severity": "HIGH",
            "confidence": "LOW",
            "cwe": {
                "ID": "798",
                "URL": "https://cwe.mitre.org/data/definitions/798.html"
            },
            "rule_id": "G101",
            "details": "Potential hardcoded credentials",
            "file": "/home/random-user-here/shift-left-security-workshop/labs/source-code-lab/main.go",
            "code": "31: \t// STEP 2: Change this and the reference below to something different (ie, not \"pawsword\" or \"password\")\n32: \tvar pawsword = \"im-a-cute-puppy\"\n33: \tfmt.Println(\"Something a puppy would use: \", username, pawsword)\n",
            "line": "32",
            "column": "6"
        }
    ],
    "Stats": {
        "files": 1,
        "lines": 89,
        "nosec": 0,
        "found": 1
    }
}

도구에서 잠재적인 문제(Potential hardcoded credentials)를 파악했습니다.

5. 라이선스 스캔

라이선스는 노출하고 싶지 않은 소스 코드의 노출을 법적으로 요구할 수 있으므로 보안에 중요한 역할을 합니다. 이 개념은 " copyleft" 라이선스에서 종속 항목을 사용하는 경우 소스 코드를 노출해야 하는 라이선스

golicense 설치

mkdir -p /tmp/golicense
wget -O /tmp/golicense/golicense.tar.gz https://github.com/mitchellh/golicense/releases/download/v0.2.0/golicense_0.2.0_linux_x86_64.tar.gz
pushd /tmp/golicense
tar -xzf golicense.tar.gz
chmod +x golicense
mv golicense $(go env GOPATH)/bin/golicense
popd

바이너리 파일 빌드

go build

'BSD-3-Clause'를 허용하지 않는 현재 정책 파일로 라이선스 확인을 실행합니다. 라이선스

golicense policies/license-policy.hcl hello-world

참고: 다음과 비슷한 출력이 표시되면서 실패합니다.

 🚫 rsc.io/sampler    BSD 3-Clause "New" or "Revised" License
 🚫 rsc.io/quote      BSD 3-Clause "New" or "Revised" License
 🚫 golang.org/x/text BSD 3-Clause "New" or "Revised" License

정책 파일 policies/license-policy.hcl을 수정하여 'BSD-3-Clause'를 이동하세요. deny 목록에서 allow 목록으로 변경합니다.

라이선스 확인 다시 실행

golicense policies/license-policy.hcl hello-world

참고: 다음과 비슷한 결과가 출력됩니다.

    ✅ rsc.io/quote      BSD 3-Clause "New" or "Revised" License
    ✅ rsc.io/sampler    BSD 3-Clause "New" or "Revised" License
    ✅ golang.org/x/text BSD 3-Clause "New" or "Revised" License

6. 축하합니다

축하합니다. Codelab을 완료했습니다.

학습한 내용

  • 소스 코드 보안을 위한 도구 및 기법

최종 업데이트: 2023년 3월 23일