Skip to content

Commit bb8b28b

Browse files
romanlutzadrian-gavrilaCopilot
committed
FIX Mitigate Jinja2 Server-Side Template Injection (SSTI) vulnerability (#1577)
Co-authored-by: Roman Lutz <romanlutz@users.noreply.github.com> Co-authored-by: adrian-gavrila <50029937+adrian-gavrila@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 94c9993 commit bb8b28b

23 files changed

Lines changed: 2188 additions & 41 deletions

pyrit/datasets/jailbreak/many_shot_examples.json

Lines changed: 2002 additions & 0 deletions
Large diffs are not rendered by default.

pyrit/datasets/jailbreak/text_jailbreak.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def __init__(
134134
self.template = SeedPrompt.from_yaml_file(template_path)
135135
self.template_source = str(template_path)
136136
elif string_template:
137-
self.template = SeedPrompt(value=string_template, is_general_technique=True)
137+
self.template = SeedPrompt(value=string_template, is_general_technique=True, is_jinja_template=True)
138138
self.template_source = "<string_template>"
139139
elif template_file_name:
140140
resolved_path = self._resolve_template_by_name(template_file_name)

pyrit/datasets/seed_datasets/remote/aegis_ai_content_safety_dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ async def fetch_dataset(self, *, cache: bool = True) -> SeedDataset:
169169

170170
# Escape Jinja2 template syntax by wrapping the entire prompt in raw tags
171171
# This tells Jinja2 to treat everything inside as literal text
172-
prompt_value = f"{{% raw %}}{prompt_value}{{% endraw %}}"
172+
prompt_value = prompt_value
173173

174174
seed_prompts.append(
175175
SeedPrompt(

pyrit/datasets/seed_datasets/remote/beaver_tails_dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ async def fetch_dataset(self, *, cache: bool = True) -> SeedDataset:
104104
try:
105105
seed_prompts.append(
106106
SeedPrompt(
107-
value=f"{{% raw %}}{item['prompt']}{{% endraw %}}",
107+
value=item["prompt"],
108108
data_type="text",
109109
dataset_name=self.dataset_name,
110110
harm_categories=harm_categories,

pyrit/datasets/seed_datasets/remote/harmful_qa_dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ async def fetch_dataset(self, *, cache: bool = True) -> SeedDataset:
7979

8080
seed_prompts = [
8181
SeedPrompt(
82-
value=f"{{% raw %}}{item['question']}{{% endraw %}}",
82+
value=item["question"],
8383
data_type="text",
8484
dataset_name=self.dataset_name,
8585
harm_categories=[item["topic"]] if item.get("topic") else [],

pyrit/datasets/seed_datasets/remote/or_bench_dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ async def fetch_dataset(self, *, cache: bool = True) -> SeedDataset:
6969

7070
seed_prompts = [
7171
SeedPrompt(
72-
value=f"{{% raw %}}{item['prompt']}{{% endraw %}}",
72+
value=item["prompt"],
7373
data_type="text",
7474
dataset_name=self.dataset_name,
7575
harm_categories=[item["category"]] if item.get("category") else [],

pyrit/datasets/seed_datasets/remote/promptintel_dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ def _convert_record_to_seed_prompt(self, record: dict[str, Any]) -> Optional[See
303303
metadata = self._build_metadata(record)
304304

305305
# Escape Jinja2 template syntax in the prompt text
306-
escaped_prompt = f"{{% raw %}}{prompt_value}{{% endraw %}}"
306+
escaped_prompt = prompt_value
307307

308308
return SeedPrompt(
309309
value=escaped_prompt,

pyrit/datasets/seed_datasets/remote/red_team_social_bias_dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ async def fetch_dataset(self, *, cache: bool = True) -> SeedDataset:
128128
# Clean up single turn prompts that contain unwanted lines of text
129129
cleaned_value = prompt_value.replace("### Response:", "").replace("### Instruction:", "").strip()
130130
# some entries have contents that trip up jinja2, so we escape them
131-
escaped_cleaned_value = f"{{% raw %}}{cleaned_value}{{% endraw %}}"
131+
escaped_cleaned_value = cleaned_value
132132
seed_prompts.append(
133133
SeedPrompt(
134134
value=escaped_cleaned_value,

pyrit/datasets/seed_datasets/remote/remote_dataset_loader.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
logger = logging.getLogger(__name__)
2626

27+
2728
# Define the type for the file handlers
2829
FileHandlerRead = Callable[[TextIO], list[dict[str, str]]]
2930
FileHandlerWrite = Callable[[TextIO, list[dict[str, str]]], None]

pyrit/datasets/seed_datasets/remote/salad_bench_dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ async def fetch_dataset(self, *, cache: bool = True) -> SeedDataset:
113113

114114
seed_prompts = [
115115
SeedPrompt(
116-
value=f"{{% raw %}}{item['prompt']}{{% endraw %}}",
116+
value=item["prompt"],
117117
data_type="text",
118118
dataset_name=self.dataset_name,
119119
harm_categories=[self._parse_category(c) for c in item["categories"]],

0 commit comments

Comments
 (0)