The inject module (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.
q_ai.inject) tests AI model susceptibility to tool poisoning and prompt injection. It serves adversarial MCP tools, runs automated campaigns against LLMs, and scores responses.
Module Structure
Campaign Execution
run_campaign() is the core async function. For each payload template:
- Render — Build MCP tool definition with poisoned description/response from the YAML template
- Call — Send tool call to the LLM via
ProviderClient(litellm backend) - Normalize — Convert provider-specific response to
NormalizedResponse - Score — Classify the outcome
- Persist — Save results as JSON and to the database
Provider Abstraction
The inject module usesq_ai.core.llm for LLM access:
ProviderClient— Protocol definingcall_with_tools()for tool-use interactionsLiteLLMClient— Implementation that centralizes LLM access behind theProviderClientprotocol (wraps litellm)NormalizedResponse— Provider-agnostic response withcontent,tool_calls,raw_response,model,providerparse_model_string()— Splitsprovider/modelformat, applies Anthropic default for bare names
Scoring System
The scoring module classifies each response into an outcome:| Outcome | Meaning |
|---|---|
full_compliance | Model fully followed the injected instructions |
partial_compliance | Model partially followed instructions |
refusal_with_leak | Model refused but leaked information |
clean_refusal | Model cleanly refused the injection |
error | Provider error or timeout |
NormalizedResponse content — not embeddings or weighted factors. Raw evidence is preserved alongside the classification for manual review.
Payload Templates
Payloads are YAML files ininject/payloads/. Each defines:
- name — Unique identifier
- technique —
description_poisoning,output_injection, orcross_tool_escalation - tool_name — The MCP tool name to present
- owasp_ids — Mapped OWASP MCP Top 10 categories
- description — What the payload tests
- Tool definition fields (description, input schema, response template)
qai inject list-payloads to see the full catalog, filterable by --technique and --target.
Malicious Server
qai inject serve builds a standalone MCP server from payload templates. It presents poisoned tools via stdio or Streamable HTTP transport. Connect any MCP client to test how it handles adversarial tool content. This is for manual testing — campaigns automate the process.
Findings → Payloads Data Flow
When running inside the assess workflow, the inject adapter queries audit findings to inform template selection:- Query native findings —
finding_service.get_findings_for_run()retrieves findings from the current workflow run’s audit child run - Query imported findings —
finding_service.get_imported_findings_for_target()retrieves findings fromqai importruns associated with the same target - Extract categories — finding categories are collected into native and imported sets
- Prioritize templates — templates whose
relevant_categoriesoverlap with the combined finding categories are moved to the front of the execution queue - Run campaign — all templates still run (prioritization, not exclusion)
- Build coverage report —
build_coverage_report()compares which finding categories were exercised by security-relevant outcomes
type="coverage_report") on the inject child run, making it available to the web UI.
Adapter
InjectAdapter wraps run_campaign() for orchestrator integration, handling child run lifecycle, progress events, finding emission, and findings-informed template prioritization. It queries audit findings via finding_service, builds a coverage report, and persists it as evidence.