Skip to content

Commit 7960c5c

Browse files
authored
Merge pull request #21953 from github/bazookamusic/cwe-1427
[Javascript] Prompt Injection queries
2 parents 1cb5be5 + 57f2006 commit 7960c5c

48 files changed

Lines changed: 3156 additions & 3 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

javascript/ql/integration-tests/query-suite/javascript-code-scanning.qls.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ ql/javascript/ql/src/Security/CWE-116/IncompleteMultiCharacterSanitization.ql
4141
ql/javascript/ql/src/Security/CWE-116/IncompleteSanitization.ql
4242
ql/javascript/ql/src/Security/CWE-116/UnsafeHtmlExpansion.ql
4343
ql/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql
44+
ql/javascript/ql/src/Security/CWE-1427/SystemPromptInjection.ql
4445
ql/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql
4546
ql/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql
4647
ql/javascript/ql/src/Security/CWE-201/PostMessageStar.ql

javascript/ql/integration-tests/query-suite/javascript-security-and-quality.qls.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ ql/javascript/ql/src/Security/CWE-116/UnsafeHtmlExpansion.ql
132132
ql/javascript/ql/src/Security/CWE-117/LogInjection.ql
133133
ql/javascript/ql/src/Security/CWE-1275/SameSiteNoneCookie.ql
134134
ql/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql
135+
ql/javascript/ql/src/Security/CWE-1427/SystemPromptInjection.ql
135136
ql/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql
136137
ql/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql
137138
ql/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql

javascript/ql/integration-tests/query-suite/javascript-security-extended.qls.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ ql/javascript/ql/src/Security/CWE-116/UnsafeHtmlExpansion.ql
4747
ql/javascript/ql/src/Security/CWE-117/LogInjection.ql
4848
ql/javascript/ql/src/Security/CWE-1275/SameSiteNoneCookie.ql
4949
ql/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql
50+
ql/javascript/ql/src/Security/CWE-1427/SystemPromptInjection.ql
5051
ql/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql
5152
ql/javascript/ql/src/Security/CWE-200/FileAccessToHttp.ql
5253
ql/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql

