如何利用Semgrep自动发现代码中的SQL注入黑洞_编写自定义安全规则

酷浩小哥_3396

酷浩小哥_3396

2026-05-12

554人浏览

原创

sql注入规则常漏报format和f-string,因semgrep默认仅匹配execute()等显式调用,而拼接发生在字符串构造阶段;需锚点前移至插值语法、结合污点追踪与上下文排除orm等安全模式。

如何利用semgrep自动发现代码中的sql注入黑洞_编写自定义安全规则

SQL注入规则为什么总漏报 format 和 f-string?

因为 Semgrep 默认规则大多只匹配 execute()、execute_many() 这类显式调用,而 Python 中大量 SQL 拼接发生在字符串构造阶段——f"SELECT * FROM users WHERE id = {user_id}" 或 "SELECT ...".format(id=user_id) 根本没进数据库函数体,静态分析器一眼扫过去就跳过了。

真正要捕获这类“黑洞”,得把规则锚点前移到字符串拼接行为本身,并结合上下文判断是否最终流入执行函数。实操建议:

  • 用 pattern-either 同时覆盖 f"、.format(、% 三类插值语法,别只盯 f-string
  • 必须加 metavariable-regex 限制变量名含 sql、query、stmt 等关键词,否则会误报日志拼接
  • 用 taint-mode: taint + sources(如 request.args.get)和 sinks(如 cursor.execute)做污点追踪,比纯模式匹配准得多

如何让规则不把 ORM 查询当漏洞报?

像 User.query.filter(User.id == user_id).all() 或 session.execute(text("...")) 这类用法本身安全,但 Semgrep 模式若写成 text("...") 就会无差别命中——它不理解 text() 是 SQLAlchemy 的安全封装,更不知道 .filter() 自动参数化。

绕过误报的关键是「白名单式排除」:

银河易创
银河易创

一款集AI对话、绘画、音乐、视频和PPT等能力于一体的一站式AIGC创作平台。

下载
  • 在 patterns 下用 pattern-not 显式排除 text(...)、.filter(、.where( 等 ORM 特征调用
  • 对 cursor.execute 类规则,加 pattern-not-inside 排除包裹在 try/except 且含 sqlalchemy import 的文件(说明项目用了 ORM)
  • 慎用 pattern-not 直接排除整个函数名,比如排除 execute 会导致漏掉原生 DB-API 调用——应限定在 ORM 上下文中排除

semgrep --config 本地规则跑不通?检查这三处

写完 YAML 规则丢进 .semgrep/rules/ 目录,运行却提示 No matches found 或直接报错,大概率卡在这几个地方:

  • YAML 缩进错位:Semgrep 对空格极其敏感,patterns 必须顶格,其子项(如 pattern、focus-metavariable)统一缩进 2 空格,多一个少一个都解析失败
  • 语言声明写错:language: python 不能写成 lang: py 或漏掉——Semgrep 不猜语言,没声明就跳过该规则
  • 路径未包含:用 semgrep --config ./rules/sql-inject.yaml 时,确保当前目录能访问到该文件;若用 --config auto,规则必须放在 .semgrep/rules/ 且文件名以 .yml 结尾(不是 .yaml)

为什么生产环境要禁用 pattern 单独匹配?

单独靠 pattern: 'f"SELECT * FROM $TABLE WHERE id = {$ID}"' 这种写法,在真实代码库中基本等于无效——变量名千奇百怪(user_input、req_id、pk),表名动态拼接(f"logs_{year}"),甚至 SQL 被拆成多行字符串加 += 拼接。这种规则只能当玩具玩。

实际可用的规则必须组合使用:

  • 用 metavariable-pattern 抓取所有疑似用户输入的变量(如 request.*.get、args[、json.get()
  • 用 taint-mode: taint 追踪该变量是否经由字符串插值进入 execute / executemany 参数
  • 最后用 pattern-not-inside 排除已知安全上下文(如被 escape_string() 包裹、或出现在 logging.info() 中)

真正难的不是写一条规则,而是让多条规则协同判断「这段 SQL 构造链里有没有未经消毒的外部输入」——漏掉任意一环,要么误报炸屏,要么漏报留洞。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

sql注入

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4183

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

891

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1089

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6081

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2963

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6060

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8141

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1110

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

972

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP开发基础之数据库篇(PDO)
PHP开发基础之数据库篇(PDO)

共10课时 | 2.3万人学习