@@ -18,20 +18,135 @@ private import semmle.python.frameworks.Stdlib
1818 * - https://werkzeug.palletsprojects.com/en/1.0.x/#werkzeug
1919 */
2020module Werkzeug {
21- /** Provides models for the `werkzeug` module. */
22- module werkzeug {
23- /** Provides models for the `werkzeug.datastructures` module. */
24- module datastructures {
21+ /**
22+ * Provides models for the `werkzeug.datastructures.MultiDict` class
23+ *
24+ * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.MultiDict.
25+ */
26+ module MultiDict {
27+ /**
28+ * A source of instances of `werkzeug.datastructures.MultiDict`, extend this class to model new instances.
29+ *
30+ * This can include instantiations of the class, return values from function
31+ * calls, or a special parameter that will be set when functions are called by an external
32+ * library.
33+ *
34+ * Use the predicate `MultiDict::instance()` to get references to instances of `werkzeug.datastructures.MultiDict`.
35+ */
36+ abstract class InstanceSource extends DataFlow:: LocalSourceNode { }
37+
38+ /** Gets a reference to an instance of `werkzeug.datastructures.MultiDict`. */
39+ private DataFlow:: TypeTrackingNode instance ( DataFlow:: TypeTracker t ) {
40+ t .start ( ) and
41+ result instanceof InstanceSource
42+ or
43+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
44+ }
45+
46+ /** Gets a reference to an instance of `werkzeug.datastructures.MultiDict`. */
47+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
48+
49+ private class MultiDictAdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
50+ override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
51+ // See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers.getlist
52+ nodeFrom = instance ( ) and
53+ nodeTo .( DataFlow:: MethodCallNode ) .calls ( nodeFrom , "getlist" )
54+ }
55+ }
56+ }
57+
58+ /**
59+ * Provides models for the `werkzeug.datastructures.FileStorage` class
60+ *
61+ * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.FileStorage.
62+ */
63+ module FileStorage {
64+ /**
65+ * A source of instances of `werkzeug.datastructures.FileStorage`, extend this class to model new instances.
66+ *
67+ * This can include instantiations of the class, return values from function
68+ * calls, or a special parameter that will be set when functions are called by an external
69+ * library.
70+ *
71+ * Use the predicate `FileStorage::instance()` to get references to instances of `werkzeug.datastructures.FileStorage`.
72+ */
73+ // All the attributes of the wrapper stream are proxied by the file storage so it’s
74+ // possible to do storage.read() instead of the long form storage.stream.read(). So
75+ // that's why InstanceSource also extends `Stdlib::FileLikeObject::InstanceSource`
76+ abstract class InstanceSource extends Stdlib:: FileLikeObject:: InstanceSource ,
77+ DataFlow:: LocalSourceNode { }
78+
79+ /** Gets a reference to an instance of `werkzeug.datastructures.FileStorage`. */
80+ private DataFlow:: TypeTrackingNode instance ( DataFlow:: TypeTracker t ) {
81+ t .start ( ) and
82+ result instanceof InstanceSource
83+ or
84+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
85+ }
86+
87+ /** Gets a reference to an instance of `werkzeug.datastructures.FileStorage`. */
88+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
89+
90+ private class FileStorageAdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
91+ override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
92+ nodeFrom = instance ( ) and
93+ exists ( DataFlow:: AttrRead read | nodeTo = read |
94+ read .getAttributeName ( ) in [
95+ // str
96+ "filename" , "name" , "content_type" , "mimetype" ,
97+ // file-like
98+ "stream" ,
99+ // TODO: werkzeug.datastructures.Headers
100+ "headers" ,
101+ // dict[str, str]
102+ "mimetype_params"
103+ ] and
104+ read .getObject ( ) = nodeFrom
105+ )
106+ }
107+ }
108+
109+ /** A file-like object instance that originates from a `FileStorage`. */
110+ private class FileStorageFileLikeInstances extends Stdlib:: FileLikeObject:: InstanceSource {
111+ FileStorageFileLikeInstances ( ) { this .( DataFlow:: AttrRead ) .accesses ( instance ( ) , "stream" ) }
112+ }
113+ }
114+
115+ import WerkzeugOld
116+ }
117+
118+ /**
119+ * Old version that contains the deprecated modules.
120+ */
121+ private module WerkzeugOld {
122+ /**
123+ * DEPRECATED: Use the modeling available directly in the `Werkzeug` module instead.
124+ *
125+ * Provides models for the `werkzeug` module.
126+ */
127+ deprecated module werkzeug {
128+ /**
129+ * DEPRECATED: Use the modeling available directly in the `Werkzeug` module instead.
130+ *
131+ * Provides models for the `werkzeug.datastructures` module.
132+ */
133+ deprecated module datastructures {
25134 /**
135+ * DEPRECATED: Use `Werkzeug::MultiDict` instead.
136+ *
26137 * Provides models for the `werkzeug.datastructures.MultiDict` class
27138 *
28139 * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.MultiDict.
29140 */
30- module MultiDict {
31- /** DEPRECATED. Use `InstanceSourceApiNode` instead. */
141+ deprecated module MultiDict {
142+ /**
143+ * DEPRECATED. Use `Werkzeug::MultiDict::InstanceSource` instead.
144+ */
32145 abstract deprecated class InstanceSource extends DataFlow:: Node { }
33146
34147 /**
148+ * DEPRECATED. Use `Werkzeug::MultiDict::InstanceSource` instead.
149+ *
35150 * A source of instances of `werkzeug.datastructures.MultiDict`, extend this class to model new instances.
36151 *
37152 * This can include instantiations of the class, return values from function
@@ -40,14 +155,16 @@ module Werkzeug {
40155 *
41156 * Use the predicate `MultiDict::instance()` to get references to instances of `werkzeug.datastructures.MultiDict`.
42157 */
43- abstract class InstanceSourceApiNode extends API:: Node { }
158+ abstract deprecated class InstanceSourceApiNode extends API:: Node { }
44159
45160 /**
161+ * DEPRECATED
162+ *
46163 * Gets a reference to the `getlist` method on an instance of `werkzeug.datastructures.MultiDict`.
47164 *
48165 * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers.getlist
49166 */
50- DataFlow:: Node getlist ( ) {
167+ deprecated DataFlow:: Node getlist ( ) {
51168 result = any ( InstanceSourceApiNode a ) .getMember ( "getlist" ) .getAUse ( )
52169 }
53170
@@ -57,26 +174,32 @@ module Werkzeug {
57174 exists ( DataFlow:: AttrRead read |
58175 read .getObject ( ) = nodeFrom and
59176 nodeTo = read and
60- nodeTo = werkzeug :: datastructures :: MultiDict :: getlist ( )
177+ nodeTo = getlist ( )
61178 )
62179 or
63180 // getlist -> getlist()
64- nodeFrom = werkzeug :: datastructures :: MultiDict :: getlist ( ) and
181+ nodeFrom = getlist ( ) and
65182 nodeTo .( DataFlow:: CallCfgNode ) .getFunction ( ) = nodeFrom
66183 }
67184 }
68185 }
69186
70187 /**
188+ * DEPRECATED: Use `Werkzeug::FileStorage` instead.
189+ *
71190 * Provides models for the `werkzeug.datastructures.FileStorage` class
72191 *
73192 * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.FileStorage.
74193 */
75- module FileStorage {
76- /** DEPRECATED. Use `InstanceSourceApiNode` instead. */
194+ deprecated module FileStorage {
195+ /**
196+ * DEPRECATED. Use `Werkzeug::FileStorage::InstanceSource` instead.
197+ */
77198 abstract deprecated class InstanceSource extends DataFlow:: Node { }
78199
79200 /**
201+ * DEPRECATED. Use `Werkzeug::FileStorage::InstanceSource` instead.
202+ *
80203 * A source of instances of `werkzeug.datastructures.FileStorage`, extend this class to model new instances.
81204 *
82205 * This can include instantiations of the class, return values from function
@@ -85,14 +208,14 @@ module Werkzeug {
85208 *
86209 * Use the predicate `FileStorage::instance()` to get references to instances of `werkzeug.datastructures.FileStorage`.
87210 */
88- abstract class InstanceSourceApiNode extends API:: Node { }
211+ abstract deprecated class InstanceSourceApiNode extends API:: Node { }
89212
90213 /** Gets a reference to an instance of `werkzeug.datastructures.FileStorage`. */
91- DataFlow:: Node instance ( ) { result = any ( InstanceSourceApiNode a ) .getAUse ( ) }
214+ deprecated DataFlow:: Node instance ( ) { result = any ( InstanceSourceApiNode a ) .getAUse ( ) }
92215
93216 private class FileStorageAdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
94217 override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
95- nodeFrom = werkzeug :: datastructures :: FileStorage :: instance ( ) and
218+ nodeFrom = instance ( ) and
96219 exists ( DataFlow:: AttrRead read | nodeTo = read |
97220 read .getAttributeName ( ) in [
98221 // str
@@ -108,21 +231,6 @@ module Werkzeug {
108231 )
109232 }
110233 }
111-
112- /** A file-like object instance that originates from a `FileStorage`. */
113- class FileStorageFileLikeInstances extends Stdlib:: FileLikeObject:: InstanceSource {
114- FileStorageFileLikeInstances ( ) {
115- this .( DataFlow:: AttrRead ) .accesses ( instance ( ) , "stream" )
116- or
117- // All the attributes of the wrapper stream are proxied by the file storage
118- // so it’s possible to do storage.read() instead of the long form
119- // storage.stream.read().
120- //
121- // due to the `InstanceSourceApiNode` stuff, we can't just make
122- // `InstanceSource` extend `Stdlib::FileLikeObject::InstanceSource`
123- this = any ( InstanceSourceApiNode api ) .getAnImmediateUse ( )
124- }
125- }
126234 }
127235 }
128236 }
0 commit comments