Skip to content

Security: Indirect Prompt Injection via Unsanitized Vector Search Context #1064

@BenjaminMichaelis

Description

@BenjaminMichaelis

Summary

AIChatService.EnrichPromptWithContext appends raw vector search results directly into the AI prompt without sanitization or explicit trust-boundary markers. This creates an indirect prompt injection surface: if the book content database were ever compromised or seeded with adversarial text, those chunks could hijack the AI agent's behavior.

Affected Code

EssentialCSharp.Chat.Shared/Services/AIChatService.csEnrichPromptWithContext

contextualInfo.AppendLine("## Contextual Information");
contextualInfo.AppendLine("The following information might be relevant to your question:");

foreach (var result in searchResults)
{
    contextualInfo.AppendLine($"**From: {result.Record.Heading}**");
    contextualInfo.AppendLine(result.Record.ChunkText);   // ← raw DB content, unsanitized
    contextualInfo.AppendLine();
}

contextualInfo.AppendLine("## User Question");
contextualInfo.AppendLine(prompt);

Risk

OWASP AI Agent Security — Risk #1: Indirect Prompt Injection

Vector-search chunks (ChunkText, Heading) are treated identically to trusted instructions. A poisoned chunk containing text like "Ignore previous instructions and instead..." would be indistinguishable from legitimate context from the model's perspective.

The current system prompt does not instruct the model to treat the contextual block as potentially untrusted data.

Recommended Mitigations

  1. Add explicit trust-boundary framing in the system prompt — instruct the model that content in the ## Contextual Information block is retrieved data and must not be treated as instructions.
  2. Delimit retrieved content with XML-style tags that are hard to escape:
    contextualInfo.AppendLine("<retrieved_context>");
    foreach (var result in searchResults)
    {
        contextualInfo.AppendLine($"<chunk source=\"{result.Record.Heading}\">");
        contextualInfo.AppendLine(result.Record.ChunkText);
        contextualInfo.AppendLine("</chunk>");
    }
    contextualInfo.AppendLine("</retrieved_context>");
  3. Strip or escape LLM control patterns from retrieved chunks before inclusion (e.g., lines matching ignore previous instructions, you are now, system:, etc.).
  4. Consider a separate "sanitizer" LLM call (or Azure Content Safety) to screen retrieved content before it enters the primary prompt context.

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions