3 步跑通 Semgrep 代码扫描:新手入门指南
【免费下载链接】semgrepLightweight static analysis for many languages. Find bug variants with patterns that look like source code.项目地址: https://gitcode.com/GitHub_Trending/se/semgrep
上周 code review 抓到一处写死的密钥,但留在生产代码里的 print 语句却没人发现——问题在于缺少对代码库的系统性扫描,同类问题会一次次被合并进去。Semgrep 代码扫描针对的就是这类场景:规则写成接近真实源代码的形式,然后逐文件匹配项目里的代码。
📌 它是什么:代码的"语义 grep"
Semgrep 是一款轻量级静态分析工具,开源、本地运行,支持 Python、JavaScript、Java、Go 等 30 多种语言。它与 grep 的差异在于匹配代码结构而非字符:grep "print"分不清注释里的字样和真实调用,而模式print($X)只命中真正的调用。与传统 SAST 的差异在于规则语法——不需要学 AST,也不涉及专门 DSL,你写的东西基本就是能跑的代码。
🚀 Semgrep 安装与首次扫描
从零到出结果,最短路径是 3 条命令:
python3 -m pip install semgrep # 安装 CLI cd my-project # 进入项目根目录 semgrep -e '$X == $X' --lang=py . # 用一条单行规则跑检查这条单行规则查找a == a这类自比较写法,多是笔误。项目里只要有匹配代码,会立刻输出结果:哪个文件、第几行、命中哪条规则。
🔍 Semgrep 自定义规则是怎么匹配代码的
规则是一个 YAML 文件,字段很少:id是唯一标识,languages指定语言,pattern是匹配模式,message是报告文案,severity是级别。扫描时 Semgrep 先把目标文件解析成 AST,再把pattern与该 AST 做结构匹配——...代表任意表达式或语句序列,$X这样的元变量可以绑定任意标识符,同名元变量必须绑定到相同内容。
下面是一条最小的 Semgrep 自定义规则,用于找出 Python 里的全部 print 调用:
rules: - id: python-no-prints-in-prod languages: [python] message: 用 logging.debug() 替代 print() pattern: print(...) severity: INFO存为mymodule.yaml后执行semgrep scan --config myrule.yaml .即可。仓库的 tests/rules/ 目录下有 900 多条规则示例,每条都配了同名目标代码文件,很适合用来理解匹配行为。
🐛 真实场景:从发现到修复一处硬编码密码
假设项目里有个 Flask 服务,数据库密码直接写在config.py。写一条短规则:
rules: - id: hardcoded-password languages: [python] message: 密码不要写死在代码里,请从环境变量读取 pattern: password = "..." severity: ERROR扫描一遍,报告会直接指向config.py:12;改成password = os.environ["DB_PASSWORD"]后再扫一遍,0 命中,闭环完成。把这条规则放进 pre-commit 或 CI,同类问题以后就进不了主干。
⚠️ 常见误区与避坑
- 误区:把
...当成正则通配符。纠正:...是代码结构的占位符,匹配任意表达式或语句序列,不是字符级的.*,写法不对会直接报解析错误。 - 误区:认为开源版 Semgrep 能追踪跨文件数据流。纠正:社区版匹配主要在单文件、单函数边界内进行,跨函数、跨文件的污点分析属于付费 Pro 引擎能力,选型时别按全功能 taint 工具预期。
- 误区:模式写得过宽,如
$F(...)匹配一切调用。纠正:先收窄到具体函数名,再按需加pattern-not排除例外,误报会少得多。
三步跑通后,项目就有了基础扫描能力,剩下的工作只是照着示例写新规则。详细用法见 README.md。
【免费下载链接】semgrepLightweight static analysis for many languages. Find bug variants with patterns that look like source code.项目地址: https://gitcode.com/GitHub_Trending/se/semgrep
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考