@@ -16,129 +16,142 @@ module Gradio {
16
16
/**
17
17
* The event handlers in Gradio, which take untrusted data.
18
18
*/
19
-
20
19
class GradioInput extends API:: CallNode {
21
- GradioInput ( ) { this = API:: moduleImport ( "gradio" )
22
- .getMember ( [
23
- "Button" , "Textbox" , "UploadButton" , "Slider" ,
24
- "JSON" , "HTML" , "Markdown" , "File" ,
25
- "AnnotatedImage" , "Audio" , "BarPlot" , "Chatbot" , "Checkbox" ,
26
- "CheckboxGroup" , "ClearButton" , "Code" , "ColorPicker" , "Dataframe" ,
27
- "Dataset" , "DownloadButton" , "Dropdown" , "DuplicateButton" , "FileExplorer" ,
28
- "Gallery" , "HighlightedText" , "Image" , "ImageEditor" , "Label" , "LinePlot" ,
29
- "LoginButton" , "LogoutButton" , "Model3D" , "Number" , "ParamViewer" ,
30
- "Plot" , "Radio" , "ScatterPlot" , "SimpleImage" , "State" , "Video" ] )
31
- .getReturn ( )
32
- .getMember ( [
33
- "change" , "input" , "click" , "submit" ,
34
- "edit" , "clear" , "play" , "pause" , "stop" , "end" , "start_recording" ,
35
- "pause_recording" , "stop_recording" , "focus" , "blur" ,
36
- "upload" , "release" , "select" , "stream" , "like" , "load" ,
37
- "like" , "key_up" , ] )
38
- .getACall ( )
39
- }
40
-
20
+ GradioInput ( ) {
21
+ this =
22
+ API:: moduleImport ( "gradio" )
23
+ .getMember ( [
24
+ "Button" , "Textbox" , "UploadButton" , "Slider" , "JSON" , "HTML" , "Markdown" , "File" ,
25
+ "AnnotatedImage" , "Audio" , "BarPlot" , "Chatbot" , "Checkbox" , "CheckboxGroup" ,
26
+ "ClearButton" , "Code" , "ColorPicker" , "Dataframe" , "Dataset" , "DownloadButton" ,
27
+ "Dropdown" , "DuplicateButton" , "FileExplorer" , "Gallery" , "HighlightedText" ,
28
+ "Image" , "ImageEditor" , "Label" , "LinePlot" , "LoginButton" , "LogoutButton" ,
29
+ "Model3D" , "Number" , "ParamViewer" , "Plot" , "Radio" , "ScatterPlot" , "SimpleImage" ,
30
+ "State" , "Video"
31
+ ] )
32
+ .getReturn ( )
33
+ .getMember ( [
34
+ "change" , "input" , "click" , "submit" , "edit" , "clear" , "play" , "pause" , "stop" ,
35
+ "end" , "start_recording" , "pause_recording" , "stop_recording" , "focus" , "blur" ,
36
+ "upload" , "release" , "select" , "stream" , "like" , "load" , "like" , "key_up" ,
37
+ ] )
38
+ .getACall ( )
41
39
}
40
+ }
42
41
43
- /**
44
- * The high-level gradio.Interface and gradio.ChatInterface classes, which take untrusted data.
45
- */
46
- class GradioInterface extends API:: CallNode {
47
- GradioInterface ( ) { this = API:: moduleImport ( "gradio" ) .getMember ( [ "Interface" , "ChatInterface" ] ) .getACall ( ) }
42
+ /**
43
+ * The high-level gradio.Interface and gradio.ChatInterface classes, which take untrusted data.
44
+ */
45
+ class GradioInterface extends API:: CallNode {
46
+ GradioInterface ( ) {
47
+ this = API:: moduleImport ( "gradio" ) .getMember ( [ "Interface" , "ChatInterface" ] ) .getACall ( )
48
48
}
49
+ }
49
50
50
51
/**
51
52
* The `inputs` parameters in Gradio event handlers, that are lists and are sources of untrusted data.
52
53
* This model allows tracking each element list back to source, f.ex. `gr.Textbox(...)`.
53
54
*/
54
55
class GradioInputList extends RemoteFlowSource:: Range {
55
56
GradioInputList ( ) {
56
- exists ( API:: CallNode call |
57
- ( call instanceof GradioInput
58
- or
59
- call instanceof GradioInterface )
60
- and
57
+ exists ( API:: CallNode call |
58
+ (
59
+ call instanceof GradioInput
60
+ or
61
+ call instanceof GradioInterface
62
+ ) and
61
63
// limit only to lists of parameters given to `inputs`.
62
- ( ( call .getKeywordParameter ( "inputs" ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
64
+ (
65
+ (
66
+ call .getKeywordParameter ( "inputs" ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
63
67
or
64
- call .getParameter ( 1 ) .asSink ( ) .asCfgNode ( ) instanceof ListNode )
65
- and
66
- ( this = call .getKeywordParameter ( "inputs" ) .getASuccessor ( ) .getAValueReachingSink ( )
67
- or
68
- this = call .getParameter ( 1 ) .getASuccessor ( ) .getAValueReachingSink ( ) ) )
69
- )
68
+ call .getParameter ( 1 ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
69
+ ) and
70
+ (
71
+ this = call .getKeywordParameter ( "inputs" ) .getASuccessor ( ) .getAValueReachingSink ( )
72
+ or
73
+ this = call .getParameter ( 1 ) .getASuccessor ( ) .getAValueReachingSink ( )
74
+ )
75
+ )
76
+ )
70
77
}
71
- override string getSourceType ( ) { result = "Gradio untrusted input" }
72
-
73
78
79
+ override string getSourceType ( ) { result = "Gradio untrusted input" }
74
80
}
75
81
76
82
/**
77
83
* The `inputs` parameters in Gradio event handlers, that are not lists and are sources of untrusted data.
78
84
*/
79
85
class GradioInputParameter extends RemoteFlowSource:: Range {
80
86
GradioInputParameter ( ) {
81
- exists ( API:: CallNode call |
82
- ( call instanceof GradioInput
83
- or
84
- call instanceof GradioInterface )
85
-
86
- and
87
- ( this = call .getKeywordParameter ( "fn" ) .getParameter ( _) .asSource ( )
88
- or
89
- this = call .getParameter ( 0 ) .getParameter ( _) .asSource ( ) )
90
-
91
- and
92
- // exclude lists of parameters given to `inputs`
93
- not call .getKeywordParameter ( "inputs" ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
94
- and
95
- not call .getParameter ( 1 ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
87
+ exists ( API:: CallNode call |
88
+ (
89
+ call instanceof GradioInput
90
+ or
91
+ call instanceof GradioInterface
92
+ ) and
93
+ (
94
+ this = call .getKeywordParameter ( "fn" ) .getParameter ( _) .asSource ( )
95
+ or
96
+ this = call .getParameter ( 0 ) .getParameter ( _) .asSource ( )
97
+ ) and
98
+ // exclude lists of parameters given to `inputs`
99
+ not call .getKeywordParameter ( "inputs" ) .asSink ( ) .asCfgNode ( ) instanceof ListNode and
100
+ not call .getParameter ( 1 ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
96
101
)
97
102
}
98
- override string getSourceType ( ) { result = "Gradio untrusted input" }
99
- }
103
+
104
+ override string getSourceType ( ) { result = "Gradio untrusted input" }
105
+ }
100
106
101
107
/**
102
108
* The `inputs` parameters in Gradio decorators to event handlers, that are sources of untrusted data.
103
109
*/
104
- class GradioInputDecorator extends RemoteFlowSource:: Range {
110
+ class GradioInputDecorator extends RemoteFlowSource:: Range {
105
111
GradioInputDecorator ( ) {
106
112
exists ( API:: CallNode call |
107
- ( call instanceof GradioInput or call instanceof GradioInterface )
108
- and
113
+ ( call instanceof GradioInput or call instanceof GradioInterface ) and
109
114
this = call .getReturn ( ) .getACall ( ) .getParameter ( 0 ) .getParameter ( _) .asSource ( )
110
115
)
111
116
}
112
- override string getSourceType ( ) { result = "Gradio untrusted input" }
113
- }
117
+
118
+ override string getSourceType ( ) { result = "Gradio untrusted input" }
119
+ }
114
120
115
121
/**
116
122
* Extra taint propagation for tracking `inputs` parameters in Gradio event handlers, that are lists.
117
123
*/
118
124
private class ListTaintStep extends TaintTracking:: AdditionalTaintStep {
119
125
override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
120
126
exists ( API:: CallNode node |
121
- ( node instanceof GradioInput
122
- or
123
- node instanceof GradioInterface )
124
- and
125
- // handle cases where there are multiple arguments passed as a list to `inputs`
126
- ( (
127
- ( node .getKeywordParameter ( "inputs" ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
128
- or
129
- node .getParameter ( 1 ) .asSink ( ) .asCfgNode ( ) instanceof ListNode )
130
- and
131
- exists ( int i |
132
- ( nodeTo = node .getParameter ( 0 ) .getParameter ( i ) .asSource ( )
133
- or
134
- nodeTo = node .getKeywordParameter ( "fn" ) .getParameter ( i ) .asSource ( ) )
135
- and
136
- ( nodeFrom .asCfgNode ( ) = node .getKeywordParameter ( "inputs" ) .asSink ( ) .asCfgNode ( ) .( ListNode ) .getElement ( i )
127
+ (
128
+ node instanceof GradioInput
137
129
or
138
- nodeFrom .asCfgNode ( ) = node .getParameter ( 1 ) .asSink ( ) .asCfgNode ( ) .( ListNode ) .getElement ( i ) ) ) )
130
+ node instanceof GradioInterface
131
+ ) and
132
+ // handle cases where there are multiple arguments passed as a list to `inputs`
133
+ (
134
+ (
135
+ node .getKeywordParameter ( "inputs" ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
136
+ or
137
+ node .getParameter ( 1 ) .asSink ( ) .asCfgNode ( ) instanceof ListNode
138
+ ) and
139
+ exists ( int i |
140
+ (
141
+ nodeTo = node .getParameter ( 0 ) .getParameter ( i ) .asSource ( )
142
+ or
143
+ nodeTo = node .getKeywordParameter ( "fn" ) .getParameter ( i ) .asSource ( )
144
+ ) and
145
+ (
146
+ nodeFrom .asCfgNode ( ) =
147
+ node .getKeywordParameter ( "inputs" ) .asSink ( ) .asCfgNode ( ) .( ListNode ) .getElement ( i )
148
+ or
149
+ nodeFrom .asCfgNode ( ) =
150
+ node .getParameter ( 1 ) .asSink ( ) .asCfgNode ( ) .( ListNode ) .getElement ( i )
151
+ )
152
+ )
139
153
)
140
154
)
141
155
}
142
156
}
143
-
144
157
}
0 commit comments