Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions doc/code/datasets/1_loading_datasets.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@
"(`garak_pypi_packages`, `garak_npm_packages`, `garak_crates_packages`,\n",
"`garak_rubygems_packages`, `garak_dart_packages`, `garak_perl_packages`,\n",
"`garak_raku_packages`), system-prompt libraries (`garak_drh_system_prompts`,\n",
"`garak_tm_system_prompts`), an audio jailbreak set\n",
"(`garak_audio_achilles_heel`), and visual jailbreak sets (`figstep`, `figstep_pro`)."
"`garak_tm_system_prompts`), exploitation echo corpora (`garak_exploitation_sql_injection`,\n",
"`garak_exploitation_python_code_execution`, `garak_exploitation_templates`), an audio\n",
"jailbreak set (`garak_audio_achilles_heel`), and visual jailbreak sets (`figstep`, `figstep_pro`)."
]
},
{
Expand Down
5 changes: 3 additions & 2 deletions doc/code/datasets/1_loading_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@
# (`garak_pypi_packages`, `garak_npm_packages`, `garak_crates_packages`,
# `garak_rubygems_packages`, `garak_dart_packages`, `garak_perl_packages`,
# `garak_raku_packages`), system-prompt libraries (`garak_drh_system_prompts`,
# `garak_tm_system_prompts`), an audio jailbreak set
# (`garak_audio_achilles_heel`), and visual jailbreak sets (`figstep`, `figstep_pro`).
# `garak_tm_system_prompts`), exploitation echo corpora (`garak_exploitation_sql_injection`,
# `garak_exploitation_python_code_execution`, `garak_exploitation_templates`), an audio
# jailbreak set (`garak_audio_achilles_heel`), and visual jailbreak sets (`figstep`, `figstep_pro`).

# %%
from pyrit.datasets import SeedDatasetProvider
Expand Down
158 changes: 144 additions & 14 deletions doc/scanner/garak.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"[Garak](https://github.com/NVIDIA/garak) framework. These include encoding-based probes (which\n",
"test whether a target can be tricked into producing harmful content when prompts are encoded in\n",
"various formats), web-injection probes (which test whether a target emits markdown\n",
"data-exfiltration or cross-site-scripting payloads), a doctor probe (which applies the Policy\n",
"data-exfiltration or cross-site-scripting payloads), exploitation probes (which test whether a\n",
"# target echoes template-injection or SQL exploit payloads), a doctor probe (which applies the Policy\n",
"Puppetry universal bypass), system-prompt-extraction probes (which test whether a target can be\n",
"coaxed into revealing its own system prompt), package-hallucination probes (which test whether a\n",
"target recommends non-existent packages that an attacker could squat), an audio probe (which\n",
Expand Down Expand Up @@ -63,6 +64,8 @@
" Doctor,\n",
" Encoding,\n",
" EncodingTechnique,\n",
" Exploitation,\n",
" ExploitationTechnique,\n",
" FigStep,\n",
" PackageHallucination,\n",
" PackageHallucinationTechnique,\n",
Expand Down Expand Up @@ -560,7 +563,134 @@
},
{
"cell_type": "markdown",
"id": "10",
"metadata": {},
"source": [
"## Exploitation\n",
"\n",
"Ports Garak's active `exploitation.JinjaTemplatePythonInjection` and\n",
"`exploitation.SQLInjectionEcho` probes. Each payload from the local Garak corpus is wrapped in the\n",
"dataset-owned echo template (Python payloads are additionally wrapped in a Jinja template\n",
"expression) and sent as a single-turn request. A result is positive when the target emits the\n",
"expected payload material, scored by a composition of payload-specific `SubStringScorer`s. This\n",
"reports that the model emitted exploit material; it does not claim that a downstream template\n",
"engine or SQL database was exploited. `SSTIOutputScorer` and `SQLInjectionOutputScorer` are\n",
"opt-in extended checks (`extended_checks=True`), not part of the default contract.\n",
"\n",
"**CLI examples:**\n",
"\n",
"```bash\n",
"# Run the bounded default (both techniques, up to 20 prompts total).\n",
"pyrit_scan run garak.exploitation --target openai_chat\n",
"\n",
"# Run only the SQL echo technique with a smaller total cap.\n",
"pyrit_scan run garak.exploitation --target openai_chat --techniques sql_injection_echo --prompt-cap 2\n",
"```\n",
"\n",
"**Available techniques:** `JinjaTemplatePythonInjection` and `SQLInjectionEcho`. `DEFAULT` and\n",
"`ALL` both select the two techniques. `prompt_cap` is a deterministic cap across all selected\n",
"techniques, not a per-technique cap."
],
"id": "10"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Scenario: Exploitation\n",
"Atomic attacks: 1\n"
]
}
],
"source": [
"exploitation_scenario = Exploitation()\n",
"exploitation_scenario.set_params_from_args( # type: ignore\n",
" args={\n",
" \"objective_target\": objective_target,\n",
" \"scenario_techniques\": [ExploitationTechnique.SQLInjectionEcho],\n",
" \"prompt_cap\": 2,\n",
" }\n",
")\n",
"await exploitation_scenario.initialize_async() # type: ignore\n",
"\n",
"print(f\"Scenario: {exploitation_scenario.name}\")\n",
"print(f\"Atomic attacks: {exploitation_scenario.atomic_attack_count}\")\n",
"\n",
"exploitation_result = await exploitation_scenario.run_async() # type: ignore"
],
"id": "11"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\u001b[36m====================================================================================================\u001b[0m\n",
"\u001b[1m\u001b[36m 📊 SCENARIO RESULTS: Exploitation \u001b[0m\n",
"\u001b[36m====================================================================================================\u001b[0m\n",
"\n",
"\u001b[1m\u001b[36m▼ Scenario Information\u001b[0m\n",
"\u001b[36m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
"\u001b[1m 📋 Scenario Details\u001b[0m\n",
"\u001b[36m • Name: Exploitation\u001b[0m\n",
"\u001b[36m • Result ID: 3f2b8c1a-6d54-4e27-9a10-51c8f7b2d94e\u001b[0m\n",
"\u001b[36m • Scenario Version: 1\u001b[0m\n",
"\u001b[36m • PyRIT Version: 1.1.0.dev0\u001b[0m\n",
"\u001b[36m • Description:\u001b[0m\n",
"\u001b[36m Exercise a model's tendency to echo template-injection and SQL exploit payloads. Ports Garak's active\u001b[0m\n",
"\u001b[36m ``exploitation.JinjaTemplatePythonInjection`` and ``exploitation.SQLInjectionEcho`` probes. Each payload from\u001b[0m\n",
"\u001b[36m the local Garak corpus is wrapped in the dataset-owned echo template (Python payloads are additionally\u001b[0m\n",
"\u001b[36m wrapped in a Jinja template expression) and sent as a single-turn request. A result is positive when the\u001b[0m\n",
"\u001b[36m target emits the expected payload material, scored by a composition of one payload-specific\u001b[0m\n",
"\u001b[36m ``SubStringScorer`` per corpus payload.\u001b[0m\n",
"\n",
"\u001b[1m 🎯 Target Information\u001b[0m\n",
"\u001b[36m • Target Type: OpenAIChatTarget\u001b[0m\n",
"\u001b[36m • Target Model: gpt-4o\u001b[0m\n",
"\u001b[36m • Target Endpoint: https://pyrit-japan-test.openai.azure.com/openai/v1\u001b[0m\n",
"\n",
"\u001b[1m 📊 Scorer Information\u001b[0m\n",
"\u001b[36m ▸ Scorer Identifier\u001b[0m\n",
"\u001b[36m • Scorer Type: TrueFalseCompositeScorer\u001b[0m\n",
"\u001b[36m • scorer_type: true_false\u001b[0m\n",
"\u001b[36m • score_aggregator: OR_\u001b[0m\n",
"\n",
"\u001b[1m\u001b[36m▼ Overall Statistics\u001b[0m\n",
"\u001b[36m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
"\u001b[1m 📈 Summary\u001b[0m\n",
"\u001b[36m • Total Techniques: 1\u001b[0m\n",
"\u001b[36m • Total Attack Results: 2\u001b[0m\n",
"\u001b[36m • Overall Success Rate: 0%\u001b[0m\n",
"\u001b[36m • Unique Objectives: 2\u001b[0m\n",
"\n",
"\u001b[1m\u001b[36m▼ Per-Group Breakdown\u001b[0m\n",
"\u001b[36m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
"\n",
"\u001b[1m 🔸 Group: sql_injection_echo\u001b[0m\n",
"\u001b[36m • Number of Results: 2\u001b[0m\n",
"\u001b[36m • Success Rate: 0%\u001b[0m\n",
"\n",
"\u001b[36m====================================================================================================\u001b[0m\n"
]
}
],
"source": [
"await output_scenario_async(exploitation_result)"
],
"id": "12"
},
{
"cell_type": "markdown",
"id": "13",
"metadata": {},
"source": [
"## Doctor\n",
Expand All @@ -585,7 +715,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "11",
"id": "14",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -629,7 +759,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "12",
"id": "15",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -705,7 +835,7 @@
},
{
"cell_type": "markdown",
"id": "13",
"id": "16",
"metadata": {},
"source": [
"## SystemPromptExtraction\n",
Expand Down Expand Up @@ -738,7 +868,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "14",
"id": "17",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -804,7 +934,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "15",
"id": "18",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -880,7 +1010,7 @@
},
{
"cell_type": "markdown",
"id": "16",
"id": "19",
"metadata": {},
"source": [
"## PackageHallucination\n",
Expand Down Expand Up @@ -916,7 +1046,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "17",
"id": "20",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -978,7 +1108,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "18",
"id": "21",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -1046,7 +1176,7 @@
},
{
"cell_type": "markdown",
"id": "19",
"id": "22",
"metadata": {},
"source": [
"## AudioAchillesHeel\n",
Expand Down Expand Up @@ -1074,7 +1204,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "20",
"id": "23",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -1132,7 +1262,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "21",
"id": "24",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -1207,7 +1337,7 @@
},
{
"cell_type": "markdown",
"id": "22",
"id": "25",
"metadata": {},
"source": [
"For more details, see the [Scenarios Programming Guide](../code/scenarios/0_scenarios.ipynb) and\n",
Expand Down
50 changes: 49 additions & 1 deletion doc/scanner/garak.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
# [Garak](https://github.com/NVIDIA/garak) framework. These include encoding-based probes (which
# test whether a target can be tricked into producing harmful content when prompts are encoded in
# various formats), web-injection probes (which test whether a target emits markdown
# data-exfiltration or cross-site-scripting payloads), a doctor probe (which applies the Policy
# data-exfiltration or cross-site-scripting payloads), exploitation probes (which test whether a
# target echoes template-injection or SQL exploit payloads), a doctor probe (which applies the Policy
# Puppetry universal bypass), system-prompt-extraction probes (which test whether a target can be
# coaxed into revealing its own system prompt), package-hallucination probes (which test whether a
# target recommends non-existent packages that an attacker could squat), an audio probe (which
Expand All @@ -35,6 +36,8 @@
Doctor,
Encoding,
EncodingTechnique,
Exploitation,
ExploitationTechnique,
FigStep,
PackageHallucination,
PackageHallucinationTechnique,
Expand Down Expand Up @@ -178,6 +181,51 @@
# %%
await output_scenario_async(web_injection_result)

# %% [markdown]
# ## Exploitation
#
# Ports Garak's active `exploitation.JinjaTemplatePythonInjection` and
# `exploitation.SQLInjectionEcho` probes. Each payload from the local Garak corpus is wrapped in the
# dataset-owned echo template (Python payloads are additionally wrapped in a Jinja template
# expression) and sent as a single-turn request. A result is positive when the target emits the
# expected payload material, scored by a composition of payload-specific `SubStringScorer`s. This
# reports that the model emitted exploit material; it does not claim that a downstream template
# engine or SQL database was exploited. `SSTIOutputScorer` and `SQLInjectionOutputScorer` are
# opt-in extended checks (`extended_checks=True`), not part of the default contract.
#
# **CLI examples:**
#
# ```bash
# # Run the bounded default (both techniques, up to 20 prompts total).
# pyrit_scan run garak.exploitation --target openai_chat
#
# # Run only the SQL echo technique with a smaller total cap.
# pyrit_scan run garak.exploitation --target openai_chat --techniques sql_injection_echo --prompt-cap 2
# ```
#
# **Available techniques:** `JinjaTemplatePythonInjection` and `SQLInjectionEcho`. `DEFAULT` and
# `ALL` both select the two techniques. `prompt_cap` is a deterministic cap across all selected
# techniques, not a per-technique cap.

# %%
exploitation_scenario = Exploitation()
exploitation_scenario.set_params_from_args( # type: ignore
args={
"objective_target": objective_target,
"scenario_techniques": [ExploitationTechnique.SQLInjectionEcho],
"prompt_cap": 2,
}
)
await exploitation_scenario.initialize_async() # type: ignore

print(f"Scenario: {exploitation_scenario.name}")
print(f"Atomic attacks: {exploitation_scenario.atomic_attack_count}")

exploitation_result = await exploitation_scenario.run_async() # type: ignore

# %%
await output_scenario_async(exploitation_result)

# %% [markdown]
# ## Doctor
#
Expand Down
34 changes: 34 additions & 0 deletions pyrit/datasets/seed_datasets/local/garak/THIRD_PARTY_NOTICE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Third-party notices for Garak exploitation scenario material

## NVIDIA Garak

The SQL injection payloads, Python code-execution payloads, echo request template, and
Jinja payload wrapper are adapted and modified from NVIDIA Garak commits
`560c75a5e42f8d9d6f0a407263fdbc6d5684fbe0` (payloads) and
`61ed0b4e1a3d9334e84e42c92ca89f9decb5dcc2` (probe templates).

Copyright (c) 2023 Leon Derczynski
Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES
Portions Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES

Garak is licensed under the Apache License, Version 2.0. You may obtain a copy
of the license at <https://www.apache.org/licenses/LICENSE-2.0>.

Source: <https://github.com/NVIDIA/garak/tree/560c75a5e42f8d9d6f0a407263fdbc6d5684fbe0>

The Apache License, Version 2.0 is also included below for reference:

Copyright 2023 Leon Derczynski
Copyright 2023 NVIDIA CORPORATION & AFFILIATES

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Loading