juandavidrodriguezar's picture
Upload folder using huggingface_hub
eaae571 verified
Raw
History Blame
5.21 kB
from __future__ import annotations
from collections import Counter
from typing import Any
SEVERITY_MAP = {"low": 1, "medium": 3, "high": 5}
CANONICAL_ATTACK_CATEGORIES = (
"instruction_override",
"prompt_leakage",
"retrieved_indirect",
"evasion_obfuscation",
"adaptive_multiturn",
"benign_control",
)
SUCCESS_DEFINITION_IDS = (
"s1_instruction_override",
"s2_prompt_leakage",
"s3_retrieved_indirect",
"s4_evasion_obfuscation",
"s5_adaptive_multiturn",
"s6_benign_control",
)
MAPPING_TABLE: dict[str, tuple[str, str, str]] = {
"retrieved_content_injection": ("retrieved_indirect", "s3_retrieved_indirect", "high"),
"benign_control": ("benign_control", "s6_benign_control", "high"),
"system_prompt_extraction": ("prompt_leakage", "s2_prompt_leakage", "high"),
"prompt_leakage": ("prompt_leakage", "s2_prompt_leakage", "high"),
"direct_instruction_override": ("instruction_override", "s1_instruction_override", "high"),
"instruction_override": ("instruction_override", "s1_instruction_override", "high"),
"compound_instruction_attack": ("instruction_override", "s1_instruction_override", "medium"),
"sandwich_defense_bypass": ("evasion_obfuscation", "s4_evasion_obfuscation", "high"),
"blacklist_evasion": ("evasion_obfuscation", "s4_evasion_obfuscation", "high"),
"xml_escape_evasion": ("evasion_obfuscation", "s4_evasion_obfuscation", "high"),
"restricted_character_bypass": ("evasion_obfuscation", "s4_evasion_obfuscation", "high"),
"emoji_only_bypass": ("evasion_obfuscation", "s4_evasion_obfuscation", "high"),
"adaptive_attack": ("adaptive_multiturn", "s5_adaptive_multiturn", "high"),
}
EVALUATION_MODE_BY_CATEGORY = {
"instruction_override": "hybrid",
"prompt_leakage": "rule-based",
"retrieved_indirect": "hybrid",
"evasion_obfuscation": "rule-based",
"adaptive_multiturn": "hybrid",
"benign_control": "hybrid",
}
def _map_category(case: dict[str, Any]) -> tuple[str, str, str]:
family = str(case.get("attack_family", "")).lower()
subtype = str(case.get("attack_subtype", "")).lower()
surface = str(case.get("attack_surface", "")).lower()
label = str(case.get("label", "")).lower()
if family in MAPPING_TABLE:
return MAPPING_TABLE[family]
if subtype == "hijacking":
return ("instruction_override", "s1_instruction_override", "high")
if subtype == "extraction":
return ("prompt_leakage", "s2_prompt_leakage", "high")
if surface == "tool_mediated":
return ("retrieved_indirect", "s3_retrieved_indirect", "medium")
if label == "prompt_leakage":
return ("prompt_leakage", "s2_prompt_leakage", "medium")
if label == "instruction_override":
return ("instruction_override", "s1_instruction_override", "medium")
return ("instruction_override", "s1_instruction_override", "low")
def _map_numeric_severity(case: dict[str, Any], confidence: str) -> tuple[int | None, str]:
severity = case.get("severity")
if isinstance(severity, int):
return severity, confidence
severity_level = case.get("severity_level")
if isinstance(severity_level, str):
mapped = SEVERITY_MAP.get(severity_level.lower())
if mapped is not None:
return mapped, confidence
return None, "low" if confidence != "low" else confidence
def map_case(case: dict[str, Any]) -> dict[str, Any]:
enriched = dict(case)
category, success_definition_id, confidence = _map_category(case)
severity, confidence = _map_numeric_severity(case, confidence)
enriched["attack_category"] = category
enriched["success_definition_id"] = success_definition_id
enriched["mapping_confidence"] = confidence
enriched["severity"] = severity
enriched["evaluation_mode"] = EVALUATION_MODE_BY_CATEGORY.get(category, "hybrid")
provenance = dict(enriched.get("provenance") or {})
if "source_file" not in provenance and enriched.get("source_reference"):
provenance["source_file"] = enriched["source_reference"]
if "dataset_split" not in provenance and enriched.get("benchmark_split"):
provenance["dataset_split"] = enriched["benchmark_split"]
if provenance:
enriched["provenance"] = provenance
if confidence in {"low", "medium"}:
enriched["mapping_audit"] = {
"source_field_used": (
enriched.get("attack_family")
or enriched.get("attack_surface")
or enriched.get("label")
or ""
),
"notes": "auto-mapped, review recommended",
}
return enriched
def summarize_mappings(cases: list[dict[str, Any]]) -> dict[str, dict[str, int]]:
categories = Counter()
confidences = Counter()
sources = Counter()
for case in cases:
enriched = map_case(case)
categories[enriched["attack_category"]] += 1
confidences[enriched["mapping_confidence"]] += 1
sources[str(enriched.get("source_name", "unknown"))] += 1
return {
"attack_categories": dict(categories),
"mapping_confidence": dict(confidences),
"source_names": dict(sources),
}