javascript/ql/integration-tests/query-suite/not_included_in_qls.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ ql/javascript/ql/src/Performance/NonLocalForIn.ql
4343
ql/javascript/ql/src/RegExp/MalformedRegExp.ql
4444
ql/javascript/ql/src/Security/CWE-020/ExternalAPIsUsedWithUntrustedData.ql
4545
ql/javascript/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql
46+
ql/javascript/ql/src/Security/CWE-1427/UserPromptInjection.ql
4647
ql/javascript/ql/src/Security/CWE-313/PasswordInConfigurationFile.ql
4748
ql/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.ql
4849
ql/javascript/ql/src/Security/CWE-798/HardcodedCredentials.ql
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: typeModel
5+
data:
6+
- ["anthropic.Client", "@anthropic-ai/sdk", "Instance"]
7+
8+
- addsTo:
9+
pack: codeql/javascript-all
10+
extensible: sinkModel
11+
data:
12+
- ["anthropic.Client", "Member[messages].Member[create].Argument[0].Member[system]", "system-prompt-injection"]
13+
- ["anthropic.Client", "Member[messages].Member[create].Argument[0].Member[system].ArrayElement.Member[text]", "system-prompt-injection"]
14+
- ["anthropic.Client", "Member[beta].Member[messages].Member[create].Argument[0].Member[system]", "system-prompt-injection"]
15+
- ["anthropic.Client", "Member[beta].Member[messages].Member[create].Argument[0].Member[system].ArrayElement.Member[text]", "system-prompt-injection"]
16+
- ["anthropic.Client", "Member[beta].Member[agents].Member[create].Argument[0].Member[system]", "system-prompt-injection"]
17+
- ["anthropic.Client", "Member[beta].Member[agents].Member[update].Argument[1].Member[system]", "system-prompt-injection"]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: typeModel
5+
data:
6+
- ["google-genai.Client", "@google/genai", "Member[GoogleGenAI].Instance"]
7+
8+
- addsTo:
9+
pack: codeql/javascript-all
10+
extensible: sinkModel
11+
data:
12+
- ["google-genai.Client", "Member[models].Member[generateContent,generateContentStream].Argument[0].Member[config].Member[systemInstruction]", "system-prompt-injection"]
13+
- ["google-genai.Client", "Member[chats].Member[create].Argument[0].Member[config].Member[systemInstruction]", "system-prompt-injection"]
14+
- ["google-genai.Client", "Member[chats].Member[create].ReturnValue.Member[sendMessage].Argument[0].Member[config].Member[systemInstruction]", "system-prompt-injection"]
15+
- ["google-genai.Client", "Member[live].Member[connect].Argument[0].Member[config].Member[systemInstruction]", "system-prompt-injection"]
16+
- ["google-genai.Client", "Member[models].Member[generateContent,generateContentStream].Argument[0].Member[contents]", "user-prompt-injection"]
17+
- ["google-genai.Client", "Member[models].Member[generateImages].Argument[0].Member[prompt]", "user-prompt-injection"]
18+
- ["google-genai.Client", "Member[models].Member[editImage].Argument[0].Member[prompt]", "user-prompt-injection"]
19+
- ["google-genai.Client", "Member[models].Member[generateVideos].Argument[0].Member[prompt]", "user-prompt-injection"]
20+
- ["google-genai.Client", "Member[chats].Member[create].ReturnValue.Member[sendMessage,sendMessageStream].Argument[0].Member[message]", "user-prompt-injection"]
21+
- ["google-genai.Client", "Member[chats].Member[create].ReturnValue.Member[sendMessage,sendMessageStream].Argument[0].Member[content]", "user-prompt-injection"]
22+
- ["google-genai.Client", "Member[interactions].Member[create].Argument[0].Member[input]", "user-prompt-injection"]
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: typeModel
5+
data:
6+
- ["langchain.ChatModel", "@langchain/openai", "Member[ChatOpenAI].Instance"]
7+
- ["langchain.ChatModel", "@langchain/anthropic", "Member[ChatAnthropic].Instance"]
8+
- ["langchain.ChatModel", "@langchain/google-genai", "Member[ChatGoogleGenerativeAI].Instance"]
9+
- ["langchain.ChatModel", "@langchain/mistralai", "Member[ChatMistralAI].Instance"]
10+
- ["langchain.ChatModel", "@langchain/groq", "Member[ChatGroq].Instance"]
11+
- ["langchain.ChatModel", "@langchain/cohere", "Member[ChatCohere].Instance"]
12+
- ["langchain.ChatModel", "@langchain/community/chat_models/fireworks", "Member[ChatFireworks].Instance"]
13+
- ["langchain.ChatModel", "@langchain/ollama", "Member[ChatOllama].Instance"]
14+
- ["langchain.ChatModel", "@langchain/aws", "Member[BedrockChat,ChatBedrockConverse].Instance"]
15+
- ["langchain.ChatModel", "@langchain/community/chat_models/togetherai", "Member[ChatTogetherAI].Instance"]
16+
- ["langchain.ChatModel", "@langchain/xai", "Member[ChatXAI].Instance"]
17+
- ["langchain.ChatModel", "@langchain/openrouter", "Member[ChatOpenRouter].Instance"]
18+
- ["langchain.ChatModel", "langchain", "Member[initChatModel].ReturnValue.Awaited"]
19+
- ["langchain.AgentExecutor", "langchain/agents", "Member[AgentExecutor].Instance"]
20+
- ["langchain.AgentExecutor", "langchain/agents", "Member[AgentExecutor].Member[fromAgentAndTools].ReturnValue"]
21+
- ["langchain.Agent", "langchain", "Member[createAgent].ReturnValue"]
22+
- ["langchain.LLMChain", "langchain/chains", "Member[LLMChain].Instance"]
23+
24+
- addsTo:
25+
pack: codeql/javascript-all
26+
extensible: sinkModel
27+
data:
28+
- ["@langchain/core/messages", "Member[HumanMessage].Argument[0]", "user-prompt-injection"]
29+
- ["@langchain/core/messages", "Member[HumanMessage].Argument[0].Member[content]", "user-prompt-injection"]
30+
- ["langchain", "Member[HumanMessage].Argument[0]", "user-prompt-injection"]
31+
- ["langchain", "Member[HumanMessage].Argument[0].Member[content]", "user-prompt-injection"]
32+
- ["@langchain/core/messages", "Member[SystemMessage].Argument[0]", "system-prompt-injection"]
33+
- ["@langchain/core/messages", "Member[SystemMessage].Argument[0].Member[content]", "system-prompt-injection"]
34+
- ["langchain", "Member[SystemMessage].Argument[0]", "system-prompt-injection"]
35+
- ["langchain", "Member[SystemMessage].Argument[0].Member[content]", "system-prompt-injection"]
36+
- ["langchain.ChatModel", "Member[invoke].Argument[0]", "user-prompt-injection"]
37+
- ["langchain.ChatModel", "Member[stream].Argument[0]", "user-prompt-injection"]
38+
- ["langchain.ChatModel", "Member[call].Argument[0]", "user-prompt-injection"]
39+
- ["langchain.ChatModel", "Member[predict].Argument[0]", "user-prompt-injection"]
40+
- ["langchain.ChatModel", "Member[batch].Argument[0].ArrayElement", "user-prompt-injection"]
41+
- ["langchain.ChatModel", "Member[generate].Argument[0].ArrayElement.ArrayElement", "user-prompt-injection"]
42+
- ["langchain.AgentExecutor", "Member[invoke].Argument[0].Member[input]", "user-prompt-injection"]
43+
- ["langchain.Agent", "Member[invoke].Argument[0].Member[messages].ArrayElement.Member[content]", "user-prompt-injection"]
44+
- ["langchain.Agent", "Member[stream].Argument[0].Member[messages].ArrayElement.Member[content]", "user-prompt-injection"]
45+
- ["langchain", "Member[createAgent].Argument[0].Member[systemPrompt]", "system-prompt-injection"]
46+
- ["langchain.LLMChain", "Member[call,invoke].Argument[0].Member[input]", "user-prompt-injection"]
47+
- ["@langchain/core/prompts", "Member[ChatPromptTemplate].Member[fromMessages].Argument[0].ArrayElement.ArrayElement", "user-prompt-injection"]
48+
- ["@langchain/core/prompts", "Member[PromptTemplate].Instance.Member[format].Argument[0]", "user-prompt-injection"]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: typeModel
5+
data:
6+
- ["openai.Client", "openai", "Instance"]
7+
- ["openai.Client", "openai", "Member[OpenAI,AzureOpenAI].Instance"]
8+
- ["openai.Client", "@openai/guardrails", "Member[GuardrailsOpenAI,GuardrailsAzureOpenAI].Member[create].ReturnValue.Awaited"]
9+
10+
- addsTo:
11+
pack: codeql/javascript-all
12+
extensible: sinkModel
13+
data:
14+
- ["openai.Client", "Member[responses].Member[create].Argument[0].Member[instructions]", "system-prompt-injection"]
15+
- ["openai.Client", "Member[completions].Member[create].Argument[0].Member[prompt]", "system-prompt-injection"]
16+
- ["openai.Client", "Member[beta].Member[assistants].Member[create].Argument[0].Member[instructions]", "system-prompt-injection"]
17+
- ["openai.Client", "Member[beta].Member[assistants].Member[update].Argument[1].Member[instructions]", "system-prompt-injection"]
18+
- ["openai.Client", "Member[beta].Member[threads].Member[runs].Member[create].Argument[1].Member[instructions,additional_instructions]", "system-prompt-injection"]
19+
- ["@openai/agents", "Member[Agent].Argument[0].Member[instructions,handoffDescription]", "system-prompt-injection"]
20+
- ["@openai/guardrails", "Member[Agent].Argument[0].Member[instructions,handoffDescription]", "system-prompt-injection"]
21+
- ["@openai/agents", "Member[Agent].Instance.Member[asTool].Argument[0].Member[toolDescription]", "system-prompt-injection"]
22+
- ["@openai/guardrails", "Member[Agent].Instance.Member[asTool].Argument[0].Member[toolDescription]", "system-prompt-injection"]
23+
- ["@openai/agents", "Member[tool].Argument[0].Member[description]", "system-prompt-injection"]
24+
- ["@openai/guardrails", "Member[tool].Argument[0].Member[description]", "system-prompt-injection"]
25+
- ["@openai/guardrails", "Member[GuardrailAgent].Member[create].Argument[2]", "system-prompt-injection"]
26+
- ["@openai/agents", "Member[run].Argument[1]", "user-prompt-injection"]
27+
- ["@openai/agents", "Member[Runner].Instance.Member[run].Argument[1]", "user-prompt-injection"]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: typeModel
5+
data:
6+
- ["openrouter.Client", "@openrouter/sdk", "Instance"]
7+
- ["openrouter.Client", "@openrouter/sdk", "Member[OpenRouter].Instance"]
8+
- ["openrouter.Agent", "@openrouter/agent", "Member[OpenRouter].Instance"]
9+
10+
- addsTo:
11+
pack: codeql/javascript-all
12+
extensible: sinkModel
13+
data:
14+
- ["@openrouter/agent", "Member[callModel].Argument[0].Member[instructions]", "system-prompt-injection"]
15+
- ["openrouter.Agent", "Member[callModel].Argument[0].Member[instructions]", "system-prompt-injection"]
16+
- ["@openrouter/agent", "Member[tool].Argument[0].Member[description]", "system-prompt-injection"]
17+
- ["openrouter.Client", "Member[embeddings].Member[create].Argument[0].Member[input]", "user-prompt-injection"]
18+
- ["@openrouter/agent", "Member[callModel].Argument[0].Member[input]", "user-prompt-injection"]
19+
- ["openrouter.Agent", "Member[callModel].Argument[0].Member[input]", "user-prompt-injection"]

javascript/ql/lib/semmle/javascript/Concepts.qll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,28 @@ module Cryptography {
226226

227227
class CryptographicAlgorithm = SC::CryptographicAlgorithm;
228228
}
229+
230+
/**
231+
* A data-flow node that prompts an AI model.
232+
*
233+
* Extend this class to refine existing API models. If you want to model new APIs,
234+
* extend `AIPrompt::Range` instead.
235+
*/
236+
class AIPrompt extends DataFlow::Node instanceof AIPrompt::Range {
237+
/** Gets an input that is used as AI prompt. */
238+
DataFlow::Node getAPrompt() { result = super.getAPrompt() }
239+
}
240+
241+
/** Provides a class for modeling new AI prompting mechanisms. */
242+
module AIPrompt {
243+
/**
244+
* A data-flow node that prompts an AI model.
245+
*
246+
* Extend this class to model new APIs. If you want to refine existing API models,
247+
* extend `AIPrompt` instead.
248+
*/
249+
abstract class Range extends DataFlow::Node {
250+
/** Gets an input that is used as AI prompt. */
251+
abstract DataFlow::Node getAPrompt();
252+
}
253+
}

0 commit comments

Comments
 (0)