Python脚本安全漏洞扫描:Bandit工具使用完全指南
目录导读
- Bandit是什么?为什么需要它?
- Bandit的安装与基础配置
- Bandit核心功能与扫描规则详解
- Bandit实战:从入门到深度扫描
- Bandit输出结果解读与误报处理
- Bandit集成CI/CD流水线的最佳实践
- 常见问题问答(FAQ)
Bandit是什么?为什么需要它?
1 定义与背景
Bandit是Python生态中最流行的静态安全分析工具之一,由OpenStack社区开发并维护,它通过解析Python代码的抽象语法树(AST),对常见安全漏洞模式进行模式匹配与启发式分析,无需执行代码即可发现潜在风险。

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)结合使用,构建纵深防御体系。