|
4 | 4 | */
|
5 | 5 |
|
6 | 6 | private import python
|
7 |
| -private import semmle.python.dataflow.new.DataFlow |
8 | 7 | private import semmle.python.dataflow.new.RemoteFlowSources
|
9 | 8 | private import semmle.python.dataflow.new.TaintTracking
|
10 | 9 | private import semmle.python.Concepts
|
@@ -141,4 +140,95 @@ module Pyramid {
|
141 | 140 | }
|
142 | 141 | }
|
143 | 142 | }
|
| 143 | + |
| 144 | + module Response { |
| 145 | + private class PyramidReturnResponse extends Http::Server::HttpResponse::Range { |
| 146 | + PyramidReturnResponse() { |
| 147 | + this.asCfgNode() = any(View::ViewCallable vc).getAReturnValueFlowNode() and |
| 148 | + not this = instance() |
| 149 | + } |
| 150 | + |
| 151 | + override DataFlow::Node getBody() { result = this } |
| 152 | + |
| 153 | + override DataFlow::Node getMimetypeOrContentTypeArg() { none() } |
| 154 | + |
| 155 | + override string getMimetypeDefault() { result = "text/html" } |
| 156 | + } |
| 157 | + |
| 158 | + private API::Node classRef() { |
| 159 | + result = API::moduleImport("pyramid").getMember("response").getMember("Response") |
| 160 | + } |
| 161 | + |
| 162 | + abstract class InstanceSource extends DataFlow::LocalSourceNode, |
| 163 | + Http::Server::HttpResponse::Range |
| 164 | + { } |
| 165 | + |
| 166 | + /** Gets a reference to an instance of `pyramid.request.Request`. */ |
| 167 | + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { |
| 168 | + t.start() and |
| 169 | + result instanceof InstanceSource |
| 170 | + or |
| 171 | + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) |
| 172 | + } |
| 173 | + |
| 174 | + /** Gets a reference to an instance of `pyramid.request.Request`. */ |
| 175 | + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } |
| 176 | + |
| 177 | + private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode { |
| 178 | + ClassInstantiation() { this = classRef().getACall() } |
| 179 | + |
| 180 | + override DataFlow::Node getBody() { result = [this.getArg(0), this.getArgByName("body")] } |
| 181 | + |
| 182 | + override DataFlow::Node getMimetypeOrContentTypeArg() { |
| 183 | + result = [this.getArg(4), this.getArgByName("content_type")] |
| 184 | + } |
| 185 | + |
| 186 | + override string getMimetypeDefault() { result = "text/html" } |
| 187 | + } |
| 188 | + |
| 189 | + private class ResponseBodySet extends Http::Server::HttpResponse::Range instanceof DataFlow::AttrWrite |
| 190 | + { |
| 191 | + string attrName; |
| 192 | + |
| 193 | + ResponseBodySet() { |
| 194 | + this.getObject() = instance() and |
| 195 | + this.getAttributeName() = attrName and |
| 196 | + attrName in ["body", "body_file", "json", "json_body", "text", "ubody", "unicode_body"] |
| 197 | + } |
| 198 | + |
| 199 | + override DataFlow::Node getBody() { result = this.(DataFlow::AttrWrite).getValue() } |
| 200 | + |
| 201 | + override DataFlow::Node getMimetypeOrContentTypeArg() { none() } |
| 202 | + |
| 203 | + override string getMimetypeDefault() { |
| 204 | + if attrName in ["json", "json_body"] |
| 205 | + then result = "application/json" |
| 206 | + else result = "text/html" |
| 207 | + } |
| 208 | + } |
| 209 | + |
| 210 | + private class RequestResponseAttr extends InstanceSource instanceof DataFlow::AttrRead { |
| 211 | + RequestResponseAttr() { |
| 212 | + this.getObject() = Request::instance() and this.getAttributeName() = "response" |
| 213 | + } |
| 214 | + |
| 215 | + override DataFlow::Node getBody() { none() } |
| 216 | + |
| 217 | + override DataFlow::Node getMimetypeOrContentTypeArg() { none() } |
| 218 | + |
| 219 | + override string getMimetypeDefault() { result = "text/html" } |
| 220 | + } |
| 221 | + |
| 222 | + private class SetCookieCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { |
| 223 | + SetCookieCall() { this.calls(instance(), "set_cookie") } |
| 224 | + |
| 225 | + override DataFlow::Node getHeaderArg() { none() } |
| 226 | + |
| 227 | + override DataFlow::Node getNameArg() { result = [this.getArg(0), this.getArgByName("name")] } |
| 228 | + |
| 229 | + override DataFlow::Node getValueArg() { |
| 230 | + result = [this.getArg(1), this.getArgByName("value")] |
| 231 | + } |
| 232 | + } |
| 233 | + } |
144 | 234 | }
|
0 commit comments