gosec - Golang 安全检查器

原文链接

通过扫描 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. 已退休规则

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 记录抑制信息,其中kindexternaljustification 是某个句子“全局抑制”。
  • 对于内联抑制,gosec 记录抑制信息,其中 kindinSource,而 justification 是评论中两个或多个破折号之后的文本。

注意: 只有 SARIF 和 JSON 格式支持跟踪抑制。


5. 构建标签

gosec 能够将您的 Go build tags 传递给分析器。它们可以以逗号分隔列表的形式提供,如下所示:

gosec -tags debug,ignore ./...

6. 输出格式

gosec 目前支持 textjsonyamlcsvsonarqubeJUnit XMLhtmlgolint 输出格式。 默认情况下,结果将报告给标准输出,但也可以写入输出文件。 输出格式由 -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 的当前密码推荐。

你可能感兴趣的:(go后端)