gosec 默认不输出具体问题详情,需用 -fmt=text 或 -fmt=json 显式指定格式才能显示文件、行号、规则ID等可定位信息;忽略误报仅支持 // #nosec 注释,//nolint 无效。

gosec 默认不输出具体问题详情,只返回 exit code 和 summary,直接跑 gosec ./ 很可能在 CI 里看到 “failed” 却找不到哪行代码有问题——这是最常卡住人的第一关。
怎么让 gosec 显示具体报错位置和规则
默认行为是只打印统计摘要(比如 “Found 3 issues”),不列文件、行号、规则 ID。必须显式指定输出格式才能看到可定位的问题:
- 加
-fmt=text:终端友好,带文件路径、行号、规则 ID(如G101)、说明 - 加
-fmt=json:适合脚本解析或集成到 IDE/CI,输出结构化数据 - 加
-out=report.txt配合-fmt=text可保存结果,避免滚动丢失 - 别用
-fmt=report(旧版遗留):它不输出问题详情,只输出汇总,容易误以为“没扫出东西”
推荐组合:gosec -fmt=text -out=gosec-report.txt ./
忽略误报的两种写法,一种有效,一种完全无效
// #nosec 是唯一被 gosec 认可的忽略注释;//nolint:gosec 或 //nolint 在 gosec 里压根不生效——这是很多人白忙活的原因。
立即学习“go语言免费学习笔记(深入)”;
- 忽略整行:把
// #nosec放在触发警告的那行末尾,例如log.Printf("debug: %v", data) // #nosec G104 - 忽略特定规则:写成
// #nosec G101或// #nosec G104,G201,多个规则用逗号分隔 - 加理由说明(强烈建议):
// #nosec G402 -- internal test env, TLS verify disabled intentionally - 注意:
// gosec: ignore是另一套语法,仅用于「函数级」或「行级」全局忽略,且必须紧贴代码上方,不能隔空行
排除目录和生成代码的正确姿势
-exclude-dir 支持多次出现,但路径写法有坑;自动生成代码(如 protobuf 或 mock 产出)必须显式跳过,否则大量误报。
- 排除 vendor 和 .git 是默认行为,不用写;但
internal/gen、mocks、pb这类需手动加:gosec -exclude-dir=mocks -exclude-dir=pb ./ - 排除生成代码:优先用
-exclude-generated,它会识别// Code generated by开头的文件注释(注意:必须是标准格式,不能少字或多空格) - 如果生成文件没带标准注释,就只能靠
-exclude-dir或正则过滤(后者需配 JSON 配置文件,较重) - 慎用
-tests:开启后会扫描*_test.go,但测试里常见InsecureSkipVerify: true这类合法不安全操作,容易引发 G402 误报
CI 中 gosec 失败却无日志?先检查这三件事
GitHub Actions 或 Jenkins 里 gosec 报 exit code 1 但日志为空,基本不是工具问题,而是输出被吞了或配置错位。
- 确认是否漏了
-fmt=text或-fmt=json:没有这个参数,gosec 真的什么都不往 stdout 打 - 检查是否用了
set -e或类似失败中断逻辑:gosec 发现问题就 exit 1,后续命令不执行,导致你没看到 report 输出命令的结果 - 别信
|| true掩盖问题:加了它虽然构建不红,但等于关掉了告警,失去扫描意义 - CI 推荐写法:
gosec -fmt=json -out=gosec.json ./ || (cat gosec.json && exit 1),确保失败时也能看到内容
真正麻烦的是规则调优——比如 G101 对密码字符串的熵值判断、G104 对某些包内 error 忽略的定制,这些没法靠命令行参数解决,得上 JSON 配置文件。但 80% 的项目,先搞定上面四点,就能让 gosec 从“鸡肋”变成每天自动提醒你哪里写错了的真帮手。


















