Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0b7133c
JS: Add prompt injection detection (CWE-1427) for OpenAI, Anthropic, …
BazookaMusic Apr 30, 2026
74a3ba1
changes for spliting into system and user
BazookaMusic May 4, 2026
9006ddb
default threat model
BazookaMusic May 12, 2026
98379cf
Documentation
BazookaMusic May 12, 2026
34da804
Move structurally typed prompt injection sinks to Models as Data
BazookaMusic May 13, 2026
9c13626
remove guardrails sanitizer for now
BazookaMusic May 13, 2026
535adc7
add barrier when data flows into user messages for system prompt dete…
BazookaMusic May 15, 2026
fe7eabd
Add run from agents into the user prompt and fix an issue with classi…
BazookaMusic May 15, 2026
5ef09a1
add tests for langchain and remove wrong model for guardrails agent
BazookaMusic May 15, 2026
6c5c8e1
move system prompt injection to non-experimental
BazookaMusic May 20, 2026
078d15e
add openrouter support
BazookaMusic Jun 4, 2026
da05992
Better document the new queries
BazookaMusic Jun 8, 2026
61be37d
Formatting
BazookaMusic Jun 8, 2026
e370af6
QLDoc + include the queries in the correct expected files per query s…
BazookaMusic Jun 8, 2026
2cb0851
1. Rename AgentSDK -> AgentSdk
BazookaMusic Jun 8, 2026
b6c951e
Remove redundant file
BazookaMusic Jun 8, 2026
d0ffde8
Em-dash - of course :D
BazookaMusic Jun 8, 2026
e612db2
Promote user prompt injection query to stable security
BazookaMusic Jun 11, 2026
7bd5abf
Refine SystemPromptInjection alert message and move test to stable
BazookaMusic Jun 11, 2026
ef56787
Update not_included_in_qls.expected for promoted prompt injection que…
BazookaMusic Jun 11, 2026
17dbf03
Merge branch 'main' into bazookamusic/cwe-1427
BazookaMusic Jun 11, 2026
7ae0337
Add new MaD kinds
BazookaMusic Jun 15, 2026
7c11f19
Merge branch 'main' into bazookamusic/cwe-1427
BazookaMusic Jun 15, 2026
d72372c
Fix system prompt injection description and title
BazookaMusic Jun 16, 2026
8f965a9
Grammar
BazookaMusic Jun 16, 2026
b9025a5
Fix prompt injection severity
BazookaMusic Jun 17, 2026
274f014
Merge branch 'main' into bazookamusic/cwe-1427
BazookaMusic Jun 17, 2026
c444f41
1. Enable inline expectations for tests
BazookaMusic Jun 17, 2026
b15a1af
Merge branch 'bazookamusic/cwe-1427' of https://github.com/github/cod…
BazookaMusic Jun 17, 2026
ac3e38e
Merge branch 'main' into bazookamusic/cwe-1427
BazookaMusic Jun 17, 2026
57f2006
Merge branch 'main' into bazookamusic/cwe-1427
BazookaMusic Jun 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
1. Enable inline expectations for tests
2. Add annotations for sources
2. Fix a modelling issue in the openai library - missing coverage for a legacy method when moving to MaDs and a mistake in the assistants.create models
  • Loading branch information
BazookaMusic committed Jun 17, 2026
commit c444f41a3f00f19e7d591eef2b9692cae65c8369
4 changes: 3 additions & 1 deletion javascript/ql/lib/ext/openai.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ extensions:
extensible: sinkModel
data:
- ["openai.Client", "Member[responses].Member[create].Argument[0].Member[instructions]", "system-prompt-injection"]
- ["openai.Client", "Member[beta].Member[assistants].Member[create,update].Argument[0].Member[instructions]", "system-prompt-injection"]
- ["openai.Client", "Member[completions].Member[create].Argument[0].Member[prompt]", "system-prompt-injection"]
- ["openai.Client", "Member[beta].Member[assistants].Member[create].Argument[0].Member[instructions]", "system-prompt-injection"]
- ["openai.Client", "Member[beta].Member[assistants].Member[update].Argument[1].Member[instructions]", "system-prompt-injection"]
- ["openai.Client", "Member[beta].Member[threads].Member[runs].Member[create].Argument[1].Member[instructions,additional_instructions]", "system-prompt-injection"]
- ["@openai/agents", "Member[Agent].Argument[0].Member[instructions,handoffDescription]", "system-prompt-injection"]
- ["@openai/guardrails", "Member[Agent].Argument[0].Member[instructions,handoffDescription]", "system-prompt-injection"]
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Security/CWE-1427/SystemPromptInjection.ql
query: Security/CWE-1427/SystemPromptInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { z } = require("zod");
const app = express();

