ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Bandit 配置实战:INI / YAML / TOML 配置文件、测试选择与 nosec 排除机制详解

Bandit 配置实战:INI / YAML / TOML 配置文件、测试选择与 nosec 排除机制详解 SAST应用安全【免费下载链接】banditBandit is a tool designed to find common security issues in Python code.项目地址https://gitcode.com/gh_mirrors/ba/bandit点击查看免费下载本文基于 Bandit 官方文档中的 Configuration 章节系统讲解 Bandit 的完整配置体系如何通过.banditINI 文件、YAML 或 TOML 配置文件控制扫描目标、路径排除与测试选择如何用# nosec注释精确抑制特定告警以及bandit-config-generator工具的用法。读完后你将能够为项目落地一套可复现、可维护的 Bandit 扫描配置并理解每个配置项在源码中的解析路径。三种配置载体INI、YAML 与 TOMLBandit 支持三种配置文件形式它们的定位各不相同载体文件名指定方式适用场景INI.bandit自动发现需-r或--ini显式指定项目级命令行参数预设YAML任意如bandit.yaml必须通过-c显式指定测试选择 插件参数覆盖TOML任意如pyproject.toml的[tool.bandit]段必须通过-c显式指定已使用 pyproject.toml 的项目三者并非互斥INI 文件提供的是应传给命令行的一组参数而 YAML/TOML 文件承载的是扫描行为配置测试选择与插件级覆盖。官方文档config.rst说明的 INI 文件支持以下命令行参数targets逗号分隔的待扫描目录/文件列表exclude逗号分隔的排除路径仅 INI 支持对应命令行的-xexclude_dirs逗号分隔的排除路径目录或文件仅 YAML 与 TOML 支持skips逗号分隔的跳过测试列表tests逗号分隔的纳入测试列表。在项目中放置.banditINI 文件将如下内容保存为项目根目录下的.bandit文件命令行参数必须写在[bandit]段中# FILE: .bandit [bandit] exclude tests,path/to/file tests B201,B301 skips B101,B601两个关键行为需要注意只有在使用-r递归扫描时Bandit 才会自动查找.bandit文件。如果不使用-r或者 INI 文件不叫.bandit需要通过--ini显式指定文件路径例如把配置复用现有文件bandit --ini tox.ini命令行参数的优先级高于 INI 文件中的同名配置。从源码可以印证这两点。cli/main.py 中的_get_options_from_ini会先在target列表里逐目录os.walk搜索名为.bandit的文件若发现多个.bandit文件会直接报错退出提示scan separately or choose one with --ini只发现一个则记录日志并加载。INI 解析由 core/utils.py 中的parse_ini_file完成它读取configparser的[bandit]段若文件无法解析或缺少该段则返回None并给出警告。而命令行优先的合并逻辑集中在 cli/main.py 的_log_option_source当命令行未显式传值时回退到 INI 值并打印Using command line arg for .../Using ini file for ...日志说明取值来源。整个合并过程覆盖了configfile、exclude、skips、tests、targets、recursive、aggregate、number、profile、level、confidence、format、msg-template、output、verbose、debug、quiet、ignore-nosec、baseline等选项见 cli/main.py因此.bandit文件实际上可以预设几乎完整的命令行行为。使用 YAML 或 TOML 文件并通过-c指定YAML 文件可以放在任意位置运行时用-c指定# FILE: bandit.yaml exclude_dirs: [tests, path/to/file] tests: [B201, B301] skips: [B101, B601]TOML 形式通常写在pyproject.toml中# FILE: pyproject.toml [tool.bandit] exclude_dirs [tests, path/to/file] tests [B201, B301] skips [B101, B601]对应的运行命令bandit -c bandit.yaml -r .bandit -c pyproject.toml -r .-c全称--configfile在 CLI 中的定义见 cli/main.py帮助文本为optional config file to use for selecting plugins and overriding defaults。加载入口是b_config.BanditConfig(config_fileargs.config_file)cli/main.py解析失败会抛出ConfigError并以退出码 2 终止。扫描行为配置YAML 配置文件详解官方文档指出Bandit 既可以作为本地开发者工具也可以嵌入 CI/CD 流水线因此支持通过 YAML 配置文件进行定制。该文件完全是可选的很多场景下并不需要需要通过-c在命令行指定。配置文件的职责有二选择要运行tests或跳过skips的具体测试插件覆盖这些测试插件的默认参数。一个更完整的配置示例官方文档原文示例如下除了测试选择还覆盖了any_other_function_with_shell_equals_true插件的函数分组### profile may optionally select or skip tests exclude_dirs: [tests, path/to/file] # (optional) list included tests here: tests: [B201, B301] # (optional) list skipped tests here: skips: [B101, B601] ### override settings - used to set settings for plugins to non-default values any_other_function_with_shell_equals_true: no_shell: [os.execl, os.execle, os.execlp, os.execlpe, os.execv, os.execve, os.execvp, os.execvpe, os.spawnl, os.spawnle, os.spawnlp, os.spawnlpe, os.spawnv, os.spawnve, os.spawnvp, os.spawnvpe, os.startfile] shell: [os.system, os.popen, os.popen2, os.popen3, os.popen4, popen2.popen2, popen2.popen3, popen2.popen4, popen2.Popen3, popen2.Popen4, commands.getoutput, commands.getstatusoutput] subprocess: [subprocess.Popen, subprocess.call, subprocess.check_call, subprocess.check_output]运行方式同样是bandit -c bandit.yaml -r .。等价的 TOMLpyproject.toml写法注意插件覆盖段落在 TOML 中要写成独立的子表[tool.bandit.插件名][tool.bandit] exclude_dirs [tests, path/to/file] tests [B201, B301] skips [B101, B601] [tool.bandit.any_other_function_with_shell_equals_true] no_shell [ os.execl, os.execle, os.execlp, os.execlpe, os.execv, os.execve, os.execvp, os.execvpe, os.spawnl, os.spawnle, os.spawnlp, os.spawnlpe, os.spawnv, os.spawnve, os.spawnvp, os.spawnvpe, os.startfile ] shell [ os.system, os.popen, os.popen2, os.popen3, os.popen4, popen2.popen2, popen2.popen3, popen2.popen4, popen2.Popen3, popen2.Popen4, commands.getoutput, commands.getstatusoutput ] subprocess [ subprocess.Popen, subprocess.call, subprocess.check_call, subprocess.check_output ]运行方式bandit -c pyproject.toml -r .配置加载的源码实现理解 core/config.py 中的BanditConfig类可以弄清上述配置的加载细节格式判定按文件后缀以.toml结尾的文件走 TOML 解析Python 3.11 使用标准库tomllib更早版本回退到tomli若解析器不可用会抛出ConfigError提示reinstall with toml extra即需要安装bandit[toml]附加依赖否则一律按 YAML 用yaml.safe_load解析core/config.pyTOML 只取[tool.bandit]段tomllib.load(f).get(tool, {}).get(bandit, {})core/config.py这也解释了为什么pyproject.toml中必须使用[tool.bandit]前缀解析后校验validate(config_file)会对 legacyprofiles中的黑名单测试引用做一致性检查配置合法但为 dict 之外类型时抛出ConfigErrorcore/config.py未提供配置文件时的默认值plugin_name_pattern *.py、include [*.py, *.pyw]core/config.py。此外命令行-x/--exclude的默认排除目录来自 core/constants.py 的EXCLUDE常量.git、__pycache__、.tox等CLI 帮助文本明确说明这些排除路径与配置文件中的排除路径相互叠加而非互相替代。文档还给出两条实用建议如果不同任务需要多套测试集应创建多份配置文件用-c在不同场合挑选如果只想控制运行哪些测试而不关心插件参数直接用命令行的-t/-s更简洁。tests 与 skips 的组合语义配置文件中可选的tests纳入与skips排除列表等价于命令行的-t/-s。四种组合的语义如下只给tests只给skips两者都给同一测试 ID 同时出现在两者只运行列表中的测试等价于排除其余全部测试运行除列表外所有测试先取tests集合再从中剔除skips报错配置非法命令行-t/-s与配置文件中的tests/skips可以共存结果是先把-t与tests拼接、-s与skips拼接再按上述规则计算最终运行的测试集。源码中这一逻辑分三步完成。第一步cli/main.py 的_get_profile从配置中取出tests与skips填充profile[include]与profile[exclude]第二步命令行参数合并profile[include].update(args.tests.split(,))、profile[exclude].update(args.skips.split(,))cli/main.py第三步extension_mgr.validate_profile(profile)校验测试 ID 合法性并拒绝同一 ID 既 include 又 exclude的矛盾配置失败时记录错误日志并以退出码 2 退出cli/main.py。nosec行级告警抑制当某行代码触发了 Bandit 告警但经过人工评审确认是误报或可接受的风险时可在行尾追加# nosec与该行的所有告警关联的结果将不再报告self.process subprocess.Popen(/bin/echo, shellTrue) # nosec精确到具体测试的抑制同一行可能触发多个测试。为避免无差别静音掩盖后续新引入的漏洞nosec后可以附带具体测试 ID只抑制列出的测试其余告警仍会正常报告# 只抑制 B602 与 B607本行其他问题仍会报告 self.process subprocess.Popen(/bin/ls *, shellTrue) # nosec B602, B607测试名称也可以替代测试 ID 使用# 抑制 B101(assert_used)B506 仍会正常报告 assert yaml.load({}) [] # nosec assert_used抑制的完整工作流可以在 core/manager.py 中找到注释匹配正则NOSEC_COMMENT re.compile(r#\s*nosec:?\s*(?Ptests[^#])?#?)与测试 ID 正则NOSEC_COMMENT_TESTS re.compile(r(?:(B\d|[a-z\d_]),?), re.IGNORECASE)core/manager.py扫描每个文件时BanditManager用tokenize遍历注释 token把行号 → 待抑制测试集合存入nosec_lines字典core/manager.py。空集合表示该行使用了不带 ID 的全局# nosec_parse_nosec_comment逐段提取 ID 或测试名_find_test_id_from_nosec_string先按 ID 匹配、再按测试名回查无法识别的名称会被记录日志并忽略core/manager.py命令行提供--ignore-nosec选项可整体关闭 nosec 行为强制报告所有被抑制的行cli/main.py适合审计已有代码中被静音的告警。文档同时建议使用 nosec 时附上解释性注释说明为什么该行被排除在安全检查之外这是良好的工程实践。使用 bandit-config-generator 自动生成配置为手工编写配置文件尤其是逐插件的覆盖段往往费时且容易写错键名。Bandit 自带bandit-config-generator工具可以自动导出当前安装环境下所有测试与黑名单插件的默认配置块供你删除或编辑成精简配置。其实现见 cli/config_generator.py--show-defaults打印各插件默认设置但不生成文件-o / --out指定输出文件文件已存在时拒绝覆盖并以退出码 2 退出-t / --tests与-s / --skip指定纳入/排除的测试 ID 列表生成文件中将填充对应的tests:/skips:段不传时生成文件不包含这两个段但会附一份完整测试 ID 清单供编辑时参考见模板注释 cli/config_generator.py配置块内容来自各插件模块get_config_settings遍历已加载插件对带有_takes_config标记且模块内实现了gen_config的插件调用其生成器cli/config_generator.py最终用yaml.safe_dump序列化。生成后把不需要的段删掉即可其余插件会沿用内置默认值。该工具也是从 legacy 配置迁移到新格式时官方推荐的助手ConfigError的报错信息与 legacy 配置的弃用日志中都会提示使用它见 core/config.py。为测试插件定制参数Bandit 的配置文件为每个测试插件提供了以测试方法名命名的配置段。官方文档给出的示例是try_except_pass插件B110检测try/except/pass静默吞异常模式try_except_pass: check_typed_exception: True具体配置块包含哪些键、默认值是什么由插件自身决定完整信息可查阅仓库内生成的插件文档列表。以 plugins/try_except_pass.py 为例可以看到插件侧的完整约定模块内定义了gen_config(name)返回默认配置该插件默认为check_typed_exception: False测试函数通过test.takes_config装饰器声明我需要配置装饰器会把配置段名即函数名try_except_pass记录到函数属性_takes_config上core/test_properties.py运行时core/test_set.py 会先尝试config.get_option(plugin.plugin._takes_config)从配置文件取同名段的值取不到时再调用插件模块的gen_config拿内置默认值。这正是配置文件中的设置优先于内置默认值的实现机制。从该插件的实现看check_typed_exception: True时即便except指定了具体异常类型如except ZeroDivisionError:也会报告Try, Except, Pass detected置为False则放过带类型声明的异常捕获。这展示了插件级覆盖如何直接改变扫描行为。在 pre-commit 中携带 Bandit 配置当项目通过 pre-commit 框架集成 Bandit 并使用了 YAML/TOML 配置文件时需要在 pre-commit 的 hook 配置中显式传入配置文件必要时声明附加依赖。官方文档给出的配置形态如下additional_dependencies中的bandit[toml]对应前文 TOML 解析所需解析器repos: - repo: https://github.com/PyCQA/bandit rev: # Update me! hooks: - id: bandit args: [-c, pyproject.toml] additional_dependencies: [bandit[toml]]其中rev: 占位符需要在接入时替换为实际使用的版本标签。注意pre-commit 环境中的 Bandit 运行于隔离环境-c指向的配置文件路径是相对于 pre-commit 运行时工作目录解析的若配置放在项目根目录之外需要改为绝对路径。配置错误的排查要点结合源码中的错误处理路径配置相关问题可以按以下线索排查Could not read config file.——-c指向的文件不存在或不可读core/config.pytoml parser not available, reinstall with toml extra—— 使用 TOML 配置但未安装bandit[toml]附加依赖core/config.pyError parsing file.—— YAML/TOML 语法错误或解析后不是 dictcore/config.pylegacy 配置警告—— 配置中含旧式profiles/ 黑名单数据时Bandit 会自动转换为新格式并打印弃用警告提示可用bandit-config-generator迁移core/config.py.bandit找不到或冲突—— 未加-r时不会自动发现 INI 文件一次扫描范围内出现多个.bandit会直接报错要求用--ini指定其一cli/main.py测试集矛盾—— 同一测试 ID 同时出现在tests与skips或经-t/-s合并后如此会触发校验错误退出码 2cli/main.py。此外-d/--debug与-v/--verbose可分别打印配置来源日志与被排除文件明细是验证我的配置到底有没有生效的最低成本手段。小结Bandit 的配置体系可以概括为三层INi 文件.bandit负责项目级命令行参数预设YAML/TOML 文件-c负责测试选择与插件参数覆盖# nosec负责行级、可精确到测试 ID 的告警抑制。三层机制分别由 core/utils.py 的 INI 解析、core/config.py 的BanditConfig加载器与 core/manager.py 的 nosec 解析器实现且都提供了明确的错误信息与日志来源说明。配合bandit-config-generator可以低成本地为团队生成起点配置再按前文的组合语义与插件定制方法逐步收敛为最小可用配置。赞分享SAST应用安全【免费下载链接】banditBandit is a tool designed to find common security issues in Python code.项目地址https://gitcode.com/gh_mirrors/ba/bandit点击查看免费下载相关推荐Traefik配置文件TOML与YAML格式详解Traefik配置文件TOML与YAML格式详解 引言配置格式的选择困境 你是否曾在部署Traefik时面对TOML与YAML两种配置格式犹豫不决是否疑后端API网关负载均衡微服务网络云原生TOML vs JSON vs YAML为什么TOML是配置文件的终极选择TOML vs JSON vs YAML为什么TOML是配置文件的终极选择 你是否曾在配置文件中迷失于JSON的引号迷宫或者被YAML的缩进规则搞得晕头转开发工具Zettlr 配置类语言语法高亮完全指南Dockerfile、TOML/INI、YAML 与 HCL/Terraform 实战详解Zettlr 配置类语言语法高亮完全指南Dockerfile、TOML/INI、YAML 与 HCL/Terraform 实战详解 Zettlr 是一款面向学桌面应用前端知识管理科研上一篇终极SketchUp STL插件指南从3D建模到实体打印的完美转换下一篇深度解析Lynx如何用版本化像素管线实现原生级渲染创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表