From 8d3071d298c0c20156a7638a01a68f3e711627b9 Mon Sep 17 00:00:00 2001 From: Sotiris Dragonas <36576941+BazookaMusic@users.noreply.github.com> Date: Mon, 6 Jul 2026 16:53:45 +0200 Subject: [PATCH] Add the missing alerts --- .../UserPromptInjection.expected | 15 +++++++++++---- .../CWE-1427-UserPromptInjection/agent_test.py | 16 ++++++++++++++-- .../CWE-1427-UserPromptInjection/gemini_test.py | 2 +- .../CWE-1427-UserPromptInjection/openai_test.py | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/UserPromptInjection.expected b/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/UserPromptInjection.expected index 364e19dedd4..e5e93f12ac0 100644 --- a/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/UserPromptInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/UserPromptInjection.expected @@ -2,6 +2,8 @@ | agent_test.py:13:38:13:42 | ControlFlowNode for query | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | agent_test.py:13:38:13:42 | ControlFlowNode for query | This prompt construction depends on a $@. | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | agent_test.py:17:15:22:9 | ControlFlowNode for List | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | agent_test.py:17:15:22:9 | ControlFlowNode for List | This prompt construction depends on a $@. | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | agent_test.py:20:28:20:32 | ControlFlowNode for query | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | agent_test.py:20:28:20:32 | ControlFlowNode for query | This prompt construction depends on a $@. | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| agent_test.py:28:9:28:62 | ControlFlowNode for BinaryExpr | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | agent_test.py:28:9:28:62 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| agent_test.py:33:9:33:98 | ControlFlowNode for BinaryExpr | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | agent_test.py:33:9:33:98 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | anthropic_test.py:20:28:20:32 | ControlFlowNode for query | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:20:28:20:32 | ControlFlowNode for query | This prompt construction depends on a $@. | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | anthropic_test.py:29:16:29:55 | ControlFlowNode for BinaryExpr | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:29:16:29:55 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | gemini_test.py:15:18:15:22 | ControlFlowNode for query | gemini_test.py:3:26:3:32 | ControlFlowNode for ImportMember | gemini_test.py:15:18:15:22 | ControlFlowNode for query | This prompt construction depends on a $@. | gemini_test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | @@ -40,14 +42,19 @@ edges | agent_test.py:2:26:2:32 | ControlFlowNode for ImportMember | agent_test.py:2:26:2:32 | ControlFlowNode for request | provenance | | | agent_test.py:2:26:2:32 | ControlFlowNode for request | agent_test.py:9:13:9:19 | ControlFlowNode for request | provenance | | +| agent_test.py:2:26:2:32 | ControlFlowNode for request | agent_test.py:25:22:25:28 | ControlFlowNode for request | provenance | | | agent_test.py:9:5:9:9 | ControlFlowNode for query | agent_test.py:13:38:13:42 | ControlFlowNode for query | provenance | Sink:MaD:20 | | agent_test.py:9:5:9:9 | ControlFlowNode for query | agent_test.py:20:28:20:32 | ControlFlowNode for query | provenance | | | agent_test.py:9:5:9:9 | ControlFlowNode for query | agent_test.py:20:28:20:32 | ControlFlowNode for query | provenance | | | agent_test.py:9:13:9:19 | ControlFlowNode for request | agent_test.py:9:13:9:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | +| agent_test.py:9:13:9:19 | ControlFlowNode for request | agent_test.py:25:5:25:18 | ControlFlowNode for other_messages | provenance | AdditionalTaintStep | | agent_test.py:9:13:9:24 | ControlFlowNode for Attribute | agent_test.py:9:13:9:37 | ControlFlowNode for Attribute() | provenance | dict.get | | agent_test.py:9:13:9:37 | ControlFlowNode for Attribute() | agent_test.py:9:5:9:9 | ControlFlowNode for query | provenance | | | agent_test.py:18:13:21:13 | ControlFlowNode for Dict [Dictionary element at key content] | agent_test.py:17:15:22:9 | ControlFlowNode for List | provenance | Sink:MaD:21 Sink:MaD:21 | | agent_test.py:20:28:20:32 | ControlFlowNode for query | agent_test.py:18:13:21:13 | ControlFlowNode for Dict [Dictionary element at key content] | provenance | | +| agent_test.py:25:5:25:18 | ControlFlowNode for other_messages | agent_test.py:28:9:28:62 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:20 | +| agent_test.py:25:5:25:18 | ControlFlowNode for other_messages | agent_test.py:33:9:33:98 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:20 | +| agent_test.py:25:22:25:28 | ControlFlowNode for request | agent_test.py:25:5:25:18 | ControlFlowNode for other_messages | provenance | AdditionalTaintStep | | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:2:26:2:32 | ControlFlowNode for request | provenance | | | anthropic_test.py:2:26:2:32 | ControlFlowNode for request | anthropic_test.py:10:15:10:21 | ControlFlowNode for request | provenance | | | anthropic_test.py:2:26:2:32 | ControlFlowNode for request | anthropic_test.py:11:13:11:19 | ControlFlowNode for request | provenance | | @@ -175,6 +182,10 @@ nodes | agent_test.py:18:13:21:13 | ControlFlowNode for Dict [Dictionary element at key content] | semmle.label | ControlFlowNode for Dict [Dictionary element at key content] | | agent_test.py:20:28:20:32 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | agent_test.py:20:28:20:32 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | +| agent_test.py:25:5:25:18 | ControlFlowNode for other_messages | semmle.label | ControlFlowNode for other_messages | +| agent_test.py:25:22:25:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| agent_test.py:28:9:28:62 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| agent_test.py:33:9:33:98 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | anthropic_test.py:2:26:2:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | anthropic_test.py:10:15:10:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -266,7 +277,3 @@ nodes | openrouter_test.py:44:16:44:20 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | openrouter_test.py:50:15:50:19 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | subpaths -testFailures -| agent_test.py:17:15:22:9 | ControlFlowNode for List | Unexpected result: Alert | -| gemini_test.py:20:18:29:9 | ControlFlowNode for List | Unexpected result: Alert | -| openai_test.py:20:15:29:9 | ControlFlowNode for List | Unexpected result: Alert | diff --git a/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/agent_test.py b/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/agent_test.py index 75920ae683b..3b4f297bf00 100644 --- a/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/agent_test.py +++ b/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/agent_test.py @@ -19,6 +19,18 @@ def get_input_agent(): "role": "user", "content": query, # $ Alert[py/user-prompt-injection] } - ] + ] # $ Alert[py/user-prompt-injection] ) - print(result1, result2) + + other_messages = request.json # tainted list of messages + result3 = Runner.run_sync( + agent, + [{"role": "system", "content": "hi"}] + other_messages # $ Alert[py/user-prompt-injection] + ) + + result4 = Runner.run_sync( + agent, + [{"role": "system", "content": "hi"}, {"role": "user", "content": query}] + other_messages # $ Alert[py/user-prompt-injection] + ) + + print(result1, result2, result3, result4) diff --git a/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/gemini_test.py b/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/gemini_test.py index 13a4953e17c..826e8e7ea22 100644 --- a/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/gemini_test.py +++ b/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/gemini_test.py @@ -26,7 +26,7 @@ def get_input_gemini(): } ] } - ], + ], # $ Alert[py/user-prompt-injection] ) chat = client.chats.create(model="gemini-2.0-flash") diff --git a/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/openai_test.py b/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/openai_test.py index 97b1bc2a702..e3a0a01131d 100644 --- a/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/openai_test.py +++ b/python/ql/test/query-tests/Security/CWE-1427-UserPromptInjection/openai_test.py @@ -26,7 +26,7 @@ async def get_input_openai(): "role": "user", "content": query, # $ Alert[py/user-prompt-injection] } - ] + ] # $ Alert[py/user-prompt-injection] ) completion1 = client.chat.completions.create(