add barrier when data flows into user messages for system prompt detection, remove embeddings from user prompt injection query

This commit is contained in:
BazookaMusic
2026-05-15 12:14:14 +02:00
parent 9c136264de
commit 535adc7a31
11 changed files with 218 additions and 67 deletions

View File

@@ -33,7 +33,7 @@ module Anthropic {
// messages: [{ role: "assistant", content: "..." }]
exists(API::Node msg |
msg = messagesCreateParams().getMember("messages").getArrayElement() and
msg.getMember("role").asSink().mayHaveStringValue("assistant")
msg.getMember("role").asSink().mayHaveStringValue(["system", "assistant"])
|
result = msg.getMember("content")
)
@@ -47,7 +47,7 @@ module Anthropic {
// messages: [{ role: "user", content: "..." }]
exists(API::Node msg |
msg = messagesCreateParams().getMember("messages").getArrayElement() and
not msg.getMember("role").asSink().mayHaveStringValue("assistant")
not msg.getMember("role").asSink().mayHaveStringValue(["system", "assistant"])
|
result = msg.getMember("content")
)

View File

@@ -33,7 +33,7 @@ module GoogleGenAI {
.getParameter(0)
.getMember("contents")
.getArrayElement() and
msg.getMember("role").asSink().mayHaveStringValue("model")
msg.getMember("role").asSink().mayHaveStringValue(["system", "model"])
|
result = msg.getMember("parts").getArrayElement().getMember("text")
)
@@ -53,7 +53,7 @@ module GoogleGenAI {
.getParameter(0)
.getMember("contents")
.getArrayElement() and
not msg.getMember("role").asSink().mayHaveStringValue("model")
not msg.getMember("role").asSink().mayHaveStringValue(["system", "model"])
|
result = msg.getMember("parts").getArrayElement().getMember("text")
)

View File

@@ -171,14 +171,6 @@ module OpenAI {
.getParameter(0)
.getMember("prompt")
or
// embeddings.create({ input: ... })
result =
clientsNoGuardrails()
.getMember("embeddings")
.getMember("create")
.getParameter(0)
.getMember("input")
or
// beta.threads.messages.create(threadId, { role: "user", content: ... })
exists(API::Node msg |
msg =

View File

@@ -74,6 +74,24 @@ module SystemPromptInjection {
}
}
/**
* Content placed in a message with `role: "user"` is not a system prompt
* injection vector; it is intended user-role content.
*
* This prevents false positives when user input and system prompts are
* combined in the same message array (e.g. `[{role:"system", content: ...},
* {role:"user", content: tainted}]`) and taint would otherwise propagate
* through array operations to the system message.
*/
private class UserRoleMessageContentBarrier extends Sanitizer {
UserRoleMessageContentBarrier() {
exists(DataFlow::SourceNode obj |
obj.getAPropertySource("role").mayHaveStringValue("user") and
this = obj.getAPropertyWrite("content").getRhs()
)
}
}
/**
* A comparison with a constant, considered as a sanitizer-guard.
*/