首页
/ ECC Python 安全规则实战:环境变量密钥管理与 bandit 静态扫描的分层防护指南

ECC Python 安全规则实战:环境变量密钥管理与 bandit 静态扫描的分层防护指南

2026-09-07 09:16:37作者:裴麒琰

本文围绕 ECC 仓库中面向 Python 开发与审查场景的安全规则文件 .cursor/rules/python-security.md 展开,讲解它在「通用安全规则 → Python 语言安全规则」分层体系中的位置,以及密钥管理、静态安全扫描两大核心命题。读完本文,你将掌握如何在 Python 项目中用环境变量替代硬编码密钥、用 bandit 建立可持续的静态安全扫描闭环,并理解这些规则如何在 ECC 的 python-reviewer Agent 与 /python-review 命令中被自动化执行。

规则文件的定位:Python 安全在 ECC 分层体系中的落点

.cursor/rules/python-security.md 是一份典型的 Agent 规则文件,其 frontmatter 定义了规则的元信息:

description: "Python security extending common rules"
globs: ["**/*.py", "**/*.pyi"]
alwaysApply: false
  • description 开门见山:本文件是对通用安全规则的 Python 化扩展
  • globs 将规则的作用域限定为 Python 源码文件(.py 与类型桩文件 .pyi);
  • alwaysApply: false 结合 globs 语义,可以推断该规则面向「上下文包含 Python 源文件」的代码生成与审查场景按需生效,而非无差别注入每一次对话。

规则正文第一句点明了它在 ECC 中的层级关系:

This file extends the common security rule with Python specific content.

也就是说,ECC 将安全规则组织为两层:一层是语言无关的通用基线(对应 .cursor/rules/common-security.md,以及规则分发目录 rules/common/security.md),另一层是语言特化扩展(如本文所述的 Python 规则)。这种「common 打底、语言规则叠加」的设计,在仓库中还有一批并行的兄弟规则,例如 .cursor/rules/ 下的 golang-security.mdkotlin-security.mdphp-security.mdswift-security.mdtypescript-security.md,以及在 rules/python/ 目录下与安全规则并列的 coding-style.mdtesting.mdhooks.mdpatterns.mdfastapi.md 等配套规则。

值得注意的是,仓库中 Python 安全规则的正文存在两处一致性存放:面向 Cursor harness 的 .cursor/rules/python-security.md(使用 globs 描述作用域)与规则库主目录 rules/python/security.md(使用 paths 描述作用域),正文内容一致,说明同一份规则会被封装适配到不同 Agent harness 使用。

继承的通用底线:提交前的强制安全清单

Python 规则并未自建一套脱离上下文的规范,而是默认叠加上 rules/common/security.md 中约定的、任何代码提交前必须逐项核对的安全清单:

  • 不得在代码中硬编码任何秘密(API Key、密码、Token);
  • 所有用户输入必须经过校验;
  • 通过参数化查询防范 SQL 注入;
  • 通过 HTML 净化防范 XSS;
  • 开启 CSRF 防护;
  • 认证 / 授权逻辑经过验证;
  • 所有端点具备限流;
  • 错误信息不得泄露敏感数据。

与这份清单呼应,.cursor/rules/common-security.md 进一步给出密钥管理的四条铁律:绝不硬编码、一律使用环境变量或密钥管理器、启动时校验必需密钥存在、对任何可能已暴露的密钥立即轮换。下面的 Python 特化内容正是把这些通用原则落为可执行的代码与命令。

密钥管理:让 API Key 只存在于进程环境中

Python 规则给出的密钥管理示例,是把「环境变量承载秘密 + 启动即校验」落地为两行关键逻辑:

import os
from dotenv import load_dotenv

load_dotenv()

api_key = os.environ["OPENAI_API_KEY"]  # Raises KeyError if missing

逐行拆解这段代码的安全语义:

  1. from dotenv import load_dotenvpython-dotenv 允许本地开发时从一个 .env 文件把配置注入进程环境,让本地环境与 CI/生产环境统一通过 os.environ 取值,避免因「本地没有环境变量就跑不起来」而诱使开发者把密钥写死进源码;
  2. load_dotenv():将项目根目录的 .env 文件读入环境,注意它只填充缺失变量,不覆盖进程已有的同名环境变量,因此在部署时由编排平台注入的真实密钥优先级更高;
  3. os.environ["OPENAI_API_KEY"]:这里刻意使用下标索引而不是 os.environ.get("OPENAI_API_KEY")。下标访问在键缺失时抛出 KeyError(代码注释也明确标注了这一行为),实现「fail fast」——如果启动环境中没有配置密钥,程序立即失败,而不是带着 None 空值继续运行,把错误推迟到真正调用第三方 API 时才暴露。这与通用规则「Validate that required secrets are present at startup(启动时校验必需密钥存在)」的要求完全一致。

.env 文件本身绝不能提交进版本库,应在 .gitignore 中排除,并维护一份不含真实值的 .env.example 作为配置模板供团队拷贝。

对于更复杂的场景,可以引入带默认值与类型转换的读取方式,例如 skills/django-security/SKILL.md 中展示的 django-environ 用法——通过 env('DJANGO_SECRET_KEY') 这类显式读取让缺失配置在配置装载阶段立即报错,同时用 env('DEBUG', default=False, cast=bool) 对可选配置提供受控默认值。这也是把「错误信息不泄露敏感数据」贯彻到配置层的手段之一。

静态安全扫描:用 bandit 建立持续防线

