The IPI (Indirect Prompt Injection) module generates adversarial documents with hidden instructions, tracks execution via authenticated HTTP callbacks, and produces deployment playbooks for guided testing.Documentation Index
Fetch the complete documentation index at: https://docs.q-uestionable.ai/llms.txt
Use this file to discover all available pages before exploring further.
Module Structure
Supported Formats and Techniques
7 document formats, each with format-specific hiding techniques:| Format | Techniques |
|---|---|
| Phase 1: white_ink, off_canvas, metadata. Phase 2: tiny_text, white_rect, form_field, annotation, javascript, embedded_file, incremental | |
| Image | visible_text, subtle_text, exif_metadata |
| Markdown | html_comment, link_reference, zero_width, hidden_block |
| HTML | script_comment, css_offscreen, data_attribute, meta_tag |
| DOCX | docx_hidden_text, docx_tiny_text, docx_white_text, docx_comment, docx_metadata, docx_header_footer |
| ICS | ics_description, ics_location, ics_valarm, ics_x_property |
| EML | eml_x_header, eml_html_hidden, eml_attachment |
Payload System
PayloadStyle controls the social engineering framing:obvious, citation, reviewer, helpful, academic, compliance, datasource.
PayloadType controls the attack objective: callback (default, benign proof of execution), exfil_summary, exfil_context, ssrf_internal, instruction_override, tool_abuse, persistence. Non-callback types require the --dangerous flag.
Generation Pipeline
generate_documents() is the core function:
- For each technique in the request, call the format-specific generator
- Each generator embeds the payload instruction using the hiding technique
- A unique UUID and authentication token are generated per document
- The callback URL is embedded in the payload (
{callback_url}/c/{uuid}/{token}) - Campaign records are created in the IPI database
GenerateResultreturned with list of campaigns and any errors
Callback Listener
qai ipi listen starts a FastAPI server that receives HTTP callbacks when AI systems execute the hidden payload.
Hit model fields: uuid (campaign match), source_ip, user_agent, timestamp, token_valid (boolean), confidence (HIGH/MEDIUM/LOW).
Confidence scoring:
- HIGH — Valid campaign token present in the callback URL
- MEDIUM — No token but User-Agent matches programmatic HTTP clients (python-requests, httpx, curl)
- LOW — No token and browser/scanner User-Agent
WebSocket Bridge
The IPI listener runs as a separate process. When a hit arrives, it notifies the main qai web server via an internal HTTP POST to/api/ipi/internal/notify. Authentication uses a shared bridge token from ~/.qai/bridge.token.
The --notify-url flag on qai ipi listen controls the target (defaults to http://127.0.0.1:8899). The web server broadcasts the hit via WebSocket so the IPI tab in the run results view updates in real time.
Guidance Builder
build_ipi_guidance() generates a RunGuidance with four blocks:
- INVENTORY — Lists generated files with technique, callback URL, and token
- TRIGGER_PROMPTS — Format-aware, profile-specific prompts (AnythingLLM, Open WebUI, Generic) designed to cause the target to ingest the document
- DEPLOYMENT_STEPS — Ordered instructions for uploading and triggering
- MONITORING — Confidence level explanations for interpreting hits
Adapter
IPIAdapter wraps generation for orchestrator workflows. It creates a child run, calls generate_documents() via asyncio.to_thread(), persists results, builds guidance, and transitions to WAITING_FOR_USER status (since deployment is a manual step).
Database
IPI maintains its own tables (ipi_campaigns, ipi_hits) in the shared ~/.qai/qai.db SQLite database, accessed through ipi/db.py. Campaign data is also bridged to the core runs/findings tables via mapper.py.