Python脚本安全漏洞扫描Bandit怎么用

wen 实用脚本 3

Python脚本安全漏洞扫描:Bandit工具使用完全指南

目录导读

  1. Bandit是什么?为什么需要它?
  2. Bandit的安装与基础配置
  3. Bandit核心功能与扫描规则详解
  4. Bandit实战:从入门到深度扫描
  5. Bandit输出结果解读与误报处理
  6. Bandit集成CI/CD流水线的最佳实践
  7. 常见问题问答(FAQ)

Bandit是什么?为什么需要它?

1 定义与背景

Bandit是Python生态中最流行的静态安全分析工具之一,由OpenStack社区开发并维护,它通过解析Python代码的抽象语法树(AST),对常见安全漏洞模式进行模式匹配与启发式分析,无需执行代码即可发现潜在风险。

Python脚本安全漏洞扫描Bandit怎么用

2 核心价值

  • 左移安全:在编码阶段而非部署后发现问题,修复成本降低60%以上
  • 覆盖OWASP Top 10:检测SQL注入、命令注入、硬编码密钥、不安全的反序列化等
  • 零运行时依赖:纯静态扫描,不执行用户代码,适合CI/CD环境
  • 自定义规则:支持使用Python编写自定义检测插件

3 典型应用场景

  • 开源项目安全审计(如PyPI包、GitHub仓库)
  • 企业内Python代码仓库的安全门禁
  • 开发者本地预提交检查
  • 安全团队批量巡检遗留代码

Bandit的安装与基础配置

1 环境要求

  • Python 3.8+
  • pip包管理器

2 安装命令(三种方式)

pip直接安装(推荐)
pip install bandit
# 如需指定版本:pip install bandit==1.7.5
通过pipx隔离安装
pipx install bandit
# 避免全局环境冲突
源码安装(开发场景)
git clone https://github.com/PyCQA/bandit.git
cd bandit
pip install -e .

3 验证安装

bandit --version
# 正常输出示例:bandit 1.7.5 (python 3.10.12)

4 基础配置(三要素)

配置文件(推荐使用pyproject.toml.bandit):

[bandit]
# 排除目录
exclude_dirs = ["tests", "venv", ".git"]
# 结果输出格式
output_format = "json"
# 仅报告高严重性问题
severity = "HIGH"
# 自定义测试ID白名单
skips = ["B101", "B110"]

命令行参数速查表: | 参数 | 作用 | 示例 | |------|------|------| | -r | 递归扫描目录 | bandit -r ./src | | -f | 输出格式 | -f json -o result.json | | -s | 跳过指定测试 | -s B101,B110 | | -t | 仅运行指定测试 | -t B301 | | --severity-level | 按严重度过滤 | --severity-level high |


Bandit核心功能与扫描规则详解

1 内置扫描插件分类(共180+规则)

类别 示例ID
注入攻击 B101、B102 assert语句(调试时禁用)、exec/eval动态执行
密码/密钥泄露 B105、B106 硬编码密码、AWS密钥、JWT token
不安全调用 B301、B302 pickle/xml.etree反序列化
文件权限 B401 不安全的临时文件创建
网络通信 B501、B502 弱的TLS/SSL版本
加密算法 B303 使用MD5/SHA1等弱哈希

2 严重度与置信度分级机制

  • 严重度(Severity)HIGH / MEDIUM / LOW — 漏洞的潜在危害等级
  • 置信度(Confidence)HIGH / MEDIUM / LOW — 规则匹配的确定性

3 自定义规则编写(进阶功能)

# 自定义插件示例:检测不安全的yaml.load
class UnsafeYamlLoad(BanditTest):
    def check_file(self, filename: str) -> BanditResult:
        # 实现检测逻辑:查找yaml.load()
        pass

放置于bandit/plugins/目录或通过--plugin-path加载。


Bandit实战:从入门到深度扫描

1 场景一:快速扫描单个文件

bandit app.py -f html -o report.html

输出说明:生成可视化HTML报告,标注代码行号与修复建议。

2 场景二:完整项目扫描(递归+排除)

bandit -r project/ \
  --exclude '*.test.py,*tests/*' \
  --exclude 'vendor/*' \
  --severity-level medium \
  --confidence-level medium

