Bandit能检测SQL注入吗

wen python案例 1

本文目录导读:

Bandit能检测SQL注入吗

  1. Bandit 检测 SQL 注入的原理
  2. Bandit 的局限性(为什么说“有限度”)
  3. 实际使用建议

可以,但有限度。

Bandit 是一个针对 Python 代码的静态分析工具,它主要检查源代码中是否存在模式上不安全的调用,对于 SQL 注入,它能够检测出最明显、最经典的写法,但对复杂或动态拼接的情况则无能为力。


Bandit 检测 SQL 注入的原理

Bandit 通过模式匹配来查找代码中使用了某些特定的、已知容易导致 SQL 注入的函数或方法。

它会检查你是否:

  • 直接使用字符串格式化字符串拼接来构建 SQL 查询。
  • 使用了不安全的数据库驱动方法(如 raw_inputcursor.execute 配合拼接字符串)。

典型能检测到的例子:

# Bandit 会报 B608: hardcoded SQL expression
def unsafe_query(user_input):
    query = "SELECT * FROM users WHERE name = '%s'" % user_input  # 字符串格式化
    cursor.execute(query)
# 或者
query = f"SELECT * FROM users WHERE name = '{user_input}'"  # f-string
cursor.execute(query)

它会报错为:

B608: Test for SQL injection


Bandit 的局限性(为什么说“有限度”)

Bandit 是静态分析,它不会实际执行代码,也不会追踪变量的数据流,以下情况它无法检测

  • 复杂拼接:变量经过多层函数传递后再组装。
  • ORM 使用不当:Django ORM 的 extra()raw() 方法。
  • 编码后的注入:经过 Base64、URL 编码或加密后的输入。
  • 动态表名、列名:如果表名或列名也是变量拼接,Bandit 可能忽略。
  • 参数化查询但忘记传参:例如只写了 cursor.execute(sql)sql 里仍有 %s 但没传参数(Bandit 可能误报或漏报)。

无法检测的例子:

def complex_query(user_input):
    # 经过函数处理
    safe_input = some_encoding(user_input)
    query = "SELECT * FROM users WHERE name = '" + safe_input + "'"
    # Bandit 可能不会报错,因为它无法静态分析 some_encoding 是否安全

实际使用建议

场景 Bandit 表现 建议
直接字符串拼接 能检测到,可封堵最低级错误
Django/Flask ORM 使用 需要配合 Django 的 SECURE_SQL_INJECTION 规则或手动审查
多层调用、编码混淆 无效 需要动态分析或人工代码审计
参数化查询 无告警(正确写法) 鼓励团队使用参数化查询,Bandit 不会报错

最佳实践:

  1. 先用 Bandit 做快速扫描(bandit -r your_project/),修复它报的所有 B608
  2. 然后 配合 SQLAlchemy / Django ORM 参数化查询 从根源避免拼接。
  3. 最后 使用 动态应用安全测试 (DAST) 工具(如 sqlmap、Burp Suite)对实际运行的应用进行渗透测试。

  • 能检测:直接字符串拼接、 格式化、f-string 构造 SQL 的明显案例。
  • 不能检测:复杂逻辑、ORM 滥用、经过编码或函数处理后的注入。
  • 🚀 :Bandit 是防 SQL 注入的第一道防线(静态代码扫描),但不能替代参数化查询和动态安全测试。

抱歉,评论功能暂时关闭!