1. 개요
안전한 소스 코드 기법은 소스 코드의 보안을 개선하는 데 사용할 수 있는 일련의 방법입니다. 이러한 기술은 소스 코드의 취약점을 식별 및 수정하고 소스 코드에 대한 무단 액세스를 방지하며 소스 코드가 수정되지 않도록 보호하는 데 도움이 될 수 있습니다.
몇 가지 일반적인 보안 소스 코드 기법은 다음과 같습니다.
- 린팅: 린트는 소스 코드에 오류 및 스타일 문제가 있는지 확인하는 프로세스입니다. 이 작업은 소스 코드를 분석하고 잠재적인 문제를 식별하는 프로그램인 린트 도구를 사용하여 수행됩니다. 린트 도구를 사용하여 구문 오류, 의미 오류, 스타일 오류, 보안 취약점을 비롯한 다양한 오류를 검사할 수 있습니다.
- 정적 애플리케이션 보안 테스트 (SAST): SAST는 소스 코드, 바이너리 코드, 바이트 코드를 분석하여 보안 취약점을 식별하는 보안 테스트 유형입니다. SAST 툴은 Go, Java, Python, C++, C# 등 다양한 프로그래밍 언어의 취약점을 찾는 데 사용될 수 있습니다.
- 라이선스 스캔: 라이선스 스캔은 소프트웨어 애플리케이션에 사용된 서드 파티 소프트웨어 구성요소의 라이선스를 식별하는 프로세스입니다. 이는 애플리케이션이 라이선스 약관을 준수하는지 확인하여 법적 문제를 방지하는 데 도움이 되므로 중요합니다.
이러한 기술은 소프트웨어 개발 수명 주기의 모든 단계에서 소스 코드의 보안을 개선하는 데 사용할 수 있습니다. 린트는 개발 프로세스 초기에 오류를 식별하는 데 사용할 수 있고, SAST를 사용하여 코드를 컴파일하거나 배포하기 전에 취약점을 찾을 수 있으며, 라이선스 스캔을 사용하여 애플리케이션이 라이선스 약관을 준수하는지 확인할 수 있습니다.
이러한 기법을 사용하면 소스 코드의 보안을 강화하고 보안 침해의 위험을 줄이는 데 도움이 될 수 있습니다.
학습할 내용
이 실습에서는 소프트웨어 소스 코드를 보호하는 도구와 기법에 중점을 둡니다.
- 린트 작업
- 정적 애플리케이션 보안 테스트
- 라이선스 스캔
이 실습에서 사용되는 모든 도구와 명령어는 Cloud Shell에서 실행됩니다.
2. 설정 및 요구사항
자습형 환경 설정
- Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.



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

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

- 편집기가 오른쪽에 탐색기가 표시되고 중앙에 편집기가 열립니다.
- 화면 하단에서 터미널 창도 사용할 수 있습니다.
- 터미널이 열려 있지 않으면 `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일