3 场景三:只检测特定漏洞类型

# 仅检测SQL注入(B201)与命令注入(B602)
bandit -r src/ -t B201,B602

4 场景四:生成机器可读的JSON报告(CI/CD常用)

bandit -r src/ -f json -o bandit_result.json

JSON结构示例:

{
  "results": [
    {
      "code": "print(exec(f\"{user_input}\"))",
      "filename": "src/eval_risk.py",
      "line_number": 15,
      "issue_severity": "HIGH",
      "issue_confidence": "HIGH",
      "test_id": "B102",
      "test_name": "exec_used"
    }
  ]
}

Bandit输出结果解读与误报处理

1 典型输出示例及含义

>> Issue: [B105:hardcoded_password_string] Possible hardcoded password: 'password'
   Severity: Medium   Confidence: High
   Location: ./config.py:10

关键字段解析

  • B105:规则ID(可查阅Bandit文档
  • hardcoded_password_string:检测模式名称
  • Possible hardcoded password:问题描述

2 误报处理策略

行内注释忽略
# 信任操作:使用 `nosec` 注释
password = "default_pwd"  # nosec
全局跳过特定规则
bandit -r src/ -s B105,B101
白名单配置

.bandit配置文件中添加:

[bandit]
skips = B105  # 跳过所有硬编码密码检测

3 误报分析案例

检测import base64报B105?这通常是误报——Bandit将base64编码误认为密钥存储,处理方式:使用# nosec或调整规则优先级。


Bandit集成CI/CD流水线的最佳实践

1 GitHub Actions集成示例

name: Python Security Scan
on: [push, pull_request]
jobs:
  bandit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Bandit
        run: pip install bandit
      - name: Run Bandit
        run: |
          bandit -r src/ -f json -o bandit-report.json
          # 若有高严重度问题则阻止PR合并
          if grep -q '"issue_severity": "HIGH"' bandit-report.json; then
            echo "High severity issues found!"
            exit 1
          fi

2 Jenkins集成

stage('Security Scan') {
    steps {
        sh 'bandit -r src/ -f xml -o bandit.xml || true'
        publishHTML([allowMissing: false, 
                     reportDir: '.', 
                     reportFiles: 'bandit.xml'])
    }
}

3 GitLab CI集成

bandit:
  stage: test
  script:
    - pip install bandit
    - bandit -r src/ -f json -o bandit.json
  artifacts:
    paths:
      - bandit.json
  allow_failure: true  # 允许扫描失败但不阻断流水线

常见问题问答(FAQ)

Q1:Bandit和IDE插件(如PyCharm)的Security Inspection有何区别? A:Bandit是独立工具,规则更全面(180+ vs 50+),且支持自定义规则与CI/CD集成,IDE插件适合本地快速检查,但无法作为自动化门禁。

Q2:如何让Bandit只报告未修复的漏洞而忽略历史问题? A:可以结合git diff实现增量扫描:

git diff --name-only HEAD~1 | xargs bandit

Q3:扫描非常慢,如何优化速度? A:1) 使用--skip跳过不必要规则 2) 通过--exclude排除node_modules/venv等 3) 使用-n参数限制并发(默认自动)

Q4:发现Bandit误报某些函数调用,是否应关闭规则? A:不推荐全局关闭,建议使用# nosec行内忽略并添加注释说明原因,若误报率超过30%,可考虑配置白名单。

Q5:能否让Bandit检测自定义库中的安全漏洞? A:可以,通过--plugin-path加载自定义插件,或使用--tags筛选检测特定模式的插件组合。

Q6:Bandit支持Python 2吗? A:Bandit 1.7.x版本已放弃Python 2.7支持,对于遗留Python 2项目,建议使用bandit 1.6.x或集成pyflakes等工具。

Q7:扫描结果中的“Test ID”代表什么?如何获取完整规则列表? A:Test ID是Bandit内置规则的唯一标识,完整列表可通过bandit -h查看--rules参数,或访问官方文档的Rules Reference


延伸阅读:

最后提醒:安全扫描不是银弹,建议将Bandit与动态测试工具(如Snyk、BlackDuck)结合使用,构建纵深防御体系。

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