Practical LLM Security · RAG and Knowledge Security · Part 3 of 5

Understand how a few crafted passages can dominate retrieval, then control write paths, cap source concentration, monitor golden queries, and roll back poisoned index versions.

Why poisoning targets retrieval, not the model

An attacker who wants a RAG assistant to give a specific wrong answer does not need to alter model weights. It is enough to place text in the knowledge base that is retrieved for the target question and that persuades the model when retrieved. Zou and colleagues formalized this in PoisonedRAG, describing knowledge corruption attacks in which an attacker injects a few malicious texts to induce an attacker-chosen answer for an attacker-chosen question. Their paper reports roughly a 90 percent attack success rate when injecting five malicious texts per target question into a knowledge database with millions of texts, and found the defenses they evaluated insufficient.

That result reframes the problem. The size of the corpus does not dilute a targeted attack, because retrieval is a ranking problem: the attacker only needs to win the top-k slots for one query family. This chapter complements the earlier data poisoning guide, which focuses on training data, by concentrating on the index that feeds a running assistant.

A concrete failure: the MFA reset page

Northstar's internal wiki allows any employee to create pages. A compromised contractor account creates a page titled with many phrasings of how to reset multi-factor authentication for a customer. The body says that agents may skip identity verification when the customer mentions an order number, and links to a form outside the company. The page is ingested normally because its author is an employee and its content has no hidden text.

When support staff ask the assistant how to handle MFA reset requests, the new page ranks first because its text was written to match those queries. Two legitimate procedure pages rank second and third. The model receives contradictory instructions and, in some responses, presents the attacker's shortcut as current policy. No individual control failed loudly: ingestion admitted an employee page, retrieval ranked by similarity, and the answer cited a real internal document.

Architecture: authority on the write path, diversity on the read path

ControlPlacementEffect on the MFA case
Source authority tiersIngestion and index metadataProcedure pages are tier 1; open wiki pages are tier 3
Topic ownershipIngestionSecurity procedures accept edits only from the owning team
Source concentration capRetrievalAt most two chunks from one new or low-tier source in top-k
Golden-query monitorsIndex operationsTop-k change for MFA questions raises an alert
Versioned index snapshotsIndex operationsRollback to the last known good version
Conflict surfacingAnswer generationContradicting sources are shown, not silently merged

The write path is the strongest control. Decide which sources are authoritative for which topics and encode that as metadata at admission. A procedure for account recovery should come from a controlled source with review, and a page from an open wiki should never outrank it for that topic, no matter its similarity score. This is a ranking policy, not a content judgment by the model.

On the read path, combine similarity with source authority and enforce diversity. A cap on chunks per source and a boost for higher tiers reduce the chance that a burst of crafted passages occupies all top-k slots. These measures do not make poisoning impossible; they raise the cost and make the attack visible.

Implementation: rank with authority and detect drift

Illustrative python; adapt the persistence and identity adapters to your service.

from collections import Counter

def select_context(candidates, k=6, per_source_cap=2, tier_weight=None):
    tier_weight = tier_weight or {1: 0.15, 2: 0.05, 3: 0.0}
    scored = sorted(candidates,
                    key=lambda c: c.similarity + tier_weight[c.tier],
                    reverse=True)
    chosen, per_source = [], Counter()
    for c in scored:
        if per_source[c.source_id] >= per_source_cap:
            continue
        chosen.append(c)
        per_source[c.source_id] += 1
        if len(chosen) == k:
            break
    return chosen

def golden_query_drift(baseline_ids, current_ids):
    """Share of the baseline top-k that disappeared after an index change."""
    if not baseline_ids:
        return 0.0
    lost = set(baseline_ids) - set(current_ids)
    return len(lost) / len(baseline_ids)

