securego/gosec

GitHub: securego/gosec

一款面向 Go 语言源码的静态安全检查工具,通过 AST 和 SSA 分析以及污点追踪来发现注入、加密弱点、硬编码凭证等常见安全问题。

Stars: 8852 | Forks: 698

# gosec - Go 安全检查器 通过扫描 Go AST 和 SSA 代码表示来检查源代码中的安全问题。 ## 快速链接 - [GitHub Action](#github-action) - [本地安装](#local-installation) - [快速入门](#quick-start) - [常见用法](#common-usage-patterns) - [选择规则](#selecting-rules) - [输出格式](#output-formats) ## 功能 - **基于模式的规则** 用于检测 Go 代码中常见的安全问题 - **基于 SSA 的分析器** 用于类型转换、切片边界和加密问题 - **污点分析** 用于跟踪从用户输入到危险函数的数据流(SQL 注入、命令注入、路径遍历、SSRF、XSS、日志注入、SMTP 注入、SSTI、不安全的反序列化、开放重定向) ## 许可证 根据 Apache 许可证 2.0 版("License")授权。 除非遵守许可证,否则您不得使用此文件。 您可以[在此处](http://www.apache.org/licenses/LICENSE-2.0)获取许可证副本。 ## 项目状态 [![CII 最佳实践](https://bestpractices.coreinfrastructure.org/projects/3218/badge)](https://bestpractices.coreinfrastructure.org/projects/3218) [![构建状态](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/d367199be8135112.svg)](https://github.com/securego/gosec/actions?query=workflows%3ACI) [![覆盖率状态](https://codecov.io/gh/securego/gosec/branch/master/graph/badge.svg)](https://codecov.io/gh/securego/gosec) [![GoReport](https://goreportcard.com/badge/github.com/securego/gosec)](https://goreportcard.com/report/github.com/securego/gosec) [![GoDoc](https://pkg.go.dev/badge/github.com/securego/gosec/v2)](https://pkg.go.dev/github.com/securego/gosec/v2) [![文档](https://readthedocs.org/projects/docs/badge/?version=latest)](https://securego.io/) [![下载量](https://img.shields.io/github/downloads/securego/gosec/total.svg)](https://github.com/securego/gosec/releases) [![GHCR](https://img.shields.io/badge/ghcr.io-securego%2Fgosec-blue)](https://github.com/orgs/securego/packages/container/package/gosec) [![Slack](https://img.shields.io/badge/Slack-4A154B?style=for-the-badge&logo=slack&logoColor=white)](http://securego.slack.com) [![go-recipes](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/f627cc58ca135119.svg)](https://github.com/nikolaydubina/go-recipes) ## 安装说明 ### GitHub Action 您可以按照以下方式将 `gosec` 作为 GitHub Action 运行: 使用带有 `@master` 的版本标签,该标签固定到最新的稳定版本。这将提供稳定的行为。 ``` 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@v3 - name: Run Gosec Security Scanner uses: securego/gosec@master with: args: ./... ``` #### 扫描带有私有模块的项目 如果您的项目导入了私有的 Go 模块,您需要配置身份验证,以便 `gosec` 能够获取依赖项。请在您的工作流中设置以下环境变量: - `GOPRIVATE`:应被视为私有的模块路径前缀的逗号分隔列表(例如 `github.com/your-org/*`)。 - `GITHUB_AUTHENTICATION_TOKEN`:具有对您的私有仓库读取权限的 GitHub token。 ``` name: Run Gosec on: push: branches: - master pull_request: branches: - master jobs: tests: runs-on: ubuntu-latest env: GO111MODULE: on GOPRIVATE: github.com/your-org/* GITHUB_AUTHENTICATION_TOKEN: ${{ secrets.PRIVATE_REPO_TOKEN }} steps: - name: Checkout Source uses: actions/checkout@v3 - name: Run Gosec Security Scanner uses: securego/gosec@v2 with: args: ./... ``` ### 与代码扫描集成 您可以通过将数据作为 SARIF 文件上传,[集成第三方代码分析工具](https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/integrating-with-code-scanning)与 GitHub 代码扫描。 该工作流展示了一个在 GitHub Action 工作流中作为步骤运行 `gosec` 并输出 `results.sarif` 文件的示例。 然后工作流使用 `upload-sarif` action 将 `results.sarif` 文件上传到 GitHub。 ``` name: "Security Scan" # 每次将代码推送到您的仓库时以及按计划运行 workflow。 # 计划的 workflow 在每周日 UTC 时间 00:00 运行。 on: push: schedule: - cron: '0 0 * * 0' jobs: tests: runs-on: ubuntu-latest env: GO111MODULE: on steps: - name: Checkout Source uses: actions/checkout@v3 - name: Run Gosec Security Scanner uses: securego/gosec@v2 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@v2 with: # Path to SARIF file relative to the root of the repository sarif_file: results.sarif ``` ### Go 分析 `goanalysis` 包提供了一个 [`golang.org/x/tools/go/analysis.Analyzer`](https://pkg.go.dev/golang.org/x/tools/go/analysis) 用于与支持标准 Go 分析接口的工具集成,例如 Bazel 的 [nogo](https://github.com/bazelbuild/rules_go/blob/master/go/nogo.rst) 框架: ``` nogo( name = "nogo", deps = [ "@com_github_securego_gosec_v2//goanalysis", # add more analyzers as needed ], visibility = ["//visibility:public"], ) ``` ### 本地安装 gosec 需要 Go 1.25 或更高版本。 ``` go install github.com/securego/gosec/v2/cmd/gosec@latest ``` ## 快速入门 ``` # 扫描当前 module 中的所有 package gosec ./... # 写入 JSON 报告 gosec -fmt json -out results.json ./... # 为 code scanning 写入 SARIF 报告 gosec -fmt sarif -out results.sarif ./... ``` ### 退出代码 - `0`:扫描完成,没有未抑制的发现/错误 - `1`:至少有一个未抑制的发现或处理错误 - 使用 `-no-fail` 将始终返回 `0` ## 用法 Gosec 可以配置为仅运行一部分规则,排除某些文件路径,并生成不同格式的报告。默认情况下,所有规则都将针对提供的输入文件运行。要从当前目录递归扫描,您可以提供 `./...` 作为输入参数。 ### 可用规则 gosec 包含以下类别的规则: - `G1xx`:通用安全编码问题(例如硬编码凭证、不安全使用、HTTP 加固、cookie 安全) - `G2xx`:查询/模板/命令构建中的注入风险 - `G3xx`:文件和路径处理风险(权限、遍历、临时文件、存档提取) - `G4xx`:加密和 TLS 弱点 - `G5xx`:列入黑名单的导入 - `G6xx`:Go 特有的正确性/安全检查(例如 range 别名和切片边界) - `G7xx`:污点分析规则(SQL 注入、命令注入、路径遍历、SSRF、XSS、日志、SMTP 注入、SSTI、不安全的反序列化和开放重定向) 有关完整列表、规则描述和每条规则的配置,请参见 [RULES.md](RULES.md)。 ### 已废弃的规则 - G105:审计 math/big.Int.Exp 的使用 - [CVE 已修复](https://github.com/golang/go/issues/15184) - G307:延迟一个返回错误的方法 - 尽管有这篇[博文](https://www.joeshaw.org/dont-defer-close-on-writable-files/)中的详细信息,但它造成的麻烦多于安全问题的修复 ### 选择规则 默认情况下,gosec 将针对提供的文件路径运行所有规则。但是,可以通过 `-include=` 标志选择要运行的规则子集,或者使用 `-exclude=` 标志指定要明确排除的规则集。 ``` # 运行一组特定的 rule $ gosec -include=G101,G203,G401 ./... # 运行除 rule G303 之外的所有内容 $ gosec -exclude=G303 ./... ``` ### CWE 映射 `gosec` 检测到的每个问题都会映射到一个 [CWE (通用缺陷枚举)](http://cwe.mitre.org/data/index.html),该枚举以更通用的术语描述了该漏洞。确切的映射可以在[此处](https://github.com/securego/gosec/blob/master/issue/issue.go#L50)找到。 ### 配置 可以在配置文件中提供许多全局设置,如下所示: ``` { "global": { "nosec": "enabled", "audit": "enabled" } } ``` - `nosec`:此设置将覆盖整个代码库中定义的所有 `#nosec` 指令 - `audit`:在审计模式下运行,这会启用额外的检查,对于正常的代码分析来说可能过于严格 ``` # 使用全局 configuration file 运行 $ gosec -conf config.json . ``` ### 基于路径的规则排除 具有多个组件的大型仓库可能需要针对不同的路径使用不同的安全规则。使用 `exclude-rules` 来抑制特定路径的特定规则。 **配置文件:** ``` { "exclude-rules": [ { "path": "cmd/.*", "rules": ["G204", "G304"] }, { "path": "scripts/.*", "rules": ["*"] } ] } ``` **CLI 标志:** ``` # 从 cmd/ 目录中排除 G204 和 G304 gosec --exclude-rules="cmd/.*:G204,G304" ./... # 从 scripts/ 目录中排除所有 rule gosec --exclude-rules="scripts/.*:*" ./... # 多重排除 gosec --exclude-rules="cmd/.*:G204,G304;test/.*:G101" ./... ``` | 字段 | 类型 | 描述 | |-------|------|-------------| | `path` | 字符串 (regex) | 与文件路径匹配的正则表达式 | | `rules` | []字符串 | 要排除的规则 ID。`*` 表示全部 | #### 规则配置 某些规则也接受配置标志;这些标志记录在 [RULES.md](https://github.com/securego/gosec/blob/master/RULES.md) 中。 #### Go 版本 某些规则需要特定的 Go 版本,该版本从项目中存在的 Go 模块文件中检索。如果找不到此版本,它将回退到 Go 运行时版本。 Go 模块版本是使用 `go list` 命令解析的,在某些情况下可能会导致性能下降。在这种情况下,可以通过设置环境变量 `GOSECGOVERSION=go1.21.1` 轻松提供 Go 模块版本。 ### 依赖项 gosec 使用 Go 模块加载包。在大多数项目中,依赖项在扫描期间会自动解析。 如果缺少依赖项,请运行: ``` go mod tidy go mod download ``` ### 排除测试文件和文件夹 gosec 将忽略所有包中的测试文件以及 vendor 目录中的任何依赖项。 可以使用以下标志启用对测试文件的扫描: ``` gosec -tests ./... ``` 此外,可以按如下方式排除附加文件夹: ``` gosec -exclude-dir=rules -exclude-dir=cmd ./... ``` ### 排除生成的文件 gosec 可以忽略带有默认生成代码注释的生成 go 文件。 ``` // Code generated by some generator DO NOT EDIT. ``` ``` gosec -exclude-generated ./... ``` ### 自动修复漏洞 gosec 可以根据 AI 建议提供修复方案。它将调用 AI API 来接收针对安全发现的建议。您可以通过提供以下命令行参数来启用此功能: - `ai-api-provider`:AI API 提供商的名称。支持的提供商: - **Gemini**:`gemini-3-pro-preview`(默认),`gemini-2.5-pro`,`gemini-2.5-flash`,`gemini-2.5-flash-lite` - **Claude**:`claude-sonnet-4-6`(默认),`claude-opus-4-7`,`claude-opus-4-6`,`claude-sonnet-4-5`,`claude-opus-4-5`,`claude-haiku-4-5` - **OpenAI**:`gpt-5.4`(默认),`gpt-5.4-mini`,`gpt-5.4-nano` - **自定义 OpenAI 兼容**:任何自定义模型名称(需要 `ai-base-url`) - `ai-api-key` 或设置环境变量 `GOSEC_AI_API_KEY`:用于访问 AI API 的密钥 - 对于 Gemini,您可以按照[这些说明](https://ai.google.dev/gemini-api/docs/api-key)创建 API 密钥 - 对于 Claude,请从 [Anthropic Console](https://console.anthropic.com/) 获取您的 API 密钥 - 对于 OpenAI,请从 [OpenAI Platform](https://platform.openai.com/api-keys) 获取您的 API 密钥 - `ai-base-url`:(可选)用于 OpenAI 兼容 API 的自定义基础 URL(例如 Azure OpenAI、LocalAI、Ollama) - `ai-skip-ssl`:(可选)跳过 AI API 的 SSL 证书验证(对于自签名证书很有用) **示例:** ``` # 使用 Gemini gosec -ai-api-provider="gemini-3-pro-preview" \ -ai-api-key="your_key" ./... # 使用 Claude gosec -ai-api-provider="claude-sonnet-4-6" \ -ai-api-key="your_key" ./... # 使用 OpenAI gosec -ai-api-provider="gpt-5.4" \ -ai-api-key="your_key" ./... # 使用 Azure OpenAI gosec -ai-api-provider="gpt-5.4" \ -ai-api-key="your_azure_key" \ -ai-base-url="https://your-resource.openai.azure.com/openai/deployments/your-deployment" \ ./... # 使用带有自定义 model 的本地 Ollama gosec -ai-api-provider="llama3.2" \ -ai-base-url="http://localhost:11434/v1" \ ./... # 使用自签名证书 API gosec -ai-api-provider="custom-model" \ -ai-api-key="your_key" \ -ai-base-url="https://internal-api.company.com/v1" \ -ai-skip-ssl \ ./... ``` ### 注释代码 与所有自动检测工具一样,在某些情况下会出现误报。如果 gosec 报告了一个经人工验证为安全的失败,可以使用以 `#nosec` 开头的注释来注释代码。 `#nosec` 注释应采用 `#nosec [RuleList] [-- Justification]` 的格式。 `#nosec` 注释需要放置在报告警告的行上。 ``` func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, // #nosec G402 }, } client := &http.Client{Transport: tr} _, err := client.Get("https://go.dev/") if err != nil { fmt.Println(err) } } ``` 当识别出特定的误报并验证为安全时,您可能希望在某段代码中仅抑制这一条规则(或一组特定规则),同时继续扫描其他问题。为此,您可以在 `#nosec` 注释中列出要抑制的规则,例如:`/* #nosec G401 */` 或 `//#nosec G201 G202 G203` 您可以在注释中加入描述或理由文本。理由应在要抑制的规则之后,并以两个或多个破折号开头,例如:`//#nosec G101 G102 -- This is a false positive` 或者,gosec 还支持 `//gosec:disable` 指令,其功能类似于 `#nosec`: ``` //gosec:disable G101 -- This is a false positive ``` 在某些情况下,您可能还希望重新检查使用了 `#nosec` 或 `//gosec:disable` 注释的地方。要运行扫描器并忽略所有 `#nosec` 注释,您可以执行以下操作: ``` gosec -nosec=true ./... ``` #### 要求规则 ID 和理由 为了防止注释无意中抑制不相关的规则,或者在添加时没有给出解释,gosec 接受两个可选标志。两者都默认为 `false`,因此现有代码库将保持不变地工作。 - `-nosec-require-rules` 拒绝没有列出任何规则 ID 的裸 `#nosec` / `//gosec:disable` 指令。 - `-nosec-require-justification` 拒绝在规则列表后没有附带 `-- justification` 的指令。 启用后,未通过检查的指令将不再抑制任何发现,并会作为错误在输出中与该行上的任何潜在问题一起报告。 ``` gosec -nosec-require-rules -nosec-require-justification ./... ``` 相同的选项可以通过全局配置块设置: ``` { "global": { "nosec-require-rules": "enabled", "nosec-require-justification": "enabled" } } ``` ### 跟踪抑制 如上所述,我们可以外部抑制违规(使用 `-include`/`-exclude`)或内联抑制(使用 `#nosec` 注释)。可以发出抑制元数据以供审计。 使用 `-track-suppressions` 启用抑制跟踪: ``` gosec -track-suppressions -exclude=G101 \ -fmt=sarif -out=results.sarif ./... ``` - 对于外部抑制,gosec 记录的抑制信息中 `kind` 为 `external`,`justification` 为 `Globally suppressed.`。 - 对于内联抑制,gosec 记录的抑制信息中 `kind` 为 `inSource`,`justification` 为注释中两个或多个破折号后的文本。 **注意:** 只有 SARIF 和 JSON 格式支持跟踪抑制。 ### 构建标签 gosec 能够将您的 [Go 构建标签](https://pkg.go.dev/go/build/)传递给分析器可以按如下方式以逗号分隔的列表形式提供它们: ``` gosec -tags debug,ignore ./... ``` ### 输出格式 gosec 支持 `text`、`json`、`yaml`、`csv`、`junit-xml`、`html`、`sonarqube`、`golint` 和 `sarif`。默认情况下,结果将报告到 stdout,但也可以写入输出文件。输出格式由 `-fmt` 标志控制,输出文件由 `-out` 标志控制,如下所示: ``` # 以 json 格式将 output 写入 results.json $ gosec -fmt=json -out=results.json *.go ``` 使用 `-stdout` 可以在写入 `-out` 的同时打印结果。 使用 `-verbose` 可以在保留文件格式的同时覆盖 stdout 的格式。 ``` # 以 json 格式将 output 写入 results.json 并输出到 stdout $ gosec -fmt=json -out=results.json -stdout *.go # 在将结果输出到 stdout 时,将 output format 覆盖为 'text', # 同时将其写入 results.json $ gosec -fmt=json -out=results.json -stdout -verbose=text *.go ``` **注意:** gosec 为 SonarQube 生成[通用问题导入格式](https://docs.sonarqube.org/latest/analysis/generic-issue/),并且必须使用 `sonar.externalIssuesReportPaths=path/to/gosec-report.json` 将报告导入 SonarQube。 ## 常见用法 ``` # 仅在 medium+ severity findings 时失败 gosec -severity medium ./... # 仅在 medium+ confidence findings 时失败 gosec -confidence medium ./... # 排除特定路径的特定 rule gosec --exclude-rules="cmd/.*:G204,G304;scripts/.*:*" ./... # 在 scan 中排除生成的文件 gosec -exclude-generated ./... # 在 scan 中包含测试文件 gosec -tests ./... ``` ## 开发 开发文档已移至 [DEVELOPMENT.md](DEVELOPMENT.md)。 ## 谁在使用 gosec? 这是 gosec 部分用户的[列表](USERS.md)。 ## 赞助商 通过成为赞助商来支持此项目。您的徽标将显示在此处,并附有指向您网站的链接。
标签:AST扫描, CISA项目, DevSecOps, EVTX分析, GitHub Action, Go, Go安全, Ruby工具, SAST, SMTP注入, SSA分析, SSRF, SSTI, XSS, 上游代理, 代码安全, 反序列化, 命令注入, 安全检查器, 开放重定向, 日志审计, 日志注入, 漏洞情报, 漏洞枚举, 盲注攻击, 聊天机器人, 自动化payload嵌入, 路径遍历, 错误基检测, 静态代码分析