AI 生成的 Python 代码安全吗?用 Bandit 定位危险调用

用 Bandit 扫描 AI 生成的 Python,定位 eval 与 shell=True,读取严重程度及置信度;按明确需求替换危险调用、复扫并核对输入和路径边界。

检查 AI 生成的 Python 代码是否包含危险调用,可以先用 Bandit 扫描 Python 语法树。它会定位一些已知的风险模式,例如 eval 和拼接输入后调用 shell=True。报告提供规则、代码行、严重程度和判断置信度,便于逐条复核;扫描通过仍需结合权限、数据流和实际业务审查。

安装后先扫描教学样例,不运行危险函数

本文实际验证环境为 Windows、Python 3.13.14、Bandit 1.9.4。新建练习目录后执行:

AI 生成的 Python 代码安全吗?用 Bandit 定位危险调用

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install bandit==1.9.4
.\.venv\Scripts\python.exe -m bandit --version

Bandit 1.9.4 要求 Python 3.10 或更新版本。macOS 或 Linux 将路径换为 .venv/bin/python。项目已配置工具时沿用项目版本;安装与递归扫描方式见Bandit 官方入门文档。

下面是故意带问题的教学代码,保存为 generated_bad.py。不要给这两个函数喂真实用户输入,也不需要运行它们:

import subprocess


def compute(text):
    return eval(text)


def list_dir(user_path):
    return subprocess.check_output('dir ' + user_path, shell=True)

扫描单文件,保存 JSON:

.\.venv\Scripts\python.exe -m bandit generated_bad.py -f json -o bandit-before.json

Bandit 在本例中实际返回退出码 1,JSON 的 errors 为空,results 有 3 条。扫整个项目可用 bandit -r src,但路径要指向业务源码,避免把虚拟环境和第三方库一起扫入。不要先加严重程度过滤,否则入门时可能漏看低级别提示。

规则 本例报告 如何判断
B404 第 1 行导入 subprocess,LOW / HIGH 提醒查看子进程使用,导入本身不等于已经存在可利用漏洞
B307 第 5 行 eval,MEDIUM / HIGH 字符串可能被作为 Python 表达式执行,必须核对输入来源
B602 第 9 行 shell=True,HIGH / HIGH 外部输入参与 shell 命令字符串,需检查命令注入路径

表中斜线前为 Severity,后为 Confidence。Confidence 高表示规则对这一代码模式的判断较确定,不是“漏洞利用概率高”。规则解释可查危险调用列表和B602 官方说明。

按真实任务替换危险调用

先把需求缩小并说清:compute 只求 JSON 数字数组之和;list_dir 只列出工作目录下 uploads 内指定目录的一层文件名。不需要任意表达式执行,也不需要 shell。保存为 generated_fixed.py:

import json
from pathlib import Path


def compute(text):
    values = json.loads(text)
    if not isinstance(values, list) or not values:
        raise ValueError('需要非空数字数组')
    if any(type(value) not in (int, float) for value in values):
        raise ValueError('数组只能包含数字')
    return sum(values)


def list_dir(user_path):
    root = Path('uploads').resolve()
    target = (root / user_path).resolve()
    if not target.is_relative_to(root):
        raise ValueError('目录超出 uploads')
    if not target.is_dir():
        raise ValueError('目录不存在')
    return sorted(path.name for path in target.iterdir())

先进行路径归一化,再检查目标是否仍在根目录内,可以拒绝 .. 向上跳出目录的请求。这里没有调用子进程,避免了 shell 命令拼接。若真实任务必须调用外部程序,应核对固定可执行文件、参数列表和输入白名单;仅把 shell=True 改成 False 不能证明所有输入都可信,B603也提醒检查无 shell 子进程的输入。

复扫后,还要核对修复有没有破坏功能

.\.venv\Scripts\python.exe -m bandit generated_fixed.py -f json -o bandit-after.json
.\.venv\Scripts\python.exe -c "from generated_fixed import compute; assert compute('[1,2,3]') == 6; print('求和样例通过')"

修复稿在本文环境中实际得到退出码 0、errors=[]、results=[]。另外实际检查了数字数组求和、拒绝布尔值、拒绝空数组、拒绝对象,以及拒绝路径 .. 五个条件。读者应保留修复前后的 JSON 与代码差异,再核对自己业务里的合法输入仍能得到正确结果。

目录示例可以在练习目录创建 uploads/demo,放一个无敏感信息的文件,然后调用 list_dir('demo') 核对返回文件名;调用 list_dir('..') 应得到“目录超出 uploads”。这些是验证方法,不是本文已完成的真实服务器权限测试。

上面的修复只用于受控练习目录。真实文件服务还需做用户归属校验、限制文件名与响应数量、避免符号链接和检查后路径被替换的竞争问题,并限制请求体大小。JSON 示例也未限制超大数组、浮点非有限值和溢出,不能直接作为对外的计算 API。扫描器不会替你确认这些业务前提。

遇到误报和已有问题,怎样处理?

先读输入从哪里来、是否可能被用户控制,再判断规则是否适用。不要为得到绿灯全局跳过 B602 或批量添加 nosec。确有误报时,记录具体规则与理由,缩小例外范围,并让评审能看见。官方支持 JSON 基线对比,但基线只方便识别新增问题,不会修复历史问题。

最终检查分成三个结果:工具是否完整扫描、危险模式是否已消除、业务验证是否通过。如果 JSON 的 errors 非空或文件被跳过,先解决扫描失败;没有检出项不能替代依赖漏洞检查和授权审查。关于 AI 草稿中还有哪些风险,可继续阅读AI 编程的代码质量与安全风险。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30542.html

赞 (0)
AI小管家的头像AI小管家
豆包 AI 和 Qwen 怎么选?用同一任务测试中文办公与代码辅助
上一篇 11小时前
Qwen 智能体怎么样?先分清模型、工具调用和业务自动化
下一篇 11小时前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部