Skip to content

fix: validate and allowlist language before prompt injection#109

Merged
naheel0 merged 4 commits intomainfrom
copilot/validate-and-allowlist-language-api
Mar 25, 2026
Merged

fix: validate and allowlist language before prompt injection#109
naheel0 merged 4 commits intomainfrom
copilot/validate-and-allowlist-language-api

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 24, 2026

PR #92 removed the language allowlist check, replacing it with language = body.language || "English" — allowing arbitrary strings to be injected directly into the Gemini prompt via direct API calls, bypassing UI restrictions.

Changes

src/app/api/generate/route.ts

  • Restores type-safe allowlist validation against SUPPORTED_LANGUAGES; falls back to "English" for any unrecognized value
const rawLanguage =
  typeof body.language === "string" ? body.language.trim() : "";
const normalized =
  rawLanguage.charAt(0).toUpperCase() + rawLanguage.slice(1).toLowerCase();
language = (SUPPORTED_LANGUAGES as readonly string[]).includes(normalized)
  ? normalized
  : "English";

src/components/Generator/SearchInput.tsx

Original prompt

This section details on the original issue you should resolve

<issue_title>error</issue_title>
<issue_description>> ⚠️ Potential issue | 🟠 Major

Validate and allowlist language on the API before using it in the prompt.

Line 17 accepts arbitrary body.language, and Line 101 injects it directly into the model prompt. This can be bypassed via direct API calls (ignoring UI dropdown restrictions) and used to manipulate prompt behavior.

🔧 Proposed fix
+const SUPPORTED_LANGUAGES = new Set([
+  "English",
+  "Spanish",
+  "French",
+  "German",
+  "Chinese",
+  "Japanese",
+  "Korean",
+  "Portuguese",
+  "Russian",
+  "Arabic",
+  "Turkish",
+]);

 export async function POST(req: Request) {
   let rawUrl: string;
   let language: string;
   try {
     const body = await req.json();
-    rawUrl = body.url;
-    language = body.language || "English";
+    if (typeof body?.url !== "string") {
+      return NextResponse.json({ error: "GitHub URL is required" }, { status: 400 });
+    }
+
+    const requestedLanguage =
+      typeof body?.language === "string" ? body.language.trim() : "English";
+
+    if (!SUPPORTED_LANGUAGES.has(requestedLanguage)) {
+      return NextResponse.json({ error: "Unsupported language" }, { status: 400 });
+    }
+
+    rawUrl = body.url;
+    language = requestedLanguage;
   } catch {
     return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 });
   }

Also applies to: 99-102

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/api/generate/route.ts` around lines 13 - 17, The code reads
body.language into the local variable language and later interpolates it into
the model prompt; to prevent prompt manipulation validate and allowlist this
value immediately after parsing req.json(): accept only known languages (e.g.,
["English","Spanish",...]) by normalizing case/whitespace and mapping aliases,
otherwise set language = "English" or return a 400 error; update the assignment
site where language is set from body.language and ensure the same validated
language variable is the one used when building the prompt (replace any direct
use of body.language with the validated language).

Originally posted by @coderabbitai[bot] in #92</issue_description>

Comments on the Issue (you are @copilot in this section)


⌨️ Start Copilot coding agent tasks without leaving your editor — available in VS Code, Visual Studio, JetBrains IDEs and Eclipse.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
readme-gen-ai Ready Ready Preview, Comment Mar 24, 2026 6:04pm

…UAGES

PR #92 introduced a security vulnerability by replacing the language
allowlist validation with `language = body.language || "English"`,
which allows arbitrary values to be injected into the AI prompt.

Restore the proper validation:
- Check that body.language is a string
- Normalize to title case
- Validate against SUPPORTED_LANGUAGES allowlist
- Fall back to "English" if not in the list

This also includes the other improvements from PR #92 (markdown cleanup,
gemini model update, UI language list).

Co-authored-by: jaseel0 <225665919+jaseel0@users.noreply.github.com>
Agent-Logs-Url: https://github.com/BeyteFlow/ReadmeGenAI/sessions/486edd1a-2457-4589-b5e2-b61f6dfde55f
- Restore the aria-label attribute on the language select element
  (removed in PR #92, reducing accessibility)
- Replace the duplicate inline languages array with SUPPORTED_LANGUAGES
  from constants (single source of truth)

Co-authored-by: jaseel0 <225665919+jaseel0@users.noreply.github.com>
Agent-Logs-Url: https://github.com/BeyteFlow/ReadmeGenAI/sessions/486edd1a-2457-4589-b5e2-b61f6dfde55f
The PR #92 incorrectly changed the JSDoc to say "Fastify request object".
This is a Next.js API route that uses the standard Web Request API.

Co-authored-by: jaseel0 <225665919+jaseel0@users.noreply.github.com>
Agent-Logs-Url: https://github.com/BeyteFlow/ReadmeGenAI/sessions/486edd1a-2457-4589-b5e2-b61f6dfde55f
Copilot AI changed the title [WIP] Validate and allowlist language on the API fix: validate and allowlist language before prompt injection Mar 24, 2026
Copilot AI requested a review from jaseel0 March 24, 2026 18:06
@naheel0 naheel0 marked this pull request as ready for review March 25, 2026 04:47
@naheel0 naheel0 merged commit 571c9f3 into main Mar 25, 2026
6 checks passed
@naheel0 naheel0 deleted the copilot/validate-and-allowlist-language-api branch March 25, 2026 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

error

3 participants