规则要求将 bandit 作为 Python 静态安全分析工具接入日常流程:

bandit -r src/

-r 表示递归扫描 src/ 目录下的所有 Python 文件。bandit 通过 AST 分析在不执行代码的前提下识别高危模式,例如:

  • 探测到疑似硬编码的密码 / API Key(B105B106B107 等);
  • 不安全的 eval / exec 调用、pickle 反序列化、yaml.load
  • 使用 MD5 / SHA1 等弱哈希处理安全场景、不安全的随机数生成;
  • 拼接式 SQL、subprocess 中直接执行不可信输入等注入类风险。

实际接入 CI 时,可以带上严重级别过滤并让高风险项直接令流水线失败,例如:

# 只报告 HIGH 及以上问题并给出机器可读输出
bandit -r src/ -lll -f json -o bandit-report.json

# 用退出码控制门禁(发现 issue 即非零退出)
bandit -r src/ -q

bandit 在 ECC 中不是孤立建议,它已深度内嵌进仓库的审查工具链,成为可验证的实现事实:

  • agents/python-reviewer.md 的「Diagnostic Commands」将 bandit -r . 列为与 mypy .ruff check .black --check . 并列的标准诊断步骤,并在 CRITICAL 级安全审查清单中覆盖 SQL/命令注入、路径穿越、eval/exec 滥用、不安全反序列化、硬编码密钥、弱加密、YAML 不安全 load 等 bandit 典型可检出项;
  • commands/python-review.md 在自动化检查脚本中串联了 bandit -r .、依赖审计 pip-auditsafety check,将「静态漏洞扫描」与「依赖供应链风险扫描」合并为一个门禁;
  • skills/python-patterns/SKILL.md 的 Tooling Integration 一节同样把 bandit -r . 作为 Python 工程的必需命令,并与 blackisortruffmypypytest 构成完整工具链。

也就是说,规则的命令只有一句话,但仓库层面的实践把它扩展成了「代码静态分析 → 依赖审计 → 漏洞修复 → 重新扫描」的闭环。

从规则到自动化:审查 Agent 如何执行 Python 安全门禁

规则文件定义了「应当做什么」,而 ECC 把规则翻译成了可自动执行的审查行为。commands/python-review.md 描述的 /python-review 命令流程包含:先通过 git diff 定位改动文件,再运行静态分析工具,随后重点检查 SQL 注入、命令注入、不安全反序列化等安全问题,最后按严重级别输出报告。

Python 审查 Agent agents/python-reviewer.md 给出的 CRITICAL 级安全红线可以直接视为对 python-security 规则的落地解读:

  • SQL 注入:查询中拼 f-string → 必须改参数化查询;
  • 命令注入:未校验输入进入 shell → 用 subprocess 的参数列表形式调用;
  • 路径穿越:用户可控路径 → 用 normpath 校验并拒绝 ..
  • eval/exec 滥用、不安全反序列化、硬编码密钥、弱哈希、yaml.load 不安全加载。

其输出与放行标准构成可复用的门禁模型:

状态 条件 处置
PASS 无 CRITICAL / HIGH 问题 允许合入
WARNING 仅存在 MEDIUM 问题 谨慎合入
FAIL 发现 CRITICAL / HIGH 问题 阻塞合入,修复后再过审

如果审查中发现安全问题,通用规则还规定了处置协议:立即停止当前工作、转交 security-reviewer Agent(对应 agents/security-reviewer.md)、优先修复 CRITICAL 级问题、轮换可能已暴露的密钥,并对整个代码库复查同类问题。

框架特化与配套资源

python-security 规则的 Reference 一节明确指出:若项目基于 Django,还应参考 django-security 技能获取框架级安全指引。对应仓库实现为 skills/django-security/SKILL.md,其覆盖范围包括生产环境配置(DEBUG = False、安全响应头、HSTS)、SECRET_KEY 强制走环境变量并在缺失时抛出 ImproperlyConfigured、CSRF/XSS/SQL 注入的 ORM 与模板层防护、文件上传校验与限流等。FastAPI 场景的安全要点则散见于 rules/python/fastapi.md 与审查命令中的「CORS 配置、Pydantic 请求校验、响应模型正确性」等专项检查。

此外,Python 工程师还可将安全规则与同一目录下的其余规则配套使用,形成完整覆盖:.cursor/rules/python-coding-style.md 负责 PEP 8 与代码风格、rules/python/testing.md 负责测试纪律、rules/python/patterns.md 负责 Pythonic 模式,而 skills/python-testing/ 提供测试技能层面的支撑。

落地自检清单

将通用与 Python 特化规则汇总为可勾选的提交前自检表:

检查项 说明
无硬编码密钥 全部敏感值来自 os.environ 或密钥管理器,.env 不入库
启动即校验 os.environ["KEY"] 下标访问或配置框架显式声明,缺失立即失败
静态扫描通过 bandit -r src/ 无 HIGH 级以上告警
依赖审计通过 pip-audit / safety check 无已知漏洞告警
输入已校验 用户输入全部验证,杜绝拼接式 SQL / shell 命令
泄漏即轮换 一旦疑似暴露立即轮换并全库复查同类模式
框架规则遵循 Django 项目对照 django-security 技能,FastAPI 项目对照 rules/python/fastapi.md

安全不是一次性动作,而是持续过程。把通用清单、Python 特化规则、bandit 扫描与 Agent 门禁串成一条自动化链条,才能在每次提交前稳定守住密钥与漏洞两条底线。

登录后查看全文
热门项目推荐
相关项目推荐