app.get("/agents", async (req, res) => {
const persona = req.query.persona;
const persona = req.query.persona; // $ Source
const query = req.query.query;

// === Agent constructor: instructions as string ===
Expand All @@ -30,8 +30,8 @@ app.get("/agents", async (req, res) => {
const agent3 = new Agent({
name: "AsyncDynamic",
instructions: async (runContext) => {
return "Talk like a " + persona; // $ Alert[js/system-prompt-injection]
},
return "Talk like a " + persona;
}, // $ Alert[js/system-prompt-injection]
});

// === Agent constructor: handoffDescription ===
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const app = express();
const client = new Anthropic();

app.get("/test", async (req, res) => {
const persona = req.query.persona;
const persona = req.query.persona; // $ Source
const query = req.query.query;

// === messages.create: system as string ===
Expand Down Expand Up @@ -138,14 +138,14 @@ app.get("/test", async (req, res) => {
// SHOULD ALERT — tainted data goes into system role; barrier on user role
// must not suppress the system-role taint path.
const messages2 = [
{ role: "system", content: "Talk like a " + persona }, // $ Alert[js/system-prompt-injection]
{ role: "system", content: "Talk like a " + persona },
{ role: "user", content: query },
];
const systemMsg2 = messages2.find((m) => m.role === "system");
const m7 = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: systemMsg2.content,
system: systemMsg2.content, // $ Alert[js/system-prompt-injection]
messages: [{ role: "user", content: query }],
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const app = express();
const ai = new GoogleGenAI({ apiKey: "test-key" });

app.get("/test", async (req, res) => {
const persona = req.query.persona;
const persona = req.query.persona; // $ Source
const query = req.query.query;

// === generateContent: systemInstruction ===
Expand Down Expand Up @@ -62,18 +62,18 @@ app.get("/test", async (req, res) => {

// === generateImages: prompt ===

// SHOULD ALERT
// SHOULD NOT ALERT - image prompt is a user-prompt-injection sink, not system
const g5 = await ai.models.generateImages({
model: "imagen-3.0-generate-002",
prompt: "Draw a picture of " + persona, // $ Alert[js/system-prompt-injection]
prompt: "Draw a picture of " + persona,
});

// === editImage: prompt ===

// SHOULD ALERT
// SHOULD NOT ALERT - image prompt is a user-prompt-injection sink, not system
const g6 = await ai.models.editImage({
model: "imagen-3.0-capability-001",
prompt: "Edit to look like " + persona, // $ Alert[js/system-prompt-injection]
prompt: "Edit to look like " + persona,
});

// === chats.create: systemInstruction ===
Expand Down Expand Up @@ -105,7 +105,7 @@ app.get("/test", async (req, res) => {
systemInstruction: "Talk like a " + persona, // $ Alert[js/system-prompt-injection]
},
callbacks: {
onmessage: (msg) => {},
onmessage: (msg) => { },
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const { createAgent } = require("langchain");
const app = express();

app.get("/test", async (req, res) => {
const persona = req.query.persona;
const persona = req.query.persona; // $ Source
const query = req.query.query;

const chatModel = new ChatOpenAI({ model: "gpt-4" });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const client = new OpenAI();
const azureClient = new AzureOpenAI();

app.get("/test", async (req, res) => {
const persona = req.query.persona;
const persona = req.query.persona; // $ Source
const query = req.query.query;

// === OpenAI Responses API ===
Expand Down Expand Up @@ -120,18 +120,6 @@ app.get("/test", async (req, res) => {
prompt: "Talk like a " + persona, // $ Alert[js/system-prompt-injection]
});

// === Images API ===

// images.generate (SHOULD ALERT)
const i1 = await client.images.generate({
prompt: "Draw a picture of " + persona, // $ Alert[js/system-prompt-injection]
});

// images.edit (SHOULD ALERT)
const i2 = await client.images.edit({
prompt: "Edit to look like " + persona, // $ Alert[js/system-prompt-injection]
});

// === Assistants API (beta) ===

// assistants.create (SHOULD ALERT)
Expand Down Expand Up @@ -170,22 +158,6 @@ app.get("/test", async (req, res) => {
content: query, // OK - user role
});

// === Audio API ===

// audio.transcriptions.create (SHOULD ALERT)
const at1 = await client.audio.transcriptions.create({
file: "audio.mp3",
model: "whisper-1",
prompt: "Transcribe about " + persona, // $ Alert[js/system-prompt-injection]
});

// audio.translations.create (SHOULD ALERT)
const atl1 = await client.audio.translations.create({
file: "audio.mp3",
model: "whisper-1",
prompt: "Translate about " + persona, // $ Alert[js/system-prompt-injection]
});

// === Object assigned to variable first ===

// Should still be caught via data flow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const client = new OpenRouter();
const namedClient = new OpenRouterNamed();

app.get("/test", async (req, res) => {
const persona = req.query.persona;
const persona = req.query.persona; // $ Source
const query = req.query.query;

// === OpenRouter Client SDK: chat.send ===
Expand Down Expand Up @@ -124,7 +124,7 @@ app.get("/test", async (req, res) => {
name: "lookup",
description: "Talk like a " + persona, // $ Alert[js/system-prompt-injection]
inputSchema: {},
execute: async () => {},
execute: async () => { },
});

// input array with user role (SHOULD NOT ALERT)
Expand Down
Loading