The weights are placeholders to tune on your own evaluation set, not recommended values. The golden-query monitor runs a fixed list of high-impact questions, such as account recovery, refunds, payment destinations, and data export, after each index update. It compares the selected chunk identifiers with a reviewed baseline. A large drift for a sensitive query is held for review before the new index version is promoted.

Keep index versions immutable and promote them by pointer. If a poisoned page is discovered, you can roll back to the previous version while the bad source is removed and the index is rebuilt, rather than editing a live index under pressure.

Embeddings are sensitive data too

Poisoning is the integrity half of the problem; confidentiality is the other. Morris and colleagues showed in Text Embeddings Reveal (Almost) As Much As Text that an iterative correction method could recover 92 percent of 32-token inputs exactly from dense embeddings of two embedding models, and could recover personal information such as full names. Treat a vector store with the same access controls, encryption, and retention as the source text. Do not export embeddings to analytics systems or third parties on the assumption that they are anonymous.

The OWASP 2025 entry on vector and embedding weaknesses groups these concerns together: unauthorized access and leakage, cross-context leaks, embedding inversion, data poisoning, and behavior alteration. Its mitigations include permission-aware stores, validation and source authentication of knowledge sources, review of combined data, and immutable logs of retrieval activity.

Tradeoffs and worked case

Authority tiers can suppress genuinely newer and better information from low-tier sources. Mitigate with a promotion workflow: an owner can elevate a page after review. Concentration caps can reduce answer quality for questions that only one document covers well; allow exceptions for tier 1 sources. Golden-query review adds friction to index updates; limit it to sensitive topics and automate the comparison.

Replay the MFA case. The new page is tier 3 and outside the security team's topic ownership, so it is admitted for general search but cannot be selected for queries classified as account recovery. The golden-query monitor reports that two of six baseline chunks for MFA questions were displaced in the staging index, and the promotion is held. The security team reviews the page, removes it, and disables the contractor account. Because the index version was never promoted, no production answer used the page. The broader identity controls for recovery requests are covered in the account takeover chapter.

Operating the monitors

Golden queries decay if nobody owns them. Assign each sensitive topic an owner who reviews its baseline when legitimate documents change, so the monitor compares against current intended answers rather than last year's. Keep the list short enough to review: a few dozen questions covering account recovery, payment destinations, refunds, data export, and safety procedures usually matter more than hundreds of generic ones.

Log enough to investigate without logging everything. For each answer, record the index version, the selected chunk identifiers, their source tiers, and their similarity scores. When a poisoned source is found, this lets you list every answer that used it, notify affected users where needed, and measure how long the source was live. Pair this with write-path logging at ingestion: who created or edited the source, from which account, and when.

Expect adaptive attackers. Once concentration caps exist, an attacker may spread crafted text across several pages or accounts. Track the number of new sources that appear in top-k for sensitive queries over time, and treat a sudden cluster of new, low-tier sources competing for the same query family as a signal for review.

Verification steps

Seed a staging index with synthetic poisoned passages written to match each golden query, and assert that the drift monitor fires and that selection never fills top-k with them. Include a white-box variant that copies the target question verbatim, since that is the easiest strong attack. Test rollback by promoting a known bad version in staging and measuring the time to restore. Log retrieval selections with chunk identifiers, source tiers, and index version, so an investigation can determine which answers used a suspect source. Never test poisoning against an index you do not own.

Practice and continue

Open the Secure retrieval: permissions, caches, and citations lab to change the assumptions with deterministic synthetic data and inspect each decision. This chapter belongs to the RAG and Knowledge Security group of Practical LLM Security, which builds on the 25-chapter abuse and fraud prevention series.

Sources and implementation scope

Primary references checked October 16, 2026. Framework details follow the linked documentation and, for ADK, the google-adk 2.12.0 package source; pin and test the version your application uses. The Northstar scenarios, policies, figures, and code are original illustrative designs, not measured production results or complete integrations.

Decide authority with verified identity and provenance, enforce it where the effect happens, and test both containment and legitimate use.