@@ -16,129 +16,142 @@ module Gradio {
1616 /**
1717 * The event handlers in Gradio, which take untrusted data.
1818 */
19-
2019 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 ( )
4139 }
40+ }
4241
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 ( )
4848 }
49+ }
4950
5051 /**
5152 * The `inputs` parameters in Gradio event handlers, that are lists and are sources of untrusted data.
5253 * This model allows tracking each element list back to source, f.ex. `gr.Textbox(...)`.
5354 */
5455 class GradioInputList extends RemoteFlowSource:: Range {
5556 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
6163 // 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
6367 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+ )
7077 }
71- override string getSourceType ( ) { result = "Gradio untrusted input" }
72-
7378
79+ override string getSourceType ( ) { result = "Gradio untrusted input" }
7480 }
7581
7682 /**
7783 * The `inputs` parameters in Gradio event handlers, that are not lists and are sources of untrusted data.
7884 */
7985 class GradioInputParameter extends RemoteFlowSource:: Range {
8086 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
96101 )
97102 }
98- override string getSourceType ( ) { result = "Gradio untrusted input" }
99- }
103+
104+ override string getSourceType ( ) { result = "Gradio untrusted input" }
105+ }
100106
101107 /**
102108 * The `inputs` parameters in Gradio decorators to event handlers, that are sources of untrusted data.
103109 */
104- class GradioInputDecorator extends RemoteFlowSource:: Range {
110+ class GradioInputDecorator extends RemoteFlowSource:: Range {
105111 GradioInputDecorator ( ) {
106112 exists ( API:: CallNode call |
107- ( call instanceof GradioInput or call instanceof GradioInterface )
108- and
113+ ( call instanceof GradioInput or call instanceof GradioInterface ) and
109114 this = call .getReturn ( ) .getACall ( ) .getParameter ( 0 ) .getParameter ( _) .asSource ( )
110115 )
111116 }
112- override string getSourceType ( ) { result = "Gradio untrusted input" }
113- }
117+
118+ override string getSourceType ( ) { result = "Gradio untrusted input" }
119+ }
114120
115121 /**
116122 * Extra taint propagation for tracking `inputs` parameters in Gradio event handlers, that are lists.
117123 */
118124 private class ListTaintStep extends TaintTracking:: AdditionalTaintStep {
119125 override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
120126 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
137129 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+ )
139153 )
140154 )
141155 }
142156 }
143-
144157}
0 commit comments