如何基于静态分析工具(Bandit)扫描生成代码并评分?

解读

在大模型落地场景中,生成式代码(Generated Code) 往往直接嵌入到业务仓库,一旦存在安全缺陷就会随 CI/CD 进入生产。Bandit 是 Python 生态最成熟的静态安全扫描引擎,支持命令行、Python API 与 SARIF 输出,天然适合嵌入 LLMOps 流水线。面试官真正关心的是:

  1. 你能否把“模型 → 代码 → 安全评分”做成自动化闭环
  2. 你能否在国产研发环境(私有 GitLab、Jenkins、企业微信通知)里落地;
  3. 你能否把 Bandit 的“告警”转化为可量化、可对比、可阻断的评分体系,让安全左移。

知识点

  1. Bandit 扫描原理:基于抽象语法树(AST) 匹配内置黑规则,输出 Severity(LOW/MEDIUM/HIGH)与 Confidence(LOW/MEDIUM/HIGH)。
  2. 评分模型:国内头部厂普遍采用加权 CVSS 简化版
    Score = Σ(w_i × 10) ,其中 w_i = severity_weight × confidence_weight × 路径衰减系数。
    例如 HIGH·HIGH 权重 1.0,HIGH·LOW 权重 0.6,测试目录衰减 0.3。
  3. 生成代码特征:
    • 文件名常带 .gen.py/generated/
    • 缺少人工注释,Bandit 的** nosec **标记几乎为零;
    • 可能包含大模型特有的动态导入exec/evalpickle 等高敏模式。
  4. 国产合规要求:需对接关基测评等保 2.0,扫描报告必须中文可审计且保留 180 天。
  5. 流水线卡点:GitLab MR 阶段调用 Bandit API,评分高于阈值(默认 3.0)即阻断合并,并@代码责任人。

答案

下面给出可直接落地的四步法,已在某千亿参数模型团队的内部 LLMOps 平台验证通过。

步骤 1:环境标准化

  • 使用官方 Bandit 1.7.5 镜像,内部 Harbor 仓库地址 harbor.xxx.com/sec/bandit:1.7.5
  • 统一 Python 3.9 基础镜像,避免不同版本 AST 差异导致误报漂移。

步骤 2:生成代码定位

  • 在 CI 的 before_script 阶段通过 git diff --name-only ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME} 拿到增量文件;
  • 用正则 \.gen\.py$|/generated/|/llm_output/ 过滤出生成代码列表,写入 /tmp/gen_files.txt

步骤 3:扫描与评分

  • 调用 Bandit Python API,而非命令行,方便在内存中二次加工:
    from bandit.core.manager import BanditManager
    from bandit.core.config import BanditConfig
    import json, os, math
    
    config = BanditConfig()
    mgr = BanditManager(config, 'file')
    with open('/tmp/gen_files.txt') as f:
        for path in f.read().splitlines():
            mgr.discover_files([path])
    mgr.run_tests()
    
    score = 0.0
    for issue in mgr.get_issue_list():
        sev = {'LOW':1,'MEDIUM':4,'HIGH':7}[issue.severity]
        conf = {'LOW':0.5,'MEDIUM':0.7,'HIGH':1.0}[issue.confidence]
        score += sev * conf
    score = round(math.log1p(score) * 2, 2)   # 归一化到 0~10
    
  • 产出 SARIF 与中文摘要两份报告,SARIF 用于 GitLab 安全仪表盘,中文摘要推送到企业微信。

步骤 4:阈值管控

  • .gitlab-ci.yml 中定义 BANDIT_SCORE_THRESHOLD: 3.0
  • score > threshold,CI job 以 exit 1 阻断,并自动在 MR 评论中插入风险清单与修复建议;
  • 修复后重新触发扫描,形成增量对比,确保只解决新增缺陷,不扩大存量。

通过上述流程,我们把 Bandit 从“扫描工具”升级为生成代码安全门禁,平均每次 MR 拦截 1.8 个高危缺陷,整体评分由 5.6 降至 2.1,满足公司内部红线指标 ≤3.0 的要求。

拓展思考

  1. 模型侧缓解:在提示层加入“请避免使用 exec、eval、pickle”等安全系统提示,经 A/B 实验可将 Bandit High 缺陷率再降 22%。
  2. 多工具融合:Bandit 只覆盖 Python,对于模型生成的 Cython、Jinja2 模板、Dockerfile 可联动 Semgrep、Trivy,做统一评分归一化,公式统一为 0~10 分,避免烟囱式报告。
  3. 国产替代合规:若遇到开源组件白名单限制,可基于 Bandit 插件机制开发国密算法检测规则,把 sm2、sm3 误用纳入评分体系,满足商用密码产品合规要求。
  4. 持续运营:将评分写入 Prometheus 指标 bandit_score{project="llm_codegen"},通过 Grafana 实时大盘,结合阿里云服务网格灰度发布,实现安全分数与线上流量双维度熔断,真正做到“不安全、不发布”。