leroidubuffet/cenit-propuestas

GitHub: leroidubuffet/cenit-propuestas

一个 LLM 提示词注入安全教学实验室,通过三个版本的聊天机器人演示和对比分层防护方案的实际效果。

Stars: 0 | Forks: 0

# Cenit Propuestas — 安全实验室模块 7 同一个 chatbot 的三个版本,用于演示和缓解 基于 LLM 系统中的 prompt injection 漏洞。 | 端口 | 版本 | 模型 | 演示内容 | |--------|---------|--------|---------------| | 8000 | `app_vulnerable.py` | Llama 3.1 8B (Groq) | System prompt 被直接拼接到 `user` 角色的 input 中。三种攻击均可成功。 | | 8001 | `app_parcheada.py` | Claude Sonnet 4.6 | 结构化分离(`system=`) + blacklists。`DISABLE_BLACKLISTS` flag 允许单独测试每一层防护。 | | 8002 | `app_parcheada_v2.py` | Claude Sonnet 4.6 + Haiku 4.5 | 结构化分离 + 使用 Claude Haiku 的语义 guardrails。也能抵抗规避攻击。 | ## 前置条件 - Docker 和 Docker Compose(24.0 / 2.20 或更高版本) - 带有可用余额的 Anthropic API Key(`sk-ant-...`) — 用于端口 8001 和 8002 - Groq API Key(在 console.groq.com 免费获取) — 用于端口 8000 - Python 3.8 或更高版本(用于通过 `python3 -m json.tool` 格式化输出) - `jq`(用于攻击脚本:`brew install jq` / `sudo apt install jq`) - `curl` ## 步骤 0:初始配置 ``` cp .env.example .env ``` 编辑 `.env` 并添加这两个密钥: ``` ANTHROPIC_API_KEY=sk-ant-... GROQ_API_KEY=gsk_... ``` Groq 密钥可在 **console.groq.com → API Keys → Create API Key** 获取(免费账号,无需信用卡)。 ``` docker compose build ``` ## 步骤 1:攻击易受攻击的系统 ### 1.1 启动易受攻击的服务 ``` docker compose up cenit-propuestas-vulnerable -d ``` 在继续之前验证其是否已准备就绪: ``` curl -s http://localhost:8000/ # 应该返回:{"servicio": "Cenit Propuestas", "version": "vulnerable", ...} ``` ### 1.2 发起攻击 ``` ./attacks/attack_1_extraccion_rol.sh ./attacks/attack_2_suplantacion.sh ./attacks/attack_3_simulacion_admin.sh ``` 这三次攻击都应该泄露内部费率或确认虚假操作。 将结果记录在 `EXERCISE_NOTES.md` 中。 ## 步骤 2:应用防御并检查其效果 ### 2.1 仅使用结构化分离(不含 blacklists) ``` docker compose down DISABLE_BLACKLISTS=true docker compose up cenit-propuestas-parcheado -d ``` 验证其是否已准备就绪: ``` curl -s http://localhost:8001/ # 应该返回:{..., "blacklists_activas": false} ``` 对已修补的服务重复攻击: ``` ENDPOINT=http://localhost:8001/chat ./attacks/attack_1_extraccion_rol.sh ENDPOINT=http://localhost:8001/chat ./attacks/attack_2_suplantacion.sh ENDPOINT=http://localhost:8001/chat ./attacks/attack_3_simulacion_admin.sh ``` 三种攻击均被拦截。模型拒绝了它们,因为 system prompt 是通过 `system=` 字段以结构化权威传递的,而不是作为可以被覆盖的 用户文本。没有任何激活的过滤器:抵抗力 完全由结构化分离提供。 ### 2.2 添加 blacklists ``` docker compose down docker compose up cenit-propuestas-parcheado -d ``` 验证其是否已准备就绪: ``` curl -s http://localhost:8001/ # 应该返回:{..., "blacklists_activas": true} ``` 重复攻击: ``` ENDPOINT=http://localhost:8001/chat ./attacks/attack_1_extraccion_rol.sh ENDPOINT=http://localhost:8001/chat ./attacks/attack_2_suplantacion.sh ENDPOINT=http://localhost:8001/chat ./attacks/attack_3_simulacion_admin.sh ``` 三种攻击均被拦截。在日志中查看警报: ``` docker compose logs cenit-propuestas-parcheado | grep ALERTA ``` ### 2.3 绕过 blacklists 无需更改已启动的服务: ``` ENDPOINT=http://localhost:8001/chat ./attacks/attack_4_evasion.sh ``` 这三个变体(不同语言、同义词、间接比例)绕过了 input 过滤器并到达了模型。如果模型包含列表中的术语,output 过滤器可以捕获 响应;在这种情况下,响应 将是 "No puedo responder a esa pregunta." (我无法回答这个问题),而不是泄露的信息。 教训是 blacklists 在两层中都很脆弱:已知词汇 是有限的,任何重新表述都可以绕过它。 ## 步骤 3(附加):使用 Haiku 的语义 guardrails ``` docker compose down docker compose up cenit-propuestas-parcheado-v2 -d ``` 验证其是否已准备就绪: ``` curl -s http://localhost:8002/ ``` 六种攻击(3 种原始攻击 + 3 种规避攻击)都应该被拦截: ``` ENDPOINT=http://localhost:8002/chat ./attacks/attack_1_extraccion_rol.sh ENDPOINT=http://localhost:8002/chat ./attacks/attack_2_suplantacion.sh ENDPOINT=http://localhost:8002/chat ./attacks/attack_3_simulacion_admin.sh ENDPOINT=http://localhost:8002/chat ./attacks/attack_4_evasion.sh ``` blacklist 和语义 guardrail 之间的直接对比: ``` # 绕过 blacklist ENDPOINT=http://localhost:8001/chat ./attacks/attack_4_evasion.sh # 被 Haiku guardrail 阻止 ENDPOINT=http://localhost:8002/chat ./attacks/attack_4_evasion.sh ``` ## 停止服务 ``` # 停止所有 contenedores(保留它们以便重新启动) docker compose stop # 停止并删除 contenedores docker compose down # 停止并删除 contenedores、imágenes 和 volúmenes docker compose down --rmi all ``` ## 附加文档 | 文件 | 内容 | |---------|-----------| | `EXERCISE_NOTES.md` | 供学生记录结果和反思的模板 | | `guia_docente.md` | 包含时间、各阶段说明和 troubleshooting 的会话指南 | | `notas_diseno.md` | 变体 B 的技术决策:为何更好,为何更差,如何绕过该补丁 |
标签:Docker, Sysdig, 安全防御评估, 安全防护, 版权保护, 生成式AI, 索引, 请求拦截, 逆向工具