通过扫描 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 " 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:
可以使用以下命令验证二进制文件签名:
cosign verify-blob --key cosign.pub --signature gosec__darwin_amd64.tar.gz.sig gosec__darwin_amd64.tar.gz
5. Docker 镜像
您还可以使用以下命令在本地构建 docker 映像:
make image
您可以在容器中针对本地 Go 项目运行gosec
工具。 您只需将项目安装到卷中,如下所示:
docker run --rm -it -w // -v /:/ securego/gosec //...
注意: 当前工作目录需要使用 -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 的当前密码推荐。