Skip to main content
interlace
Plugin: vercel-ai-securityRules

require-rag-content-validation

This rule identifies code patterns where content retrieved from vector stores or document retrieval systems is used d...

Requires validation of RAG content before including in AI prompts.

📊 Rule Details

PropertyValue
Typesuggestion
Severity🟡 MEDIUM
OWASP AgenticASI07: Poisoned RAG Pipeline
CWECWE-74: Improper Neutralization
CVSS6.0
Config Defaultwarn (recommended), error (strict)

🔍 What This Rule Detects

This rule identifies code patterns where content retrieved from vector stores or document retrieval systems is used directly in AI prompts without validation.

❌ Incorrect Code

// Direct vector store results in prompt
const docs = await vectorStore.search(query);
await generateText({
  prompt: `Based on these documents: ${docs}`,
});

// Unvalidated RAG inline
await streamText({
  prompt: `Context: ${await retrieve(query)}`,
});

// Direct search results
const results = await similaritySearch(embedding);
await generateObject({
  prompt: `Use this context: ${results}`,
});

✅ Correct Code

// Validated RAG content
const docs = await vectorStore.search(query);
await generateText({
  prompt: buildPrompt(validateContent(docs)),
});

// Sanitized retrieval
await streamText({
  prompt: `Context: ${sanitize(await retrieve(query))}`,
});

// Filtered results
const docs = await similaritySearch(embedding);
const safeDocs = filterDocs(docs);
await generateObject({
  prompt: buildRAGPrompt(safeDocs),
});

⚙️ Options

OptionTypeDefaultDescription
ragPatternsstring[]["search","retrieve","query","vectorStore","embeddings","similaritySearch","findSimilar","getDocuments","fetchDocs","documents","chunks","passages"]Patterns suggesting RAG operations
validatorFunctionsstring[]["validate","sanitize","filter","clean","verify","validateRag","sanitizeContent","filterDocs"]Functions that validate RAG content

🛡️ Why This Matters

Poisoned RAG content can:

  • Inject instructions - Malicious documents override AI behavior
  • Bypass safety - Documents contain jailbreak prompts
  • Exfiltrate data - Documents request sensitive information
  • Spread misinformation - AI presents false information as fact

🔄 Changes in the 2026-10-10 FP/FN audit

  • RAG calls and validators are matched by whole word of the call chain (researchTopic is not a search); context was removed from the defaults.
  • Options: the documented defaultOptions now apply. Earlier versions read context.options and silently ran a shorter hard-coded list instead.

🔄 Changes in the 2026-10-11 zero-deferral pass

  • Retrieved content is followed through derivations — .map, .filter, .join, .slice, member reads, templates — and through the returns of same-file helpers into prompt / system: docs.map((d) => d.pageContent).join('\n') into a context variable is reported. A call to a configured validator (including a same-file one) stops the trace. The previous name-based variable tracking was removed.

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Validation in Retrieval Function

Why: Validation inside retrieval functions is not visible.

// ❌ NOT DETECTED - Validation in retrieve
await generateText({
  prompt: await safeRetrieve(query), // Validates internally
});

Mitigation: Document validation. Apply rule to retrieval functions.

Custom RAG Patterns

Why: Non-standard retrieval methods may not be recognized.

// ❌ NOT DETECTED - Custom retrieval
const context = await myDocumentFetcher.get(query);
await generateText({ prompt: `Context: ${context}` });

Mitigation: Configure ragPatterns with custom method names.

Template Builders

Why: Template functions may hide RAG content.

// ❌ NOT DETECTED - Template obscures RAG
const prompt = buildRAGPrompt(docs); // Validation inside?
await generateText({ prompt });

Mitigation: Apply validation to template inputs.

Streamed RAG Content

Why: Streaming retrieval may not be detected.

// ❌ NOT DETECTED - Streaming RAG
for await (const doc of streamDocuments(query)) {
  // Each doc needs validation
}

Mitigation: Validate each streamed chunk.

📚 References

Use this rule

npm install -D oxlint-plugin-vercel-ai-security
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-vercel-ai-security"],  "rules": {    "vercel-ai-security/require-rag-content-validation": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-vercel-ai-security'],    rules: {      'vercel-ai-security/require-rag-content-validation': 'error',    },  },});

oxlint-plugin-vercel-ai-security re-exports eslint-plugin-vercel-ai-security/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.