1. 總覽
安全的原始碼技術是一組可用於提升原始碼安全性的做法。這些技術有助於找出及修正原始碼中的安全漏洞、防止未經授權存取原始碼,以及保護原始碼免於遭到修改。
常見的安全原始碼技術包括:
- Linting:Linting 是檢查原始碼是否有錯誤和樣式問題的程序。這項工作是透過 lint 工具完成,這是一項可分析原始碼並找出潛在問題的程式。您可以使用 Lint 工具檢查各種錯誤,包括語法錯誤、語義錯誤、樣式錯誤和安全漏洞。
- 靜態應用程式安全性測試 (SAST):SAST 是一種安全性測試,可分析原始碼、二進位碼或位元碼,找出安全性漏洞。SAST 工具可用於找出各種程式設計語言中的安全漏洞,包括 Go、Java、Python、C++ 和 C#。
- 授權掃描:授權掃描是指識別軟體應用程式中所用第三方軟體元件的授權。這很重要,因為這有助於確保應用程式遵守授權條款,避免法律問題。
這些技巧可用於軟體開發生命週期的所有階段,提升原始碼的安全性。您可以使用 Linting 在開發過程的早期找出錯誤,也可以使用 SAST 在編譯或部署程式碼前找出安全漏洞,並使用授權掃描功能確保應用程式遵守授權條款。
使用這些技術有助於提升原始碼的安全性,並降低安全性違規的風險。
學習目標
本實驗室將著重於保護軟體原始碼的工具和技巧。
- Linting
- 靜態應用程式安全性測試
- 掃描授權
本研究室中使用的所有工具和指令都會在 Cloud Shell 中執行。
2. 設定和需求
自學環境設定
- 登入 Google Cloud 控制台,然後建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請務必建立帳戶。
- 「Project name」是這個專案參與者的顯示名稱。這是 Google API 不會使用的字元字串。您隨時可以更新。
- 專案 ID 在所有 Google Cloud 專案中都是不重複的值,且無法變更 (設定後即無法變更)。Cloud 控制台會自動產生一個專屬字串,您通常不需要特別留意。在大多數程式碼研究室中,您都需要參照專案 ID (通常會標示為
PROJECT_ID
)。如果您不喜歡系統產生的 ID,可以隨機產生另一組 ID。或者,您也可以自行嘗試,看看是否可用。這項設定在這個步驟後即無法變更,並會在專案期間維持不變。 - 僅供參考,有些 API 會使用第三個值,也就是「專案編號」。如要進一步瞭解這三個值,請參閱說明文件。
- 接下來,您需要在 Cloud 控制台中啟用帳單功能,才能使用 Cloud 資源/API。執行本程式碼研究室時,費用應該不會太高,甚至可能不收費。如要關閉資源,避免產生教學課程以外的費用,您可以刪除已建立的資源,或刪除整個專案。Google Cloud 新使用者可享有 $300 美元的免費試用期。
啟動 Cloud Shell 編輯器
本研究室是專為搭配 Google Cloud Shell 編輯器使用而設計及測試。如要存取編輯器,請按照下列步驟操作:
- 前往 https://console.cloud.google.com 存取 Google 專案。
- 按一下右上角的雲端 Shell 編輯器圖示
- 視窗底部會開啟新的窗格
- 按一下「Open Editor」(開啟編輯器) 按鈕
- 編輯器會隨即開啟,右側顯示探索器,中央區域則顯示編輯器
- 畫面底部也應有終端機窗格
- 如果終端機未開啟,請使用 `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
檢查工具可用於檢查常見的樣式錯誤或與語法相關的瑕疵。透過 Linting 提供跨團隊通用的語法模式,有助於提升安全性,讓團隊更快完成程式碼審查、分享知識,並讓程式碼更清晰。
此外,Linting 會找出可能導致常見漏洞的常見語法錯誤,例如不當或效率較低的程式庫或核心 API 使用方式。
安裝 staticcheck
連結工具
go get honnef.co/go/tools/cmd/staticcheck@latest
在專案根目錄中執行 Go Linter (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
下方的LINTING - Step 1
行註解排除,方法是加上開頭斜線(//
)。 - 移除
main()
方法內LINTING - Step 2
下方兩行的開頭斜線,取消註解這兩行。
在專案根目錄中重新執行 staticcheck
staticcheck
指令不應傳回任何結果 (即空白行)。
檢查指令的結束狀態。
echo $?
在這種情況下,由於指令不會導致錯誤,因此結束狀態會是 零。
4. 靜態應用程式安全性測試
AST/靜態安全性測試:提供靜態程式碼分析,找出常見的弱點和曝露 ( CWEs)
安裝 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. 恭喜
恭喜,您已完成程式碼研究室!
您學到的內容
- 保護原始碼的工具和技巧
—
上次更新時間:2023 年 3 月 23 日