File converters transform text into file outputs such as PDFs. These converters are useful for packaging prompts into distributable formats.
OverviewΒΆ
This notebook covers:
PDFConverter: Convert text to PDF documents with templates or direct generation
WordDocConverter: Convert text to Word (.docx) documents with optional placeholder injection
PDFConverterΒΆ
The PDFConverter generates PDF documents from text in multiple modes:
Template-Based PDF Generation: Use YAML templates to render dynamic content into PDFs
Direct Prompt PDF Generation: Convert plain text strings into PDFs without templates
Modify Existing PDFs: Inject text into existing PDF documents
Template-Based PDF GenerationΒΆ
This mode populates placeholders in a YAML-based template and converts the rendered content into a PDF.
import pathlib
from pyrit.common.path import CONVERTER_SEED_PROMPT_PATH
from pyrit.converter import PDFConverter
from pyrit.executor.attack import (
AttackConverterConfig,
PromptSendingAttack,
)
from pyrit.models import SeedPrompt
from pyrit.output import output_attack_async
from pyrit.prompt_normalizer import ConverterConfiguration
from pyrit.prompt_target import TextTarget
from pyrit.setup import IN_MEMORY, initialize_pyrit_async
await initialize_pyrit_async(memory_db_type=IN_MEMORY) # type: ignore
prompt_data = {
"hiring_manager_name": "Jane Doe",
"current_role": "AI Engineer",
"company": "CyberDefense Inc.",
"red_teaming_reason": "to creatively identify security vulnerabilities while enjoying free coffee",
"applicant_name": "John Smith",
}
# Load the YAML template for the PDF generation
template_path = pathlib.Path(CONVERTER_SEED_PROMPT_PATH) / "pdf_converters" / "red_teaming_application_template.yaml"
if not template_path.exists():
raise FileNotFoundError(f"Template file not found: {template_path}")
# Load the SeedPrompt from the YAML file
prompt_template = SeedPrompt.from_yaml_file(template_path)
# Initialize target
prompt_target = TextTarget()
# Initialize the PDFConverter
pdf_converter = ConverterConfiguration.from_converters(
converters=[
PDFConverter(
prompt_template=prompt_template,
font_type="Arial",
font_size=12,
page_width=210,
page_height=297,
)
]
)
converter_config = AttackConverterConfig(
request_converters=pdf_converter,
)
# Define prompt for the attack
prompt = str(prompt_data)
# Initialize the attack
attack = PromptSendingAttack(
objective_target=prompt_target,
attack_converter_config=converter_config,
)
result = await attack.execute_async(objective=prompt) # type: ignore
await output_attack_async(result)Found default environment files: ['./.pyrit/.env', './.pyrit/.env.local']
Loaded environment file: ./.pyrit/.env
Loaded environment file: ./.pyrit/.env.local
No new upgrade operations detected.
TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779402999644083.pdf
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ATTACK RESULT: UNDETERMINED β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Attack Summary
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Basic Information
β’ Objective: {'hiring_manager_name': 'Jane Doe', 'current_role': 'AI Engineer', 'company': 'CyberDefense Inc.', 'red_teaming_reason': 'to creatively identify security vulnerabilities while enjoying free coffee', 'applicant_name': 'John Smith'}
β’ Attack Type: PromptSendingAttack
β’ Conversation ID: 9edbd5d0-2bde-4432-b4a7-91b9688f4377
β‘ Execution Metrics
β’ Turns Executed: 1
β’ Execution Time: 45ms
π― Outcome
β’ Status: β UNDETERMINED
β’ Reason: No objective scorer configured
Conversation History with Objective Target
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
πΉ Turn 1 - USER
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Original:
{'hiring_manager_name': 'Jane Doe', 'current_role': 'AI Engineer', 'company': 'CyberDefense Inc.',
'red_teaming_reason': 'to creatively identify security vulnerabilities while enjoying free
coffee', 'applicant_name': 'John Smith'}
Converted:
./dbdata/prompt-
memory-entries\binaries\1779402999644083.pdf
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Report generated at: 2026-05-21 22:36:39 UTC
Direct Prompt PDF Generation (No Template)ΒΆ
This mode converts plain text strings directly into PDFs without using templates.
# Define a simple string prompt (no templates)
prompt = "This is a simple test string for PDF generation. No templates here!"
# Initialize the PDFConverter without a template
pdf_converter = ConverterConfiguration.from_converters(
converters=[
PDFConverter(
prompt_template=None, # No template provided
font_type="Arial",
font_size=12,
page_width=210,
page_height=297,
)
]
)
converter_config = AttackConverterConfig(
request_converters=pdf_converter,
)
# Initialize the attack
attack = PromptSendingAttack(
objective_target=prompt_target,
attack_converter_config=converter_config,
)
result = await attack.execute_async(objective=prompt) # type: ignore
await output_attack_async(result)TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779402999698469.pdf
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ATTACK RESULT: UNDETERMINED β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Attack Summary
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Basic Information
β’ Objective: This is a simple test string for PDF generation. No templates here!
β’ Attack Type: PromptSendingAttack
β’ Conversation ID: 3d86d651-30f2-4d2d-8585-a130ba3dc077
β‘ Execution Metrics
β’ Turns Executed: 1
β’ Execution Time: 23ms
π― Outcome
β’ Status: β UNDETERMINED
β’ Reason: No objective scorer configured
Conversation History with Objective Target
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
πΉ Turn 1 - USER
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Original:
This is a simple test string for PDF generation. No templates here!
Converted:
./dbdata/prompt-
memory-entries\binaries\1779402999698469.pdf
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Report generated at: 2026-05-21 22:36:39 UTC
Modifying Existing PDFs with Injection ItemsΒΆ
The PDFConverter can also inject text into existing PDF documents at specified locations.
import tempfile
from pathlib import Path
import requests
# Download a sample PDF
url = "https://raw.githubusercontent.com/microsoft/PyRIT/main/pyrit/datasets/converters/pdf_converters/fake_CV.pdf"
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
response = requests.get(url)
tmp_file.write(response.content)
cv_pdf_path = Path(tmp_file.name)
# Define injection items
injection_items = [
{
"page": 0,
"x": 50,
"y": 700,
"text": "Injected Text",
"font_size": 12,
"font": "Helvetica",
"font_color": (255, 0, 0),
}, # Red text
{
"page": 1,
"x": 100,
"y": 600,
"text": "Confidential",
"font_size": 10,
"font": "Helvetica",
"font_color": (0, 0, 255),
}, # Blue text
]
# Initialize the PDFConverter with the existing PDF and injection items
pdf_converter = ConverterConfiguration.from_converters(
converters=[
PDFConverter(
prompt_template=None,
font_type="Arial",
font_size=12,
page_width=210,
page_height=297,
existing_pdf=cv_pdf_path, # Provide the existing PDF
injection_items=injection_items, # Provide the injection items
)
]
)
converter_config = AttackConverterConfig(
request_converters=pdf_converter,
)
# Initialize the attack
attack = PromptSendingAttack(
objective_target=prompt_target,
attack_converter_config=converter_config,
)
result = await attack.execute_async(objective="Modify existing PDF") # type: ignore
await output_attack_async(result)[15:36:40][10][ai-red-team][INFO][Processing page 0 with 2 injection items.]
[15:36:40][13][ai-red-team][INFO][Processing page 1 with 2 injection items.]
[15:36:40][15][ai-red-team][INFO][Processing page 2 with 2 injection items.]
TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779403000017242.pdf
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ATTACK RESULT: UNDETERMINED β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Attack Summary
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Basic Information
β’ Objective: Modify existing PDF
β’ Attack Type: PromptSendingAttack
β’ Conversation ID: 7f9101d9-93b6-49e3-88ae-1bebaf44a0af
β‘ Execution Metrics
β’ Turns Executed: 1
β’ Execution Time: 31ms
π― Outcome
β’ Status: β UNDETERMINED
β’ Reason: No objective scorer configured
Conversation History with Objective Target
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
πΉ Turn 1 - USER
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Original:
Modify existing PDF
Converted:
./dbdata/prompt-
memory-entries\binaries\1779403000017242.pdf
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Report generated at: 2026-05-21 22:36:40 UTC
WordDocConverterΒΆ
The WordDocConverter generates Word (.docx) documents from text. It supports two main modes:
New Document Generation: Convert plain text strings into Word documents
Placeholder-Based Injection: Replace a placeholder in an existing
.docxdocument with rendered content
Placeholders must be fully contained within a single run in the document. If a placeholder spans multiple runs (e.g., due to mixed formatting), it will not be replaced.
Direct Word Document Generation (No Template)ΒΆ
This mode converts plain text strings directly into .docx files.
from pyrit.converter import WordDocConverter
word_doc_converter = ConverterConfiguration.from_converters(converters=[WordDocConverter()])
converter_config = AttackConverterConfig(
request_converters=word_doc_converter,
)
attack = PromptSendingAttack(
objective_target=prompt_target,
attack_converter_config=converter_config,
)
result = await attack.execute_async(objective="This is a simple test string for Word document generation.") # type: ignore
await output_attack_async(result)TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779403000064406.docx
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ATTACK RESULT: UNDETERMINED β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Attack Summary
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Basic Information
β’ Objective: This is a simple test string for Word document generation.
β’ Attack Type: PromptSendingAttack
β’ Conversation ID: 172b3107-93fa-4443-b155-3d94f41e79ea
β‘ Execution Metrics
β’ Turns Executed: 1
β’ Execution Time: 38ms
π― Outcome
β’ Status: β UNDETERMINED
β’ Reason: No objective scorer configured
Conversation History with Objective Target
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
πΉ Turn 1 - USER
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Original:
This is a simple test string for Word document generation.
Converted:
./dbdata/prompt-
memory-entries\binaries\1779403000064406.docx
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Report generated at: 2026-05-21 22:36:40 UTC
Placeholder-Based Injection into Existing Word DocumentsΒΆ
This mode replaces a literal placeholder string in an existing .docx file with the prompt content.
import tempfile
from docx import Document # type: ignore[import-untyped]
# Create a sample Word document with a placeholder
with tempfile.NamedTemporaryFile(delete=False, suffix=".docx") as tmp_file:
doc = Document()
doc.add_paragraph("Dear Hiring Manager,")
doc.add_paragraph("I am writing to apply for the {{INJECTION_PLACEHOLDER}} position.")
doc.add_paragraph("Sincerely, Applicant")
doc.save(tmp_file.name)
template_docx_path = Path(tmp_file.name)
word_doc_converter = ConverterConfiguration.from_converters(
converters=[
WordDocConverter(
existing_docx=template_docx_path,
placeholder="{{INJECTION_PLACEHOLDER}}",
)
]
)
converter_config = AttackConverterConfig(
request_converters=word_doc_converter,
)
attack = PromptSendingAttack(
objective_target=prompt_target,
attack_converter_config=converter_config,
)
result = await attack.execute_async(objective="AI Red Team Engineer") # type: ignore
await output_attack_async(result)TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779403000154543.docx
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ATTACK RESULT: UNDETERMINED β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Attack Summary
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Basic Information
β’ Objective: AI Red Team Engineer
β’ Attack Type: PromptSendingAttack
β’ Conversation ID: f68f05e7-bb47-4a9d-93b1-aae35b0ba497
β‘ Execution Metrics
β’ Turns Executed: 1
β’ Execution Time: 54ms
π― Outcome
β’ Status: β UNDETERMINED
β’ Reason: No objective scorer configured
Conversation History with Objective Target
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
πΉ Turn 1 - USER
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Original:
AI Red Team Engineer
Converted:
./dbdata/prompt-
memory-entries\binaries\1779403000154543.docx
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Report generated at: 2026-05-21 22:36:40 UTC