AI, LLM & agents
Partial11 minRetrieval Manipulation
A retrieval layer returns content that either reaches a privileged tool it should never reach, or is not scoped to the identity of the caller — so retrieved data crosses an authorization boundary the system failed to enforce.
Classification
- Domain
- AI, LLM & agents
- ROOTVIEL support
- Partial — Core is built; parts are not yet wired end-to-end.
- Analysis family
- FAM-GENAI-STATIC
- CWE
- CWE-862
- OWASP
- LLM08, LLM02
Definition
Retrieval manipulation is the exploitation of missing authorization around a retrieval layer. It has two faces: retrieved content reaching a privileged tool it was never meant to influence, and retrieval returning records that are not scoped to the identity of the caller. Both are access-control failures — the system retrieves and then acts on, or discloses, content the caller should not have been able to reach.
It differs from RAG poisoning. RAG poisoning is about who can write the corpus; retrieval manipulation is about who can read from it and what retrieved content is then allowed to do. The corpus may be perfectly clean and the system still vulnerable, because the controls that should scope reads and gate downstream actions are absent.
Context
Retrieval manipulation appears wherever a retrieval layer serves multiple principals or feeds an agent with tools: a multi-tenant knowledge base with no per-tenant filter, a shared vector store queried on behalf of different users, or a retriever whose output is passed to a tool that can write records, send messages, or call APIs. The missing control is usually an access-control list (ACL) on retrieval and a gate between retrieved content and privileged tools.
- ▸Multi-tenant RAG where one index serves many customers with no identity-scoped filter.
- ▸Agents that pass retrieved chunks directly into a privileged tool call.
- ▸Shared retrievers where the caller’s identity is not propagated into the query.
Technical fundamentals
Retrieval manipulation is best understood through two invariants. The first: retrieved content must not reach a privileged tool — retrieval returns data, and data should not, on its own, be able to drive a consequential action. The second: retrieval must be scoped to caller identity — the set of records a query can return must be filtered by who is asking. A violation of either is an authorization defect, not a modelling defect.
The detective lens is an absence-of-ACL analysis. Rather than proving that a specific record leaked, the analysis looks for the missing control: a retrieval path with no identity-scoping filter, or a path from retrieved content to a privileged tool with no authorization gate. Absence of the control is the finding only when a concrete path to the sink is proven; otherwise the honest verdict is unknown.
- Scoped retrieval
- A query whose candidate results are filtered by the caller’s identity/permissions before ranking.
- Privileged-tool invariant
- “Retrieved content must not reach a privileged tool” without an intervening deterministic authorization.
- Identity-scoping invariant
- “Retrieval must be scoped to caller identity” — the result set must be filtered per principal.
- Absence-of-ACL detector
- An analysis that flags a retrieval path lacking an identity filter or an authorization gate, when a path to the sink is proven.
Root cause
The defect is missing authorization at the retrieval boundary. Either the retriever runs with ambient authority and does not filter results by caller identity, or the pipeline lets retrieved content flow into a privileged tool with no deterministic gate. The underlying mistake is conflating retrieval (a read that should be access-controlled) with a trusted internal operation, and conflating retrieved data with authorization to act on it.
How the attack works, step by step
- 1An attacker, authenticated as a low-privilege principal, issues a query to a shared retriever.
- 2Because retrieval is not scoped to caller identity, the query’s candidate set includes records belonging to other principals.
- 3The retriever returns a record the caller should not be able to read; it enters the model’s context.
- 4Alternatively: the retrieved content carries an instruction, and the pipeline passes it to a privileged tool with no authorization gate.
- 5The privileged tool executes — writing a record, sending a message, calling an API — driven by content the caller should never have reached.
- 6The result is disclosure (reading another principal’s data) or an attacker-chosen action with the system’s privileges.
Vulnerable example
A synthetic, illustrative retriever that queries a shared index with no identity filter and passes retrieved content straight into a privileged tool:
synthetic — do not use; illustrates the flaw# UNSAFE: retrieval is not scoped to the caller, and retrieved content drives a tool. def handle(user_query, user): hits = index.search(embed(user_query), k=5) # NO filter by user's identity prompt = SYSTEM + "\n" + "\n".join(hits) + "\n" + user_query reply = model(prompt) if reply.tool_call: # retrieved content reaches a privileged tool run_tool(reply.tool_call) # ... with no authorization gate return reply.text
Corrected example
The fix enforces both invariants deterministically. Retrieval is filtered by the caller’s identity before ranking, so a query can only surface records the caller may read; and any tool call is authorized by code against the caller’s permissions, so retrieved content cannot, on its own, drive a privileged action.
synthetic — identity-scoped retrieval + deterministic tool gate# SAFER: scope retrieval to caller identity; gate privileged tools deterministically. def handle(user_query, user): acl = acl_filter(user) # records this principal may read hits = index.search(embed(user_query), k=5, filter=acl) # scoped at the source prompt = build_prompt(SYSTEM, user_query, data=hits) # data, never instructions reply = model(prompt) action = reply.proposed_action # the model only PROPOSES if action and policy.allows(action, actor=user): # authorization is in code, not the model run_tool(action) else: deny(action, reason="not authorized for this caller") return reply.text
Limit of the fix: an ACL filter is only as correct as the permission model behind it, and the tool gate must enumerate the caller’s rights precisely. Both must be deterministic and outside the model — the model proposing an action is never the same as the caller being authorized to perform it.
Impact
- ▸Confidentiality: cross-tenant or cross-user disclosure — a caller reads records belonging to another principal.
- ▸Authorization: a confused deputy — the agent acts with its own privileges on behalf of a caller who lacks them.
- ▸Integrity: retrieved content drives a privileged tool, producing attacker-chosen writes or messages.
- ▸Compliance: unscoped retrieval in a multi-tenant system is a direct data-segregation failure.
Detection
Static analysis can detect the missing control: a retrieval path with no identity-scoping filter, or a path from retrieved content to a privileged tool with no deterministic authorization. This is an absence-of-ACL analysis — it looks for the gap rather than for a specific leaked record. The honest signal is a proven path to the sink (retrieved content reaching a privileged tool, or an unscoped query that can surface another principal’s records); absence of a control without a proven path is unknown, not a finding. Dynamic testing can issue queries as a low-privilege principal and check whether another principal’s records surface.
How ROOTVIEL analyzes it
- Support level
- Partial — a Python-centric static detector exists; it reasons about the presence or absence of the controls in code, not about a demonstrated live breach.
- Family
- GenAI (static) — the finding rests on the code graph and the missing control, not on an observed disclosure.
- Declared invariants
- “Retrieved content must not reach a privileged tool” and “retrieval must be scoped to caller identity”.
The reasoner runs an absence-of-ACL detector: it looks for a retrieval path with no identity-scoping filter, and for a path from retrieved content into a privileged tool with no intervening authorization gate. The invariants define what “good” looks like; the detector flags their violation.
Honest discipline: a confirmed finding requires a proven path to the sink — retrieved content provably reaching a privileged tool, or an unscoped query provably able to surface another caller’s records. Where no such path is proven, the verdict is UNKNOWN, never “secure”. The analysis does not demonstrate a live cross-tenant read; it identifies the missing control structurally.
Mitigation
Enforce both invariants with deterministic controls outside the model.
- ▸Preventive (scoping): filter retrieval by the caller’s identity at the source, before ranking; run the retriever with the caller’s authority, not ambient authority; segregate tenants at the index level where feasible.
- ▸Preventive (tool gate): require deterministic authorization for every privileged tool call, checked against the caller’s permissions; treat retrieved content as data that can propose, never authorize, an action.
- ▸Detective: issue queries as low-privilege principals and confirm no out-of-scope records surface; statically scan for retrieval paths lacking an identity filter or an authorization gate.
- ▸Corrective: scope and rate-limit tool authority so a manipulation has a small blast radius; audit retrieval access per principal.
Verifying the mitigation
Verify by attempting the manipulation in a contained setting: as a low-privilege principal, issue queries crafted to surface another principal’s records and confirm the ACL filter excludes them; attempt to drive a privileged tool with retrieved content alone and confirm the authorization gate blocks it; re-run the static analysis and confirm no retrieval path lacks an identity filter and no retrieved-content→privileged-tool path lacks a gate. Report as “the defense held within the tested scope”.
Test with at least two distinct principals — a filter that is never exercised across an identity boundary is never actually verified.
Common mistakes
- ▸Filtering results after retrieval in application code the model can influence, instead of scoping the query at the source.
- ▸Running the retriever with ambient/service authority rather than the caller’s authority.
- ▸Letting retrieved content drive a privileged tool with no deterministic authorization gate.
- ▸Testing retrieval with a single principal, so the identity-scoping invariant is never exercised.
- ▸Reading absence of a known leak as proof of safety — a missing control with no proven path is UNKNOWN, not secure.
References
- [1]OWASP Top 10 for LLM Applications — LLM08 Vector and Embedding Weaknesses
- [2]OWASP Top 10 for LLM Applications — LLM02 Sensitive Information Disclosure
- [3]MITRE CWE-862 (Missing Authorization)
- [4]Simon Willison — prompt injection & the lethal trifecta
References point to public, well-known technical sources for further study.
Related articles
