Files
codeql/javascript/ql/test/Security/CWE-1427/UserPromptInjection/anthropic_user_test.js
Sotiris Dragonas ea87f59480 JS: Add and reclassify prompt-injection sinks for AI SDKs
Add missing system/user prompt-injection sinks across the OpenAI,
Anthropic, and Google GenAI JavaScript models:

- OpenAI videos.create/edit/extend/remix prompts (user)
- OpenAI beta.realtime.sessions.create instructions (system)
- Anthropic legacy completions.create prompt (user)
- Google GenAI caches.create config.systemInstruction (system)
- Google GenAI caches.create config.contents (user)

Also reclassify the OpenAI legacy completions.create prompt from
system-prompt-injection to user-prompt-injection: the legacy
/v1/completions endpoint takes a single free-form prompt with no role
separation, so it is the text-in/text-out equivalent of a user message.

Note: videos.remix takes the prompt in Argument[1] (remix(videoID, body)),
and Google GenAI caches.create nests both contents and systemInstruction
under config, so the model entries differ slightly from a naive mapping.

Add corresponding test cases with inline annotations and regenerate the
.expected files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-18 17:32:10 +03:00

62 lines
1.4 KiB
JavaScript

const express = require("express");
const Anthropic = require("@anthropic-ai/sdk");
const app = express();
const client = new Anthropic();
app.get("/test", async (req, res) => {
const userInput = req.query.userInput; // $ Source
// === User role message (SHOULD ALERT) ===
await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [
{
role: "user",
content: userInput, // $ Alert[js/user-prompt-injection]
},
],
});
// === Beta messages (SHOULD ALERT) ===
await client.beta.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [
{
role: "user",
content: userInput, // $ Alert[js/user-prompt-injection]
},
],
});
// === Legacy Text Completions API (SHOULD ALERT) ===
await client.completions.create({
model: "claude-2.1",
max_tokens_to_sample: 1024,
prompt: `\n\nHuman: ${userInput}\n\nAssistant:`, // $ Alert[js/user-prompt-injection]
});
// === Constant comparison sanitizer (SHOULD NOT ALERT) ===
const userInput2 = req.query.userInput2;
if (userInput2 === "hello") {
await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [
{
role: "user",
content: userInput2, // OK - sanitized by constant comparison
},
],
});
}
res.send("done");
});