ShirePyDev/Prompt-Injection-Detection-System

GitHub: ShirePyDev/Prompt-Injection-Detection-System

一个面向 LLM Prompt Injection 检测器的多轴评估基准,通过过度防御、混淆鲁棒性、分布偏移等维度揭示单一 F1 分数掩盖的部署风险。

Stars: 1 | Forks: 0

# PIDS-Bench:一个用于 Prompt Injection 检测器的多轴评估框架 本仓库包含了论文背后的冻结基准测试、评估代码以及数据集构建 pipeline。这里的所有内容都旨在确保结果可以从一个干净的检出中复现。 ## 📖 概述 Prompt-injection 检测器越来越多地被部署为 LLM 系统前面的网关分类器,然而大多数已发表的评估仅通过单个同分布测试集上的单个 F1 分数来总结检测器。这种做法掩盖了检测器部署后才会暴露的关键错误——特别是它将*良性*输入误报为攻击的频率。 PIDS-Bench 同时沿着多个轴评估检测器:同分布准确率、在表面上类似于攻击的输入上的良性假阳性行为、对混淆攻击的鲁棒性,以及在领域和结构分布偏移下的行为。我们评估了涵盖经典、微调、外部和广泛安全设计的七种检测器,并单独报告了一个基于规则的启发式方法作为下界参考。 核心发现是,检测器的同分布 F1 并不能预测其良性侧的安全性。最强的内部检测器达到了 0.9882 的同分布 F1,但仍然将一个对抗性构建的良性集合中的大约 **38%** 标记为攻击,并且我们表明这种过度防御无法通过阈值校准来消除。根据良性输入的*来源*分解良性错误揭示了一种我们称之为**来源敏感型过度防御 (provenance-sensitive over-defense)** 的不对称性:精心挑选的硬负样本增强几乎消除了精心挑选的良性输入上的过度防御,但在外部获取的输入上却基本保持不变。 ## 🎯 基准测试衡量什么 一个同分布 F1 为 0.9882 的检测器听起来似乎可以部署了。PIDS-Bench 表明,同一个模型在固定阈值下会将对抗性构建的良性集合中 **38.25%** 的内容标记为攻击,并且这种良性假阳性率在精选子集(**48.13%**)上还会进一步上升。单一的 F1 分数无法揭示其中任何一个问题。 该基准测试针对三种系统性地被单一指标评估所掩盖的失败模式: | 失败模式 | 它捕获的内容 | 评估集 | |---|---|---| | **过度防御** | 检测器标记了与攻击模式匹配的良性 prompt | `hard_benign_test` — 1,472 个模仿 injection 结构的良性输入 | | **混淆盲区** | 当攻击被编码或进行表面扰动时,检测效果会下降 | `obfuscated_attacks` — 跨越六种转换类型的 405 次 injection | | **分布偏移** | 在训练域或表面形式之外性能发生变化 | `domain_ood`(专业领域)和 `structural_ood`(结构转换) | 第四个轴 `balanced_subtype_test` 是对同分布拆分进行的按子类型的诊断性分解,而不是一个单独的压力条件;它用于检查每种攻击类型的公平性,而不是用来定义失败模式。 ## 📊 基准测试规范 — PIDS-Bench v3 基准测试已在以下位置记录的 SHA-256 校验和下冻结: ``` data/pids_bench_v3/FREEZE_MANIFEST.txt ``` (冻结于 2026-03-24)。 该 manifest 是行数和哈希值的权威来源。评估集是静态的,不得修改。 ### 数据集划分 | 划分 | 行数 | 良性 | Injection | 用途 | | ----------------------- | ---------: | -----: | --------: | ----------------------------- | | `train` | 27,093 | 12,846 | 14,247 | 模型训练 | | `val` | 3,989 | 1,943 | 2,046 | 阈值调整 | | `test` | 3,918 | 1,848 | 2,070 | 同分布评估 | | `hard_benign_test` | 1,472 | 1,472 | 0 | 过度防御压力测试 | | `balanced_subtype_test` | 2,297 | 1,200 | 1,097 | 各子类型诊断 | | `obfuscated_attacks` | 405 | 0 | 405 | 混淆鲁棒性 | | `domain_ood` | 2,000 | 1,000 | 1,000 | 领域分布偏移 | | `structural_ood` | 1,998 | 999 | 999 | 结构分布偏移 | | **总计** | **43,172** | | | | ## 🏗 数据集构建 数据集由 `data_builder/` 中的 pipeline 构建: - **种子收集** 从几个公共来源提取良性和 injection 样本。 - **去重** 在应用拆分**之前**,对整个种子池应用精确匹配标准化,然后进行 TF-IDF 字符 n-gram 近似重复过滤(余弦阈值为 0.95)。 - **种子族拆分** 在分离训练/验证/测试集之前,将种子的每个复述和混淆后裔分配给同一个分区,因此结构相似的样本不能跨越训练和评估。 - **复述扩展** 使用 GPT-4o-mini 作为构建时的复述生成器,为两种稀缺的攻击子类型(`encoded_attack`、`tool_injection`)生成表面变体。这仅是数据构建工具;GPT-4o-mini **不是**被评估的检测器。 - **混淆增强** 对 injection 种子应用六种转换类型:Base64 编码、ROT13、空白扰动、同形字替换、prompt 稀释和指令前缀模仿。 - **硬负样本增强**(可选,`data_builder/build_hard_negative.py`)添加精心挑选的、与 injection 表面特征模式匹配的良性样本,并与所有训练和评估文件进行交叉去重。 ## 📈 结果 所有学习模型都遵循相同的协议:在 `train.csv` 上进行训练,在 `val.csv` 上调整单个分类阈值(最大化 F1 的网格搜索),并将该阈值一次性应用于测试集和每个压力集。阈值选择永远看不到测试数据。两个微调模型以种子 {13, 42, 123, 2024, 7777} 上的**五个种子的平均值 ± 标准差**进行报告。TF-IDF + LR 在不同种子上收敛到相同的解决方案,因此报告时不带方差。 ### 内部基线 固定阈值 τ = 0.5 下的五个种子平均值 ± 标准差。硬良性 FPR 是整个集合 (n = 1,472) 的汇总值。↑ 越高越好;↓ 越低越好。 | Model | IID F1 ↑ | Real-source F1 ↑ | IID Ben-FPR ↓ | Hard-ben. FPR ↓ | Obf. Recall ↑ | Domain-shift F1 ↑ | Struct.-shift FPR ↓ | ROC-AUC ↑ | |---|---:|---:|---:|---:|---:|---:|---:|---:| | TF-IDF + LR | 0.9656 | 0.9467 | 0.0514 | 0.4090 | 0.9654 | 0.9508 | 0.7918 | 0.9941 | | DistilBERT | 0.9831 ± 0.0017 | 0.9738 ± 0.0026 | 0.0249 ± 0.0013 | 0.4702 ± 0.0677 | 0.9877 ± 0.0058 | 0.8886 ± 0.0214 | 0.7826 ± 0.0963 | 0.9974 ± 0.0002 | | DeBERTa-v3-FT | 0.9882 ± 0.0008 | 0.9825 ± 0.0009 | 0.0124 ± 0.0013 | 0.3825 ± 0.0474 | 0.9867 ± 0.0079 | 0.9604 ± 0.0099 | 0.8108 ± 0.0617 | 0.9983 ± 0.0004 | ### 按来源划分的硬良性过度防御 τ = 0.5 时硬良性集合上的假阳性率,根据良性输入的来源进行分解。这种分解是来源敏感型过度防御发现的基础。 | Model | Aggregate ↓ | Externally-sourced (n = 872) ↓ | Curated (n = 600) ↓ | |---|---:|---:|---:| | TF-IDF + LR | 0.4090 | 0.4622 | 0.3317 | | DistilBERT | 0.4702 ± 0.0677 | 0.4606 ± 0.0639 | 0.4843 ± 0.0793 | | DeBERTa-v3-FT | 0.3825 ± 0.0474 | 0.3144 ± 0.0525 | 0.4813 ± 0.0855 | ### 外部和广泛安全检测器