共计 8011 个字符,预计需要花费 21 分钟才能阅读完成。
原文链接
通过扫描 Go AST 查看源代码是否存在平安问题。
一、许可证
依据 Apache 许可证 2.0 版(“许可证”)取得许可。除非恪守许可,否则您不得应用此文件。您能够在此处获取许可证的正本。
二、装置
1. CI 装置
# 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
# The file will be in the current folder where you run the command
# and you can check the checksum like this
echo "<check sum from the check sum file> gosec_vX.Y.Z_OS.tar.gz" | sha256sum -c -
gosec --help
2. GitHub Action
您能够将 gosec 作为 GitHub 操作运行,如下所示:
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: ./...
3. 与代码扫描集成
您能够通过将数据上传为 SARIF 文件,将第三方代码剖析工具与 GitHub 代码扫描集成。
该工作流显示了将 gosec 作为 GitHub 操作工作流中的一个步骤运行的示例,该工作流输入 results.sarif 文件。而后,工作流应用 upload-sarif 操作将 results.sarif 文件上传到 GitHub。
name: "Security Scan"
# Run workflow each time code is pushed to your repository and on a schedule.
# The scheduled workflow runs every at 00:00 on Sunday UTC time.
on:
push:
schedule:
- cron: '0 0 * * 0'
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:
# we let the report trigger content trigger a failure using the GitHub Security features.
args: '-no-fail -fmt sarif -out results.sarif ./...'
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v1
with:
# Path to SARIF file relative to the root of the repository
sarif_file: results.sarif
4. 本地装置
4.1 Go 1.16+
go install github.com/securego/gosec/v2/cmd/gosec@latest
4.2 Go version < 1.16
go get -u github.com/securego/gosec/v2/cmd/gosec
三、用法
Gosec 能够配置为仅运行规定子集,排除某些文件门路,并生成不同格局的报告。默认状况下,所有规定都将针对提供的输出文件运行。要从当前目录递归扫描,您能够提供 ./… 作为输出参数。
1. 可用规定
- G101: Look for hard coded 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 审核 ssh.InsecureIgnoreHostKey 的应用
- G107: Url provided to HTTP request as taint input 提供给 HTTP 申请的 URL 作为污点输出
- G108: Profiling endpoint automatically exposed on /debug/pprof 在 /debug/pprof 上主动公开的剖析端点
- G109: Potential Integer overflow made by strconv.Atoi result conversion to int16/32 strconv.Atoi 后果转换为 int16/32 造成的潜在整数溢出
- G110: Potential DoS vulnerability via decompression bomb 通过解压缩炸弹的潜在 DoS 破绽
- G111: Potential directory traversal 潜在的目录遍历
- G112: Potential slowloris attack 潜在的 slowloris 攻打
- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772) 在 math/big 中应用 Rat.SetString 并溢出 (CVE-2022-23772)
- G114: Use of net/http serve function that has no support for setting timeouts 应用不反对设置超时的 net/http 服务函数
- G201: SQL query construction using format string 应用格局字符串构建 SQL 查问
- G202: SQL query construction using string concatenation 应用字符串连贯的 SQL 查问结构
- G203: Use of unescaped data in HTML templates 在 HTML 模板中应用未本义的数据
- G204: Audit use of command execution 审计命令执行的应用
- G301: Poor file permissions used when creating a directory 创立目录时应用的文件权限不佳
- G302: Poor file permissions used with chmod 与 chmod 一起应用的文件权限不佳
- G303: Creating tempfile using a predictable path 应用可预测的门路创立临时文件
- G304: File path provided as taint input 作为污点输出提供的文件门路
- G305: File traversal when extracting zip/tar archive 提取 zip/tar 存档时的文件遍历
- G306: Poor file permissions used when writing to a new file 写入新文件时应用的文件权限不佳
- G307: Deferring a method which returns an error 提早返回谬误的办法
- G401: Detect the usage of DES, RC4, MD5 or SHA1 检测 DES、RC4、MD5 或 SHA1 的应用状况
- G402: Look for bad TLS connection settings 查找谬误的 TLS 连贯设置
- G403: Ensure minimum RSA key length of 2048 bits 确保最小 RSA 密钥长度为 2048 位
- G404: Insecure random number source (rand) 不平安的随机数源 (rand)
- G501: Import blocklist: crypto/md5 导入黑名单:crypto/md5
- G502: Import blocklist: crypto/des 导入黑名单:crypto/des
- G503: Import blocklist: crypto/rc4 导入黑名单:crypto/rc4
- G504: Import blocklist: net/http/cgi 导入黑名单:net/http/cgi
- G505: Import blocklist: crypto/sha1 导入黑名单:crypto/sha1
- G601: Implicit memory aliasing of items from a range statement 范畴语句中我的项目的隐式内存别名
\
2. 已退休规定
- G105:审核 math/big.Int.Exp 的应用 – CVE 已修复
3. 可抉择规定
默认状况下,gosec 将针对提供的文件门路运行所有规定。然而,能够通过 -include=
标记抉择要运行的规定子集,或应用 -exclude=
标记指定一组要明确排除的规定。
# Run a specific set of rules
$ gosec -include=G101,G203,G401 ./...
# Run everything except for rule G303
$ gosec -exclude=G303 ./...
4. CWE 映射
gosec
检测到的每个问题都映射到 CWE (Common Weakness Enumeration) 以更通用的术语形容破绽。能够在 这里 找到确切的映射。
5. 配置
能够在配置文件中提供许多全局设置,如下所示:
{
"global": {
"nosec": "enabled",
"audit": "enabled"
}
}
nosec
:此设置将笼罩整个代码库中定义的所有#nosec
指令audit
:在审计模式下运行,这容许额定查看失常代码剖析可能太爱管闲事
# Run with a global configuration file 应用全局配置文件运行
$ gosec -conf config.json .
还有一些规定承受配置。例如,在规定 G104 上,能够定义包以及在审核未查看谬误时将跳过的函数列表:
{
"G104": {"ioutil": ["WriteFile"]
}
}
您还能够应用其余模式配置硬编码凭据规定 G101,或调整熵阈值:
{
"G101": {"pattern": "(?i)passwd|pass|password|pwd|secret|private_key|token",
"ignore_entropy": false,
"entropy_threshold": "80.0",
"per_char_threshold": "3.0",
"truncate": "32"
}
}
四、依赖项
gosec 将在 go 模块关上时主动获取正在剖析的代码的依赖关系(例如GO111MODULE=on
)。如果不是这种状况,须要在扫描前通过运行“go get -d”命令显式下载依赖项。
gosec 将在 go 模块关上时主动获取正在剖析的代码的依赖关系(例如GO111MODULE=on
)。如果不是这种状况,须要在扫描前通过运行“go get -d”命令显式下载依赖项。
1. 排除测试文件和文件夹
gosec 将疏忽所有包中的测试文件和供应商目录中的任何依赖项。
能够应用以下标记启用测试文件的扫描:
gosec -tests ./...
也能够排除其余文件夹,如下所示:
gosec -exclude-dir=rules -exclude-dir=cmd ./...
2. 排除生成的文件
gosec 能够疏忽生成的带有默认生成代码正文的 go 文件。
// Code generated by some generator DO NOT EDIT.
gosec -exclude-generated ./...
3. 正文代码
与所有自动检测工具一样,也会呈现误报的状况。如果 gosec 报告已手动验证为平安的故障,则能够应用以 #nosec
结尾的正文来正文代码。#nosec
正文应具备格局 #nosec [RuleList] [– Justification] **。
正文导致 gosec 进行解决 AST 中的任何其余节点,因而能够利用于整个块或更精密地利用于单个表达式。
import "md5" //#nosec
func main(){
/* #nosec */
if x > y {h := md5.New() // this will also be ignored
}
}
当一个特定的误报被辨认并验证为平安时,您可能心愿在一段代码中仅禁止该单个规定(或一组特定规定),同时持续扫描其余问题。为此,您能够列出要在其中暗藏的规定 #nosec正文,例如:/ #nosec G401 / 或 //#nosec G201 G202 G203**
您能够为正文搁置形容或理由文本。理由应该在规定之后以克制并以两个或多个破折号结尾,例如://#nosec G101 G102 — 这是误报
在某些状况下,您可能还想从新拜访应用过 #nosec正文的中央。要运行扫描仪并疏忽任何 #nosec 正文,您能够执行以下操作:
gosec -nosec=true ./...
4. 跟踪删除
如上所述,咱们能够在 gosec 中从内部(应用 -include
/-exclude
)或内联(应用 #nosec
正文)克制违规行为。这种克制炎症可用于生成相应的信号用于审计目标。
咱们能够通过 -track-suppressions
标记跟踪克制,如下所示:
gosec -track-suppressions -exclude=G101 -fmt=sarif -out=results.sarif ./...
- 对于内部克制,gosec 记录克制信息,其中
kind
是external
,justification
是某个句子“全局克制”。 - 对于内联克制,gosec 记录克制信息,其中
kind
是inSource
,而justification
是评论中两个或多个破折号之后的文本。
留神: 只有 SARIF 和 JSON 格局反对跟踪克制。
5. 构建标签
gosec 可能将您的 Go build tags 传递给分析器。它们能够以逗号分隔列表的模式提供,如下所示:
gosec -tags debug,ignore ./...
6. 输入格局
gosec 目前反对 text
、json
、yaml
、csv
、sonarqube
、JUnit XML
、html
和 golint
输入格局。默认状况下,后果将报告给规范输入,但也能够写入输入文件。输入格局由 -fmt 标记管制,输入文件由 -out 标记管制,如下所示:
# Write output in json format to results.json
$ gosec -fmt=json -out=results.json *.go
后果将通过 -stdout
标记报告给规范输入以及提供的输入文件。-verbose
标记在规范输入后果时笼罩输入格局,同时将它们保留在输入文件中:
# Write output in json format to results.json as well as stdout
$ gosec -fmt=json -out=results.json -stdout *.go
# Overrides the output format to 'text' when stdout the results, while writing it to results.json
$ gosec -fmt=json -out=results.json -stdout -verbose=text *.go
留神: gosec 为 SonarQube 生成 通用问题导入格局,并且必须应用 sonar 将报告导入 SonarQube .externalIssuesReportPaths=path/to/gosec-report.json
。
五、开发
1. 编译
您能够应用以下命令构建二进制文件:
make
2. Sarif 类型生成注意事项
装置工具:
go get -u github.com/a-h/generate/cmd/schema-generate
而后生成类型:
schema-generate -i sarif-schema-2.1.0.json -o mypath/types.go
大多数 MarshallJSON/UnmarshalJSON 都被删除了,除了 PropertyBag 的那一个,它能够不便地内联附加属性。其余的能够删除。URI、ID、UUID、GUID 已重命名,因而它合乎此处定义的 Golang 约定。
3. 测试
您能够应用以下命令运行所有单元测试:
make test
4. 公布
您能够通过如下标记版本来创立公布:
git tag v1.0.0 -m "Release version v1.0.0"
git push origin v1.0.0
GitHub 公布工作流 在标签被推送到上游后立刻触发。此流量将应用 goreleaser 操作公布二进制文件,而后它将构建 docker 映像并将其公布到 Docker Hub。
公布的工件应用 cosign 进行签名。您能够应用 cosign.pub 文件中的公钥来验证 docker 映像和二进制文件的签名。
能够应用以下命令验证 docker 映像签名:
cosign verify --key cosign.pub securego/gosec:<TAG>
能够应用以下命令验证二进制文件签名:
cosign verify-blob --key cosign.pub --signature gosec_<VERSION>_darwin_amd64.tar.gz.sig gosec_<VERSION>_darwin_amd64.tar.gz
5. Docker 镜像
您还能够应用以下命令在本地构建 docker 映像:
make image
您能够在容器中针对本地 Go 我的项目运行 gosec
工具。您只需将我的项目装置到卷中,如下所示:
docker run --rm -it -w /<PROJECT>/ -v <YOUR PROJECT PATH>/<PROJECT>:/<PROJECT> securego/gosec /<PROJECT>/...
留神: 当前工作目录须要应用 -w
选项设置,以便胜利解析 go 模块文件中的依赖项
6. 生成 TLS 规定
TLS 规定的配置能够从 Mozilla 的 TLS 明码举荐生成。
首先你须要装置生成器工具:
go get github.com/securego/gosec/v2/cmd/tlsconfig/...
您当初能够在我的项目的根目录中调用go generate
:
go generate ./...
这将生成 rules/tls_config.go
文件,其中将蕴含来自 Mozilla 的以后明码举荐。