擔(dān)心密碼提交到 GitHub?建議使用這個 Go 開源工具
閱讀本文大概需要 10 分鐘。
大家好,我是 polarisxu。
最近跟安全扛上了!這是我分享的 Go 安全相關(guān)的第 5 篇文章,前 4 篇文章如下:
《Go 團隊開始重視安全問題了》 《Go Module 有漏洞?免費的 Go 漏洞掃描 VSCode 插件》 《這個工具真好:看看你的Go項目依賴有無漏洞》 重磅!GitHub 為 Go 社區(qū)帶來安全支持
今天要分享的這個開源工具,我個人認為更實用,可以當(dāng)作一個 vet 工具使用,切切實實檢查日常開發(fā)經(jīng)常會忽略的安全問題,最常見的,比如將密碼提交到 GitHub 上了。。。
這個工具就是 gosec,GitHub 地址:https://github.com/securego/gosec,截止目前 Star 數(shù) 5.3k+,目測這一波能漲不少~
01 簡介
這個工具通過掃描 Go 代碼的 AST 樹來發(fā)現(xiàn)安全問題,具體來說,它通過一些規(guī)則來檢查代碼的安全。有專門的官網(wǎng):https://securego.io/。

02 安裝
官方提供了幾種安裝方式。作為一個 Go 程序員,我喜歡使用 go get 或 go install 安裝。
Go1.16 開始,安裝可執(zhí)行 Go 程序使用 go install,下載安裝普通庫,使用 go get
因為目前最新版本是 v2,因此這么安裝:
$ go install github.com/securego/gosec/v2/cmd/gosec@latest
當(dāng)然,你也可以使用官方編譯好的安裝:
# binary will be $(go env GOPATH)/bin/gosec
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(go env GOPATH)/bin vX.Y.Z
# or install it into ./bin/
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s vX.Y.Z
# In alpine linux (as it does not come with curl by default)
wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s vX.Y.Z
# If you want to use the checksums provided on the "Releases" page
# then you will have to download a tar.gz file for your operating system instead of a binary file
wget https://github.com/securego/gosec/releases/download/vX.Y.Z/gosec_vX.Y.Z_OS.tar.gz
如果你想將其和 CI 工具集成,可以參考和 GitHub Action 的集成方式:
name: Run Gosec
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
tests:
runs-on: ubuntu-latest
env:
GO111MODULE: on
steps:
- name: Checkout Source
uses: actions/checkout@v2
- name: Run Gosec Security Scanner
uses: securego/gosec@master
with:
args: ./...
03 使用和規(guī)則介紹
本地安裝好后,執(zhí)行 gosec -h 可以看到使用幫助:(請確保 gosec 在 PATH 環(huán)境變量中)
$ gosec -h
gosec - Golang security checker
gosec analyzes Go source code to look for common programming mistakes that
can lead to security problems.
VERSION: dev
GIT TAG:
BUILD DATE:
USAGE:
# Check a single package
$ gosec $GOPATH/src/github.com/example/project
# Check all packages under the current directory and save results in
# json format.
$ gosec -fmt=json -out=results.json ./...
# Run a specific set of rules (by default all rules will be run):
$ gosec -include=G101,G203,G401 ./...
# Run all rules except the provided
$ gosec -exclude=G101 $GOPATH/src/github.com/example/project/...
OPTIONS:
-color
Prints the text format report with colorization when it goes in the stdout (default true)
-conf string
Path to optional config file
-confidence string
Filter out the issues with a lower confidence than the given value. Valid options are: low, medium, high (default "low")
-exclude string
Comma separated list of rules IDs to exclude. (see rule list)
-exclude-dir value
Exclude folder from scan (can be specified multiple times)
-fmt string
Set output format. Valid options are: json, yaml, csv, junit-xml, html, sonarqube, golint, sarif or text (default "text")
-include string
Comma separated list of rules IDs to include. (see rule list)
-log string
Log messages to file rather than stderr
-no-fail
Do not fail the scanning, even if issues were found
-nosec
Ignores #nosec comments when set
-nosec-tag string
Set an alternative string for #nosec. Some examples: #dontanalyze, #falsepositive
-out string
Set output file for results
-quiet
Only show output when errors are found
-severity string
Filter out the issues with a lower severity than the given value. Valid options are: low, medium, high (default "low")
-sort
Sort issues by severity (default true)
-stdout
Stdout the results as well as write it in the output file
-tags string
Comma separated list of build tags
-tests
Scan tests files
-verbose string
Overrides the output format when stdout the results while saving them in the output file.
Valid options are: json, yaml, csv, junit-xml, html, sonarqube, golint, sarif or text
-version
Print version and quit with exit code 0
RULES:
G101: Look for hardcoded credentials
G102: Bind to all interfaces
G103: Audit the use of unsafe block
G104: Audit errors not checked
G106: Audit the use of ssh.InsecureIgnoreHostKey function
G107: Url provided to HTTP request as taint input
G108: Profiling endpoint is automatically exposed
G109: Converting strconv.Atoi result to int32/int16
G110: Detect io.Copy instead of io.CopyN when decompression
G201: SQL query construction using format string
G202: SQL query construction using string concatenation
G203: Use of unescaped data in HTML templates
G204: Audit use of command execution
G301: Poor file permissions used when creating a directory
G302: Poor file permissions used when creation file or using chmod
G303: Creating tempfile using a predictable path
G304: File path provided as taint input
G305: File path traversal when extracting zip archive
G306: Poor file permissions used when writing to a file
G307: Unsafe defer call of a method returning an error
G401: Detect the usage of DES, RC4, MD5 or SHA1
G402: Look for bad TLS connection settings
G403: Ensure minimum RSA key length of 2048 bits
G404: Insecure random number source (rand)
G501: Import blocklist: crypto/md5
G502: Import blocklist: crypto/des
G503: Import blocklist: crypto/rc4
G504: Import blocklist: net/http/cgi
G505: Import blocklist: crypto/sha1
G601: Implicit memory aliasing in RangeStmt
拿 Go 語言中文網(wǎng)試驗一下,切換到 studygolang 源碼目錄,執(zhí)行:
$ gosec ./...
...
Summary:
Gosec : dev
Files : 186
Lines : 27434
Nosec : 0
Issues : 292
中間過程輸出內(nèi)容很多,最后進行了匯總。根據(jù)默認規(guī)則,一共發(fā)現(xiàn)了 292 個 issue。但別慌,這里面有些規(guī)則太嚴(yán)格了,比如:
[/Users/xuxinhua/project/golang/studygolang/cmd/studygolang/background.go:57] - G104 (CWE-703): Errors unhandled. (Confidence: HIGH, Severity: LOW)
56: // 生成閱讀排行榜
> 57: c.AddFunc("@daily", genViewRank)
58:
因為 c.AddFunc 會返回 error,這個 error 一般不需要處理(這是啟動定時任務(wù)進行處理),它提示沒有處理,對應(yīng)的規(guī)則是 G104。所以,我們將該規(guī)則排除掉:
$ gosec -exclude ./...
...
Summary:
Gosec : dev
Files : 186
Lines : 27434
Nosec : 0
Issues : 51
這次 issue 只剩下 51 個。查看過程中指出的問題代碼,依然發(fā)現(xiàn)有些規(guī)則可以忽略,比如:
[/Users/xuxinhua/project/golang/studygolang/logic/sitemap.go:266] - G307 (CWE-703): Deferring unsafe method "Close" on type "*os.File" (Confidence: HIGH, Severity: MEDIUM)
265: }
> 266: defer file.Close()
267:
對應(yīng)規(guī)則是 G307:Deferring a method which returns an error。大家一般都會這么做,因此這個規(guī)則也可以排除。
有興趣的可以一步步看,默認提供的 30 來個規(guī)則都檢測了哪些問題,根據(jù)你的項目情況,排除或使用哪些規(guī)則。
接下來,看一下密碼安全問題規(guī)則,這是第一個規(guī)則:G101,只使用這個規(guī)則檢測 studygolang 試試:
$ gosec -include=G101 ./...
...
[/Users/xuxinhua/project/golang/studygolang/http/http.go:437] - G101 (CWE-798): Potential hardcoded credentials (Confidence: LOW, Severity: HIGH)
436: const (
> 437: TokenSalt = "b3%JFOykZx_golang_polaris"
438: NeedReLoginCode = 600
Summary:
Gosec : dev
Files : 186
Lines : 27434
Nosec : 0
Issues : 1
挺厲害,檢查出了 TokenSalt 寫死在代碼里了,這是當(dāng)時準(zhǔn)備做 APP 時寫的一個 Token,雖然影響不大(因為沒有使用),也提醒了這樣的應(yīng)該提前寫在配置文件中。
那 gosec 是怎么檢測到的呢?在官網(wǎng)對這個規(guī)則有說明。它根據(jù)名稱是否類似下面這些來判斷的:
“password” “pass” “passwd” “pwd” “secret” “token”
此外,安全相關(guān)特別要注意的就是 XSS 和 SQL 注入,這方面 gosec 也會有相關(guān)規(guī)則檢測,比如 G201、G202、G203。
注意:通過 gosec 檢測出的 issue,不代表一定有問題,但對我們是一個很好的提醒,讓我們能夠?qū)徱曌约旱拇a,確保相關(guān)地方?jīng)]問題,知道自己為什么這么寫。
gosec 工具其他的使用,可以看文檔說明,自己嘗試。
04 總結(jié)
安全問題,我們永遠不能忽視。很多時候,可能不會有問題,但真出了問題可能就是大問題。在寫代碼時,我們難免會有疏忽,通過使用 gosec 這樣的工具,可以為我們把好最后一道關(guān)。
趕緊用 gosec 檢驗一下你的項目吧。
我是 polarisxu,北大碩士畢業(yè),曾在 360 等知名互聯(lián)網(wǎng)公司工作,10多年技術(shù)研發(fā)與架構(gòu)經(jīng)驗!2012 年接觸 Go 語言并創(chuàng)建了 Go 語言中文網(wǎng)!著有《Go語言編程之旅》、開源圖書《Go語言標(biāo)準(zhǔn)庫》等。
堅持輸出技術(shù)(包括 Go、Rust 等技術(shù))、職場心得和創(chuàng)業(yè)感悟!歡迎關(guān)注「polarisxu」一起成長!也歡迎加我微信好友交流:gopherstudio
