# https://github.com/PyCQA/bandit 项目说明书

生成时间：2026-06-19 17:22:19 UTC

## 目录

- [项目概览与快速开始](#page-1)
- [核心架构与扫描引擎](#page-2)
- [配置文件、排除规则与插件机制](#page-3)
- [命令行工具、Baseline 与输出格式](#page-4)

<a id='page-1'></a>

## 项目概览与快速开始

### 相关页面

相关主题：[核心架构与扫描引擎](#page-2), [命令行工具、Baseline 与输出格式](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [bandit/__init__.py](https://github.com/PyCQA/bandit/blob/main/bandit/__init__.py)
- [bandit/__main__.py](https://github.com/PyCQA/bandit/blob/main/bandit/__main__.py)
- [bandit/cli/main.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/main.py)
- [bandit/cli/baseline.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/baseline.py)
- [bandit/cli/config_generator.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/config_generator.py)
- [setup.cfg](https://github.com/PyCQA/bandit/blob/main/setup.cfg)
- [setup.py](https://github.com/PyCQA/bandit/blob/main/setup.py)
- [README.rst](https://github.com/PyCQA/bandit/blob/main/README.rst)
</details>

# 项目概览与快速开始

## 项目定位与核心能力

Bandit 是一款面向 Python 源码的静态安全分析工具（Static Analysis Security Testing, SAST），由 PyCQA 维护，最新发布版本为 1.9.4。项目以安全审计为目标，对每个待扫描文件调用 AST 节点级插件，输出按严重程度（severity）与置信度（confidence）分级的缺陷列表。在仓库组织层面，Bandit 把 CLI 拆分为若干独立入口，分别承担主扫描、基线对比与配置生成三类职责。资料来源：[bandit/cli/main.py:1-15]()

CLI 框架通过 `stevedore` 实现插件式扩展，使得新增检查项（B 系列 ID，例如 B101 `assert_used`）或新的报告格式（formatter）只需注册 entry-point 即可热加载。资料来源：[README.rst:1-30]()、`bandit/cli/main.py:80-110]()` 中的 `_init_extensions()` 调用。

## 命令行工具矩阵

项目提供三个可执行入口，每个入口职责清晰、独立运行：

| 工具 | 入口 | 主要用途 | 典型参数 |
|---|---|---|---|
| `bandit` | `bandit/cli/main.py:main` | 主扫描器，递归分析目标文件并产出报告 | `targets`、`-r`、`-t`、`-s`、`-f`、`-o`、`-b` |
| `bandit-baseline` | `bandit/cli/baseline.py:main` | 对比当前提交与父提交的差异（仅显示新增缺陷） | `targets`、`-f txt|html|json` |
| `bandit-config-generator` | `bandit/cli/config_generator.py:main` | 生成 YAML 配置文件（profile），用于覆盖插件默认值 | `-o`、`-t`、`-s`、`--show-defaults` |

资料来源：[bandit/cli/main.py:130-160]()`、`[bandit/cli/baseline.py:60-95]()`、`[bandit/cli/config_generator.py:60-90]()`。`setup.cfg` 中通过 `entry_points` 把上述入口挂到 `console_scripts`，从而允许用户 `pip install bandit` 后直接调用。资料来源：[setup.cfg:25-50]()

## 快速开始

### 基本扫描

最小化命令对单文件或目录执行一次性扫描，并在终端输出结果：

```bash
bandit -r ./examples/
```

`-r` 表示递归扫描子目录；`-f` 指定输出格式，可选 `txt`、`html`、`json`、`xml`、`screen`、`custom`；`-o` 把结果写入文件。资料来源：[bandit/cli/main.py:200-225]()

### 与基线对比

当存在已有 JSON 报告时，可通过 `-b` 仅报告新增缺陷，常用于 CI 流水线：

```bash
bandit -r ./src/ -b previous_report.json -f txt
```

也可使用 `bandit-baseline` 自动完成「检出父提交 → 扫描 → 切回当前提交 → 对比」流程。资料来源：[bandit/cli/baseline.py:100-140]()`、`[bandit/cli/baseline.py:160-195]()`。

### 生成配置文件

通过配置生成器可得到一份带注释的 YAML 模板，便于版本化管理：

```bash
bandit-config-generator -o bandit.yaml
```

若仅查看插件默认参数而不落盘，可使用 `--show-defaults`。资料来源：[bandit/cli/config_generator.py:95-130]()`、`[bandit/cli/config_generator.py:140-175]()`。

### 内联抑制

在源码行末追加 `# nosec` 注释即可让 Bandit 跳过该条告警；若需禁用此机制，使用 `--ignore-nosec`。资料来源：[bandit/cli/main.py:170-195]()

## 配置加载与排除路径

Bandit 支持通过项目级 `.bandit` 文件提供默认参数。加载顺序如下：CLI 参数 → INI 文件 → 内置默认值，最终通过 `_log_option_source()` 标注每个选项的来源。资料来源：[bandit/cli/main.py:240-275]()`、`[bandit/cli/main.py:280-310]()`。

常见字段包括 `exclude`（glob 模式）、`tests`/`skips`（插件 ID 列表）、`recursive`、`level`、`confidence`、`format` 等。需要注意的是，社区反馈显示 `-x ./mymodule/tests/` 与 `.bandit` 中的 `exclude` 在 1.6.x 系列中存在失效问题，需升级或显式使用 `-x` 兼容路径。该行为在后续版本中已修复。资料来源：[bandit/cli/main.py:315-340]()`，相关讨论见 Issue #488 与 #657。

排除路径既支持 `glob` 通配符（如 `./.tox,./tests`），也支持与 CLI 参数合并——CLI 提供的排除会被附加到配置文件的排除列表之后。资料来源：[bandit/cli/main.py:195-215]()`、`[bandit/core/constants.py]` 中的默认 `EXCLUDE` 常量。

## 下一步

- 阅读 **架构与插件机制**，理解插件如何基于 AST 节点工作。
- 阅读 **报告与基线流程**，掌握 JSON 报告字段含义与基线对比细节。
- 阅读 **配置文件参考**，查阅全部 INI / YAML 字段及其默认值。

## See Also

- 架构与插件机制
- 报告格式与输出定制
- 配置文件参考（INI / YAML）
- 持续集成（CI）集成指南

---

<a id='page-2'></a>

## 核心架构与扫描引擎

### 相关页面

相关主题：[项目概览与快速开始](#page-1), [配置文件、排除规则与插件机制](#page-3), [命令行工具、Baseline 与输出格式](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [bandit/cli/main.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/main.py)
- [bandit/cli/baseline.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/baseline.py)
- [bandit/cli/config_generator.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/config_generator.py)
- [bandit/core/manager.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/manager.py)
- [bandit/core/config.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/config.py)
- [bandit/core/constants.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/constants.py)
- [bandit/core/extension_loader.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/extension_loader.py)
- [bandit/core/utils.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/utils.py)
</details>

# 核心架构与扫描引擎

## 架构概览

Bandit 由三层松耦合模块组成：CLI 层（`bandit/cli/`）、核心调度层（`bandit/core/`）以及由 `extension_loader` 托管的插件层。CLI 命令在解析完参数后，会构造 `BanditManager` 实例（`b_manager`），由后者负责遍历目标、调用 AST 测试插件、收集 `Issue`、并交给 `Formatter` 输出。资料来源：[bandit/cli/main.py:1-9]()。

```mermaid
flowchart TD
    A[CLI 入口<br/>main.py] --> B[argparse 解析参数]
    B --> C[加载 .bandit INI]
    C --> D[初始化扩展<br/>extension_loader]
    D --> E[_log_option_source 仲裁优先级]
    E --> F[BanditManager]
    F --> G[遍历目标文件]
    G --> H[NodeVisitor 访问 AST]
    H --> I[Tester 调用测试插件]
    I --> J[Issue 收集]
    J --> K[Formatter 输出报告]
    L[bandit-baseline] --> A
    M[bandit-config-generator] --> D
```

## CLI 入口与初始化流程

`main()` 在最早阶段建立日志记录，并根据 `-d/--debug` 是否出现切换日志级别（`logging.DEBUG`/`logging.INFO`），随后调用 `_init_extensions()` 加载所有检查器、格式化器和黑名单，填充 `extension_mgr`。资料来源：[bandit/cli/main.py:407-413]()、[bandit/cli/main.py:1-9]()。

`argparse.ArgumentParser` 注册的关键参数包括：`targets`、`-r/--recursive`、`-t/--tests`、`-s/--skips`、`--profile`、严重级别（`-l/--severity`，`-ll`，`-lll`）、置信度（`-i/--confidence`，`-ii`，`-iii`）、`-f/--format`、`-o/--output`、`--msg-template`、`-x/--exclude`、`-b/--baseline`、`--ini`、`--ignore-nosec`、`--exit-zero` 等。资料来源：[bandit/cli/main.py:430-540]()。

默认输出格式依据环境动态决定：当 `sys.stdout.isatty()` 为真、`NO_COLOR` 未设置、`TERM` 不等于 `dumb` 时使用 `screen`，否则使用 `txt`。资料来源：[bandit/cli/main.py:496-505]()。

## 配置加载与优先级仲裁

Bandit 支持通过 `.bandit` INI 文件提供默认参数。`_get_options_from_ini()` 在未显式传入 `--ini` 时会递归遍历 `target` 寻找 `.bandit` 文件；若发现多个则发出警告。资料来源：[bandit/cli/main.py:60-83]()。

CLI 解析完成后，`_log_option_source()` 按"命令行 → ini → 默认值"的优先级解析最终值，并通过日志标注每项设置的来源。例如 `args.severity = _log_option_source(default, cli_val, ini_val, "severity level")`。资料来源：[bandit/cli/main.py:150-180]()。

`.bandit` 配置文件支持的常用键：

| 配置键 | 作用 | 默认 |
| --- | --- | --- |
| `exclude` | 逗号分隔的路径 glob（追加到内置排除） | `constants.EXCLUDE` |
| `tests` | 启用的测试 ID 列表 | 全选 |
| `skips` | 跳过的测试 ID 列表 | 空 |
| `level` | 最低严重级别 | `1` |
| `confidence` | 最低置信度 | `1` |
| `format` | 输出格式 | `screen`/`txt` |
| `msg-template` | 自定义报告模板 | 无 |
| `output` | 输出文件 | `stdout` |
| `ignore-nosec` | 忽略 `# nosec` 注释 | `False` |

资料来源：[bandit/cli/main.py:150-220]()。

社区反馈 #488 与 #657 都指向 1.6.x 时代 `.bandit` 中 `exclude` 不被尊重的问题：当用户在命令行显式提供 `-x` 时，旧实现会忽略 ini 段的同名键。该缺陷正是 `_log_option_source` 优先级逻辑需要正确处理的场景。资料来源：[bandit/cli/main.py:90-110]()。

## 测试插件与配置文件生成

`bandit-config-generator` 通过遍历 `extension_loader.MANAGER.plugins`，对每个声明了 `_takes_config` 的插件调用其模块的 `gen_config()` 函数收集默认值，最终以 YAML 输出。资料来源：[bandit/cli/config_generator.py:124-134]()。

输出模板（`template`）由三段组成：可用测试 ID 列表（注释形式 `# ID : 名称`）、`tests/skips` 列表占位符、以及插件设置块。`get_config_settings()` 仅当插件函数带 `_takes_config` 且模块中存在 `gen_config` 时才会收集，避免无效配置。资料来源：[bandit/cli/config_generator.py:38-58]()。

## 基准扫描 (Bandit Baseline)

`bandit-baseline` 通过 `GitPython`（`git`）切换到父提交并运行 Bandit 生成 JSON 报告，再切换回当前提交并以该报告作为 `-b` 参数重新运行，从而只显示新增问题。资料来源：[bandit/cli/baseline.py:1-8]()、[bandit/cli/baseline.py:185-210]()。

运行前置条件校验：必须位于 git 项目根目录、当前工作区不能 dirty、临时文件 `_bandit_baseline_run.json_` 不能已存在、不可与 `-o` 同时使用、输出格式受 `valid_baseline_formats = ["txt", "html", "json"]` 限制。资料来源：[bandit/cli/baseline.py:107-130]()、[bandit/cli/baseline.py:152-170]()。

`baseline_setup()` 上下文管理器负责建立临时目录并在退出时清理、还原仓库 HEAD，确保 baseline 子进程失败不会污染工作区。资料来源：[bandit/cli/baseline.py:230-240]()。

## 已知问题与社区反馈

- **路径排除优先级**（#488、#657）：1.6.x 中命令行显式提供 `-x` 时会忽略 `.bandit` 中 `exclude`，现已通过 `_log_option_source` 修复。资料来源：[bandit/cli/main.py:90-180]()。
- **配置格式扩展**（#212、#550）：社区请求支持 `setup.cfg` 与 `pyproject.toml`（PEP 518），目前仍以 `.bandit` INI 为主流。资料来源：[bandit/cli/main.py:60-83]()。
- **精细化跳过**（#346）：希望按文件名 glob 跳过 `B101 assert_used` 等规则，目前只能在 `.bandit` 中全局 `skips`。资料来源：[bandit/cli/config_generator.py:38-58]()。

## See Also

- Bandit 官方仓库：[PyCQA/bandit](https://github.com/PyCQA/bandit)
- 测试插件列表与 ID：可通过 `bandit-config-generator --show-defaults` 查看（资料来源：[bandit/cli/config_generator.py:38-58]()）
- baseline 工具：`bandit-baseline`（资料来源：[bandit/cli/baseline.py:1-8]()）

---

<a id='page-3'></a>

## 配置文件、排除规则与插件机制

### 相关页面

相关主题：[核心架构与扫描引擎](#page-2), [命令行工具、Baseline 与输出格式](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [bandit/cli/main.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/main.py)
- [bandit/cli/baseline.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/baseline.py)
- [bandit/cli/config_generator.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/config_generator.py)
- [bandit/core/config.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/config.py)
- [bandit/core/extension_loader.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/extension_loader.py)
- [bandit/core/test_properties.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/test_properties.py)
- [bandit/core/manager.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/manager.py)
- [bandit/core/constants.py](https://github.com/PyCQA/bandit/blob/main/bandit/core/constants.py)
</details>

# 配置文件、排除规则与插件机制

## 概述

Bandit 通过三层机制实现灵活的项目级安全扫描配置：**YAML/INI 配置文件** 用于声明插件开关与插件级参数，**路径/插件排除规则** 用于在文件级别和检查器级别裁剪扫描范围，**插件/扩展加载器** 则负责发现并注册所有可用的检查器与格式化器。本页基于仓库内 CLI 入口与核心模块源码,说明这三层机制如何协同工作,以及社区反馈中常见的兼容性与功能缺口。

## 配置文件与发现流程

Bandit 支持两类配置文件:基于 YAML 的 `bandit.yaml`(由 `BASE_CONFIG = "bandit.yaml"` 常量定义)用于插件级参数,以及基于 INI 语法的 `.bandit` 文件用于整体运行参数。CLI 通过 `--ini` 参数显式指定 INI 路径,或在未提供时通过 `os.walk` 在所有 `targets` 目录中递归查找名为 `.bandit` 的文件 资料来源：[bandit/cli/main.py:73-95]()。

INI 文件被解析后,`_log_option_source()` 会按"命令行 > INI > 默认值"的优先级决定每个选项的最终值,并在日志中标注来源(`Using command line arg for ...` 或 `Using ini file for ...`) 资料来源：[bandit/cli/main.py:165-210]()。目前 INI 支持的键包括 `tests`、`skips`、`targets`、`recursive`、`aggregate`、`number`、`profile`、`level`、`confidence`、`format`、`msg-template`、`output`、`verbose`、`debug`、`quiet`、`ignore-nosec` 等 资料来源：[bandit/cli/main.py:210-250]()。

```mermaid
flowchart TD
    A[bandit CLI 启动] --> B{提供 --ini?}
    B -- 是 --> C[读取指定 .bandit]
    B -- 否 --> D[在 targets 中 os.walk 查找 .bandit]
    C --> E[解析 INI 为字典]
    D --> E
    E --> F[加载 bandit.yaml<br/>BASE_CONFIG]
    F --> G[_log_option_source 合并]
    G --> H[命令行参数覆盖]
    H --> I[BanditManager.discover_files]
    I --> J[b_mgr.run_tests]
```

值得注意的是,社区曾多次请求支持 `setup.cfg`(issue #212)与 `pyproject.toml`(issue #550)作为配置文件来源,但当前代码仅原生支持 `.bandit` 与 `bandit.yaml`。

## 路径与插件排除规则

### 路径排除

`-x / --exclude` 参数接受逗号分隔的 glob 模式列表,默认值为 `constants.EXCLUDE` 列表 资料来源：[bandit/cli/main.py:148-156]()。CLI 会同时合并命令行提供的 `excluded_paths` 与 INI 中的 `excluded_paths`,最终交给 `BanditManager.discover_files()` 统一处理 资料来源：[bandit/core/manager.py]()。

社区曾报告在 1.6.0 之后 `-x` 参数不再生效(issue #488,25 条评论),以及 1.6.3 中 `.bandit` 文件里的 `exclude:` 键未被尊重(issue #657,16 条评论)。这反映出路径排除在版本演进中曾出现回归,使用时建议通过 `-v/--verbose` 验证被排除的文件是否如预期,并优先在命令行显式传 `-x` 而非依赖 INI 间接配置。

### 插件排除

CLI 提供 `-t/--tests` 与 `-s/--skips` 配合 INI 中的 `tests` / `skips` 键,用于按检查器 ID(如 `B101`、`B406`)启用或停用特定插件 资料来源：[bandit/cli/main.py:210-225]()。在配置生成器中,二者会同时序列化为 YAML 模板的 `tests` 与 `skips` 列表 资料来源：[bandit/cli/config_generator.py:55-70]()。

## 插件机制

### 扩展加载器

`bandit.core.extension_loader` 通过 `MANAGER` 单例对外暴露已注册的检查器与黑名单。CLI 启动时调用 `_init_extensions()` 构建扩展管理器,随后通过 `extension_mgr.plugins_by_id` 与 `extension_mgr.blacklist` 收集插件信息并打印到 `--help` 输出中 资料来源：[bandit/cli/main.py:127-140]()。

插件通过两个特殊属性声明其能力:

| 属性 | 含义 | 用途 |
| --- | --- | --- |
| `_takes_config` | 标记插件接受外部配置 | `gen_config` 收集其默认参数 |
| `_accepts_baseline` | 标记格式化器能消费基线 | baseline 子命令筛选输出格式 |

资料来源：[bandit/cli/config_generator.py:108-130]() 与 [bandit/cli/main.py:88-95]()。

### 配置生成器

`bandit_conf_generator` 工具(`bandit/cli/config_generator.py`)通过 `--show-defaults` 打印所有可配置插件的默认参数,或通过 `-o/--out` 写出完整 YAML 模板 资料来源：[bandit/cli/config_generator.py:90-145]()。生成器会调用每个插件模块的 `gen_config(function._takes_config)` 函数,后者必须返回与 `_takes_config` 字段同构的字典 资料来源：[bandit/cli/config_generator.py:108-130]()。

### Baseline 工具与格式化器

`bandit-baseline` 子命令(由 `bandit/cli/baseline.py` 实现)在调用前会过滤 `extension_mgr.formatters`,仅保留带有 `_accepts_baseline` 标记的格式化器 资料来源：[bandit/cli/main.py:88-95]()。Baseline 通过 `git` 检出父提交、运行 Bandit 写入临时 JSON(`_bandit_baseline_run.json_`),再在当前提交上以 `-b bandit_tmpfile` 比对差异 资料来源：[bandit/cli/baseline.py:75-130]()。

## 常见问题与最佳实践

1. **路径排除失效**:遇到类似 issue #488/#657 的场景时,使用 `bandit -r . -x ./tests/ -v` 显式验证排除集合。
2. **per-file 检查器跳过**:issue #346 提议在配置中按文件名模式跳过 `B101` 等检查器,当前代码未提供开箱即用支持,可通过在文件内添加 `# nosec` 注释(除非使用 `--ignore-nosec`)或维护多份 INI 文件间接实现。
3. **配置文件格式**:若项目已统一使用 `setup.cfg` 或 `pyproject.toml`,需自行预处理或关注 issue #212/#550 的进展。
4. **插件参数调整**:修改 `bandit.yaml` 后可用 `bandit-config-generator --show-defaults` 校验默认值,避免误改导致误报。

## 参见

- [Bandit 官方文档:配置](https://bandit.readthedocs.io/en/latest/config.html)
- [PEP 518 – pyproject.toml 规范](https://www.python.org/dev/peps/pep-0518/)

---

<a id='page-4'></a>

## 命令行工具、Baseline 与输出格式

### 相关页面

相关主题：[项目概览与快速开始](#page-1), [配置文件、排除规则与插件机制](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [bandit/cli/main.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/main.py)
- [bandit/cli/baseline.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/baseline.py)
- [bandit/cli/config_generator.py](https://github.com/PyCQA/bandit/blob/main/bandit/cli/config_generator.py)
- [bandit/formatters/__init__.py](https://github.com/PyCQA/bandit/blob/main/bandit/formatters/__init__.py)
- [bandit/formatters/json.py](https://github.com/PyCQA/bandit/blob/main/bandit/formatters/json.py)
- [bandit/formatters/html.py](https://github.com/PyCQA/bandit/blob/main/bandit/formatters/html.py)
</details>

# 命令行工具、Baseline 与输出格式

Bandit 项目在仓库根目录下通过三个独立的 CLI 入口协作完成扫描任务：主扫描器 `bandit`、变更对比工具 `bandit-baseline`，以及配置生成器 `bandit-config-generator`。三者均以 `stevedore` 插件管理器作为能力注册点，统一面向 [`extension_mgr`](https://github.com/PyCQA/bandit/blob/main/bandit/cli/main.py) 中的 formatter、check 与 blacklist 插件。本页聚焦其参数解析、配置加载顺序、Baseline 工作流与可插拔输出格式。

## 一、主命令行工具（bandit）

主入口在 [`bandit/cli/main.py`](https://github.com/PyCQA/bandit/blob/main/bandit/cli/main.py) 中，由 `main()` 函数负责参数解析、配置装载和调用 `BanditManager`。

### 参数分组与默认值

解析器使用 `argparse.MutuallyExclusiveGroup` 把日志控制拆分为 `(-v|--verbose)` 与 `(-q|--quiet|--silent)`，严重度与置信度同样以互斥组承载：`-l/-ll/-lll` 表示 LOW/MEDIUM/HIGH 严重度计数，`-i/-ii/-iii` 表示置信度计数；并提供语义化的 `--confidence-level {all,low,medium,high}` 备选。资料来源：[main.py:235-258]()

输出格式 `-f/--format` 的默认值并非静态值：`main()` 在解析前会根据 `sys.stdout.isatty()`、`os.getenv("NO_COLOR")` 与 `os.getenv("TERM")` 动态选择 `screen` 或 `txt`。资料来源：[main.py:260-275]() 这与社区对“颜色/无 TTY 环境”兼容性的关切直接相关。

### `.bandit` 配置文件与选项优先级

`_get_options_from_ini()` 在未显式传入 `--ini` 时，会通过 `os.walk` + `fnmatch.filter(filenames, ".bandit")` 扫描 target 目录以发现项目级 `.bandit` 文件。每个 INI 选项随后经 `_log_option_source()` 与命令行解析结果比较，并以 `cli value`、`ini value`、`default value` 的顺序决定最终生效值。资料来源：[main.py:90-180]()

这一行为是社区长期关注的痛点。Issue [#488](https://github.com/PyCQA/bandit/issues/488)（25 条评论）报告 Bandit 1.6.0 不再尊重 `-x` 排除的目录；Issue [#657](https://github.com/PyCQA/bandit/issues/657)（16 条评论）则进一步指出 `.bandit` 中的 `exclude` 在 1.6.3 中被命令行默认值覆盖——这两类问题都源于 `_log_option_source()` 链路上命令行/INI/默认值之间的合并顺序。社区在 Issue [#212](https://github.com/PyCQA/bandit/issues/212) 与 [#550](https://github.com/PyCQA/bandit/issues/550) 中也分别请求 `setup.cfg` 与 `pyproject.toml` 支持，目前主流仍为 `.bandit` + `bandit.yaml`（见 `BASE_CONFIG = "bandit.yaml"`）。

### 扫描与结果输出

`main()` 在装载配置后调用 `b_mgr.discover_files(targets, recursive, excluded_paths)`、`b_mgr.run_tests()` 与 `b_mgr.output_results(...)`。退出码规则为：若 `b_mgr.results_count(sev_filter, conf_filter) > 0` 且未传 `--exit-zero`，则 `sys.exit(1)`，否则 `sys.exit(0)`。资料来源：[main.py:320-345]()

## 二、Baseline 工具（bandit-baseline）

入口在 [`bandit/cli/baseline.py`](https://github.com/PyCQA/bandit/blob/main/bandit/cli/baseline.py)，定位是“对比当前提交与父提交的安全发现增量”。运行时使用 `GitPython` 库，因此必须以 `[baseline]` extras 安装才能执行；否则 `initialize()` 会输出 `Git not available, reinstall with baseline extra` 并以退出码 2 失败。资料来源：[baseline.py:80-95]()

### 校验前置条件

`initialize()` 中执行的硬性校验包括：仓库必须存在且 `repo.is_dirty()` 为 False；输出文件名 `bandit_baseline_result.{fmt}` 不得已存在；临时文件 `_bandit_baseline_run.json_` 必须先清理；**禁止**传入 `-o`（会与 baseline 自身的输出逻辑冲突）。资料来源：[baseline.py:95-130]() 任何一条校验失败都会让 `main()` 立即 `sys.exit(2)`。

### 两步扫描工作流

`main()` 在确定 `current_commit` 与 `parent_commit` 后，进入如下两步流程并最终使用 `baseline_setup()` 上下文清理临时目录与重置 HEAD：

```mermaid
flowchart TD
    A[reset HEAD -> parent_commit] --> B[bandit -f json -o bandit_tmpfile]
    B --> C[reset HEAD -> current_commit]
    C --> D[bandit -b bandit_tmpfile -f/-o]
    D --> E{exit_code ∈ {0,1}?}
    E -- 否 --> F[LOG.error 并退出]
    E -- 是 --> G[打印/写出报告]
```

资料来源：[baseline.py:140-200]() `valid_baseline_formats = ["txt", "html", "json"]` 决定可选输出格式；终端输出模式会直接把对比结果打印到 stdout，否则写入 `bandit_baseline_result.<fmt>`。

## 三、配置生成器（bandit-config-generator）

入口在 [`bandit/cli/config_generator.py`](https://github.com/PyCQA/bandit/blob/main/bandit/cli/config_generator.py)。`get_config_settings()` 遍历 `extension_loader.MANAGER.plugins`，对所有带有 `_takes_config` 属性的插件 `importlib.import_module()` 其模块并调用 `gen_config()`，最终通过 `yaml.safe_dump(config, default_flow_style=False)` 写出 YAML。资料来源：[config_generator.py:55-72]()

`main()` 支持 `--show-defaults`（打印默认 YAML 而不写文件）、`-o/--out`（写文件）、`-t/--tests`、`-s/--skip`。所有 `-t`/`-s` 中的 ID 都会经 `MANAGER.check_id()` 校验，避免把未注册的测试写到配置中。资料来源：[config_generator.py:105-135]()

## 四、输出格式与报告流程

`main.py` 在收集 formatter 时使用 `extension_mgr.formatter_names` 动态生成 `-f` 的 `choices`；同时通过 `hasattr(x.plugin, "_accepts_baseline")` 过滤出兼容 baseline 的 formatter 子集。资料来源：[main.py:60-72](), [main.py:215-235]()

最终由 `BanditManager.output_results()` 配合 `--msg-template`（仅在 `format=custom` 时合法）渲染。`--msg-template` 支持的标签包括 `{abspath},{relpath},{line},{col},{test_id},{severity},{msg},{confidence},{range}`，并兼容 Python `str.format` 的字段宽度语法。资料来源：[main.py:155-200]()

| 格式化器 | 适用场景 | 关键能力 |
| --- | --- | --- |
| `txt` / `screen` | 本地终端 | 默认 TTY 友好，支持 `--msg-template` 时降级为 `txt` |
| `json` | 机器消费 / baseline | 提供 `_accepts_baseline`，被 `bandit-baseline` 用作基线 |
| `html` | 报告归档 | 兼容 baseline（见 `valid_baseline_formats`） |
| `custom` | CI 集成 | 必须配合 `--msg-template`，否则 argparse 拒绝 |

资料来源：[main.py:215-235](), [baseline.py:30-50](), [config_generator.py:1-40]()

## See Also

- [Bandit 主扫描与插件系统](bandit-core.md)
- [Bandit 测试插件列表（B101–B614）](bandit-plugins.md)
- [PEP 518 兼容的配置方案讨论（Issue #550）](https://github.com/PyCQA/bandit/issues/550)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：PyCQA/bandit

摘要：发现 8 个潜在踩坑项，其中 1 个为 high/blocking；最高优先级：安全/权限坑 - 来源证据：False negative: narrow argument-shape checks in B508/B509。

## 1. 安全/权限坑 · 来源证据：False negative: narrow argument-shape checks in B508/B509

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：False negative: narrow argument-shape checks in B508/B509
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 证据：community_evidence:github | https://github.com/PyCQA/bandit/issues/1397 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 2. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | https://github.com/PyCQA/bandit | README/documentation is current enough for a first validation pass.

## 3. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | https://github.com/PyCQA/bandit | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | https://github.com/PyCQA/bandit | no_demo; severity=medium

## 5. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | https://github.com/PyCQA/bandit | no_demo; severity=medium

## 6. 安全/权限坑 · 来源证据：Feature request: Adding Canary Credentials to detect supply chain compromise

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Feature request: Adding Canary Credentials to detect supply chain compromise
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 证据：community_evidence:github | https://github.com/PyCQA/bandit/issues/1432 | 来源类型 github_issue 暴露的待验证使用条件。

## 7. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | https://github.com/PyCQA/bandit | issue_or_pr_quality=unknown

## 8. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | https://github.com/PyCQA/bandit | release_recency=unknown

<!-- canonical_name: PyCQA/bandit; human_manual_source: deepwiki_human_wiki -->
