整个中文网络关于semgrep的信息非常之少,竟然只找到一篇内容还过得去的文章:介绍semgrep扫描xss漏洞,而且读起来还像是翻译的。这般待遇实在是与semgrep的强大和在国外的流行完全匹配不上,再加上近期团队做安全编码规范的配套扫描工具建设,从而催生了本文。
简介
semgrep是一款基于Facebook开源SAST工具pfff中的sgrep组件开发的开源SAST工具,目前由安全公司r2c统一开发维护,走的是开源共建模式,主打轻量、定制化,slogan是Static analysis at ludicrous speed, Find bugs and enforce code standards(以极致的速度扫描发现bug并强化代码规范的落地)。
原理
semgrep同时支持正则匹配和AST分析两种模式,跟国内前些年流行的开源SAST工具cobra原理比较相近,从技术演进的方向上看,semgrep大致位于中间地带:
如下图所示,扫描器核心逻辑在semgrep-core,可以看到工具主要是由OCaml语言开发,然后通过python执行系统命令去调用semgrep-core,关于semgrep-core的具体实现另文介绍。
优点
语言 | 框架 | 支持情况 |
---|---|---|
python | django/flask/boto/sqlalchemy | 一般 |
java | spring | 较好 |
go | gorilla/grpc/pgorm(目前我们还实现了xorm) | 一般 |
js/ts | express/nest/vue/react/angular/sequelize | 一般 |
php | Laravel | 一般 |
其他 | ... | 几乎没有 |
缺点
与其他SAST工具和Linter的区别
相信看了上面的介绍后,很多人会认为semgrep更像是一款很像SAST工具的Linter,但是谁又能说两者一定有严格的界限呢?例如用eslint或者pylint扫描安全风险的太常见了,所以下面也将从官方FAQ中针对这块稍作介绍,主要列举与SonarQube、CodeQL的对比。
工具 | 定位 | 是否开源 | 是否收费 | 扫描速度 | 是否需要编译 | 是否支持定制规则 | 规则开源程度 | 规则定制难度 | 支持语言 | 是否支持自动修复 | 数据流跟踪能力 | 准确度 | 覆盖度 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Semgrep | 编码安全规范违规检测(与漏洞检测) | 是 | 工具本身否,但saas服务收费 | 很快,官方号称在20k-100k loc/sec每条规则 | 否 | 是 | 全部开源 | 简单,编写yaml配置 | 17+ | 支持 | 一般,污点跟踪、常量传播、等价替代等特性较弱,还在实验阶段,但可试用,另外也不支持过程间分析 | 中等(缺乏数据统计,只能定性分析),但官方目标是90%以上 | 最多:内置多种框架支持,同时支持app漏洞扫描 |
SonarQube | 发现不符合编码规范的编码问题 | 是,但与商业版相比存在特性缺失 | 存在商业版本 | 慢,大约400loc/sec | 否 | 是 | 工具自带,但官方不统一维护 | 复杂 | java为主 | 不支持 | 不支持 | 从编码规范角度上看高,漏洞角度看低 | 从编码规范角度上看高,漏洞角度看低 |
CodeQL | 漏洞检测 | 否 | 只允许用于开源代码扫描,涉及CI或者闭源代码需要收费 | 很慢 | 是 | 是 | 工具自带,但官方不统一维护 | 复杂,需要深度学习ql语法 | java/c/c++/js/python等5+,不支持php | 否 | 很强大,例如支持过程间分析、完善的数据流跟踪能力 的 | 看定制规则质量,如果规则写得好,准确率是最高 | 完全需要定制规则 |
测试
近期我们团队在对PCG开源代码仓库做安全编码规范扫描,目前已使用codeql编写了go sql拼接的相关规则,当时为了验证semgrep的扫描效果,我们也针对部分使用xorm框架的业务做了对比评测,涉及5套代码仓库、10万行代码,最终测试结果如下,可以发现semgrep在编码安全规范扫描这块的总体效果更好,已知问题还是准确率比codeql稍低一点,但也在95%以上。
工具 | 扫出风险数 | 准确率 | 扫描速度 |
---|---|---|---|
semgrep | 61 | 58/61 | 每条规则4500 loc/sec |
codeql | 44 | 42/44 | 无具体统计,但不高于每条规则600 loc/sec |
规则定制难度
根据大概估算,查找、理解xorm sql执行的sink点大概需要30分钟,编写xorm拼接靶场代码需要20分钟,加上编写规则15分钟,全程花费在1个小时左右,而使用codeql开发,单纯编写规则就要0.5个人天,可以看到semgrep规则开发成本非常低。
准召率
针对xorm sql拼接的规则还比较粗糙,实际误报的场景如下:
而从xorm sql注入的角度来看,该规则未优化前的误报率可能在50%左右,甚至更高。
扫描速度
单就go语言的扫描情况来看,每条规则可达到4500 loc/sec的扫描速度,效果还是非常理想的。
结论
综上所述,从工具定位、自定义规则提供的能力以及扫描速度来看,正如官方slogan所言,Static analysis at ludicrous speed, Find bugs and enforce code standards,semgrep是非常适合做安全编码规范扫描的。
下篇将分享semgrep具体实现逻辑,欢迎关注。
参考资料