Skip to content

Commit 0a36be1

Browse files
committed
Refactor openai model
1 parent 29aad2e commit 0a36be1

File tree

2 files changed

+52
-50
lines changed

2 files changed

+52
-50
lines changed

python/ql/lib/semmle/python/frameworks/OpenAI.qll

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,57 @@ private import python
77
private import semmle.python.ApiGraphs
88

99
/**
10-
* Provides models for Agent (instances of the `agents.Agent` class).
10+
* Provides models for Agent (instances of the `openai.OpenAI` class).
1111
*
12-
* See https://github.com/openai/openai-agents-python.
12+
* See https://github.com/openai/openai-python.
1313
*/
14-
module Agent {
15-
/** Gets a reference to the `agents.Agent` class. */
16-
API::Node classRef() { result = API::moduleImport("agents").getMember("Agent") }
14+
module OpenAI {
15+
/** Gets a reference to the `openai.OpenAI` class. */
16+
API::Node classRef() {
17+
result =
18+
API::moduleImport("openai").getMember(["OpenAI", "AsyncOpenAI", "AzureOpenAI"]).getReturn()
19+
}
1720

18-
/** Gets a reference to a potential property of `agents.Agent` called instructions which refers to the system prompt. */
19-
API::Node sink() { result = classRef().getACall().getKeywordParameter("instructions") }
21+
/** Gets a reference to a potential property of `openai.OpenAI` called instructions which refers to the system prompt. */
22+
API::Node getContentNode() {
23+
exists(API::Node content |
24+
content =
25+
classRef()
26+
.getMember("responses")
27+
.getMember("create")
28+
.getKeywordParameter(["input", "instructions"]) or
29+
content =
30+
classRef()
31+
.getMember("responses")
32+
.getMember("create")
33+
.getKeywordParameter(["input", "instructions"])
34+
.getASubscript()
35+
.getSubscript("content") or
36+
content =
37+
classRef()
38+
.getMember("realtime")
39+
.getMember("connect")
40+
.getReturn()
41+
.getMember("conversation")
42+
.getMember("item")
43+
.getMember("create")
44+
.getKeywordParameter("item")
45+
.getSubscript("content") or
46+
content =
47+
classRef()
48+
.getMember("chat")
49+
.getMember("completions")
50+
.getMember("create")
51+
.getKeywordParameter("messages")
52+
.getASubscript()
53+
.getSubscript("content")
54+
|
55+
// content
56+
if not exists(content.getASubscript())
57+
then result = content
58+
else
59+
// content.text
60+
result = content.getASubscript().getSubscript("text")
61+
)
62+
}
2063
}

python/ql/lib/semmle/python/security/dataflow/PromptInjectionCustomizations.qll

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ private import semmle.python.Concepts
1010
private import semmle.python.dataflow.new.RemoteFlowSources
1111
private import semmle.python.dataflow.new.BarrierGuards
1212
private import semmle.python.frameworks.data.ModelsAsData
13-
private import semmle.python.ApiGraphs
13+
private import semmle.python.frameworks.OpenAI
1414

1515
/**
1616
* Provides default sources, sinks and sanitizers for detecting
@@ -51,48 +51,7 @@ module PromptInjection {
5151

5252
private class PromptContentSink extends Sink {
5353
PromptContentSink() {
54-
exists(API::Node openai, API::Node content |
55-
openai =
56-
API::moduleImport("openai")
57-
.getMember(["OpenAI", "AsyncOpenAI", "AzureOpenAI"])
58-
.getReturn() and
59-
content =
60-
[
61-
openai
62-
.getMember("responses")
63-
.getMember("create")
64-
.getKeywordParameter(["input", "instructions"]),
65-
openai
66-
.getMember("responses")
67-
.getMember("create")
68-
.getKeywordParameter(["input", "instructions"])
69-
.getASubscript()
70-
.getSubscript("content"),
71-
openai
72-
.getMember("realtime")
73-
.getMember("connect")
74-
.getReturn()
75-
.getMember("conversation")
76-
.getMember("item")
77-
.getMember("create")
78-
.getKeywordParameter("item")
79-
.getSubscript("content"),
80-
openai
81-
.getMember("chat")
82-
.getMember("completions")
83-
.getMember("create")
84-
.getKeywordParameter("messages")
85-
.getASubscript()
86-
.getSubscript("content")
87-
]
88-
|
89-
// content
90-
if not exists(content.getASubscript())
91-
then this = content.asSink()
92-
else
93-
// content.text
94-
this = content.getASubscript().getSubscript("text").asSink()
95-
)
54+
this = OpenAI::getContentNode().asSink()
9655
}
9756
}
9857

0 commit comments

Comments
 (0)