Skip to content

Commit 0beaa7f

Browse files
committed
Model content-type setters as HeaderWrites.
1 parent 9ea8b34 commit 0beaa7f

File tree

1 file changed

+77
-31
lines changed

1 file changed

+77
-31
lines changed

ql/src/experimental/frameworks/CleverGo.qll

Lines changed: 77 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -200,58 +200,98 @@ private module CleverGo {
200200
*/
201201
private class HttpResponseBodyStaticContentType extends HTTP::ResponseBody::Range {
202202
string contentTypeString;
203+
DataFlow::Node receiverNode;
203204

204205
HttpResponseBodyStaticContentType() {
205206
exists(string package, string receiverName |
206-
setsBodyAndStaticContentType(package, receiverName, this, contentTypeString)
207-
or
208-
exists(DataFlow::CallNode bodySetterCall, DataFlow::CallNode contentTypeSetterCall |
209-
setsBody(package, receiverName, bodySetterCall, this) and
210-
setsStaticContentType(package, receiverName, contentTypeSetterCall, contentTypeString)
211-
|
212-
contentTypeSetterCall.getReceiver().getAPredecessor*() =
213-
bodySetterCall.getReceiver().getAPredecessor*()
214-
)
207+
setsBodyAndStaticContentType(package, receiverName, this, contentTypeString, receiverNode)
215208
)
216209
}
217210

218211
override string getAContentType() { result = contentTypeString }
219212

220-
override HTTP::ResponseWriter getResponseWriter() { none() }
213+
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
221214
}
222215

223216
/**
224217
* Models HTTP ResponseBody where the content-type can be dynamically set by the caller.
225218
*/
226219
private class HttpResponseBodyDynamicContentType extends HTTP::ResponseBody::Range {
227220
DataFlow::Node contentTypeNode;
221+
DataFlow::Node receiverNode;
228222

229223
HttpResponseBodyDynamicContentType() {
230224
exists(string package, string receiverName |
231-
setsBodyAndDynamicContentType(package, receiverName, this, contentTypeNode)
232-
or
233-
exists(DataFlow::CallNode bodySetterCall, DataFlow::CallNode contentTypeSetterCall |
234-
setsBody(package, receiverName, bodySetterCall, this) and
235-
setsDynamicContentType(package, receiverName, contentTypeSetterCall, contentTypeNode)
236-
|
237-
contentTypeSetterCall.getReceiver().getAPredecessor*() =
238-
bodySetterCall.getReceiver().getAPredecessor*()
239-
)
225+
setsBodyAndDynamicContentType(package, receiverName, this, contentTypeNode, receiverNode)
240226
)
241227
}
242228

243229
override DataFlow::Node getAContentTypeNode() { result = contentTypeNode }
244230

245-
override HTTP::ResponseWriter getResponseWriter() { none() }
231+
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
232+
}
233+
234+
/**
235+
* Models HTTP ResponseBody where the content-type is set by another call.
236+
*/
237+
private class HttpResponseBodyNoContentType extends HTTP::ResponseBody::Range {
238+
private DataFlow::Node receiverNode;
239+
240+
HttpResponseBodyNoContentType() {
241+
exists(string package, string receiverName |
242+
setsBody(package, receiverName, receiverNode, this)
243+
)
244+
}
245+
246+
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
247+
}
248+
249+
/**
250+
* Models an HTTP static content-type setter for package: clevergo.tech/clevergo@v0.5.2
251+
*/
252+
private class StaticContentTypeSetter extends HTTP::HeaderWrite::Range, DataFlow::CallNode {
253+
DataFlow::Node receiverNode;
254+
string contentType;
255+
256+
StaticContentTypeSetter() { setsStaticContentType(_, _, this, contentType, receiverNode) }
257+
258+
override string getHeaderName() { result = "content-type" }
259+
260+
override string getHeaderValue() { result = contentType }
261+
262+
override DataFlow::Node getName() { none() }
263+
264+
override DataFlow::Node getValue() { none() }
265+
266+
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
267+
}
268+
269+
/**
270+
* Models an HTTP dynamic content-type setter for package: clevergo.tech/clevergo@v0.5.2
271+
*/
272+
private class DynamicContentTypeSetter extends HTTP::HeaderWrite::Range, DataFlow::CallNode {
273+
DataFlow::Node receiverNode;
274+
DataFlow::Node contentType;
275+
276+
DynamicContentTypeSetter() { setsDynamicContentType(_, _, this, contentType, receiverNode) }
277+
278+
override string getHeaderName() { result = "content-type" }
279+
280+
override DataFlow::Node getName() { none() }
281+
282+
override DataFlow::Node getValue() { result = contentType }
283+
284+
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
246285
}
247286

248287
// Holds for a call that sets the body.
249288
private predicate setsBody(
250-
string package, string receiverName, DataFlow::CallNode bodySetterCall, DataFlow::Node bodyNode
289+
string package, string receiverName, DataFlow::Node receiverNode, DataFlow::Node bodyNode
251290
) {
252-
exists(string methodName, Method m |
291+
exists(string methodName, Method m, DataFlow::CallNode bodySetterCall |
253292
m.hasQualifiedName(package, receiverName, methodName) and
254-
bodySetterCall = m.getACall()
293+
bodySetterCall = m.getACall() and
294+
receiverNode = bodySetterCall.getReceiver()
255295
|
256296
package = packagePath() and
257297
(
@@ -272,12 +312,14 @@ private module CleverGo {
272312

273313
// Holds for a call that sets the body; the content-type is static and implicit.
274314
private predicate setsBodyAndStaticContentType(
275-
string package, string receiverName, DataFlow::Node bodyNode, string contentTypeString
315+
string package, string receiverName, DataFlow::Node bodyNode, string contentTypeString,
316+
DataFlow::Node receiverNode
276317
) {
277318
// One call sets both body and content-type (which is implicit in the func name).
278319
exists(string methodName, Method m, DataFlow::CallNode bodySetterCall |
279320
m.hasQualifiedName(package, receiverName, methodName) and
280-
bodySetterCall = m.getACall()
321+
bodySetterCall = m.getACall() and
322+
receiverNode = bodySetterCall.getReceiver()
281323
|
282324
package = packagePath() and
283325
(
@@ -360,11 +402,13 @@ private module CleverGo {
360402

361403
// Holds for a call that sets the body; the content-type is a parameter.
362404
private predicate setsBodyAndDynamicContentType(
363-
string package, string receiverName, DataFlow::Node bodyNode, DataFlow::Node contentTypeNode
405+
string package, string receiverName, DataFlow::Node bodyNode, DataFlow::Node contentTypeNode,
406+
DataFlow::Node receiverNode
364407
) {
365408
exists(string methodName, Method m, DataFlow::CallNode bodySetterCall |
366409
m.hasQualifiedName(package, receiverName, methodName) and
367-
bodySetterCall = m.getACall()
410+
bodySetterCall = m.getACall() and
411+
receiverNode = bodySetterCall.getReceiver()
368412
|
369413
package = packagePath() and
370414
(
@@ -388,11 +432,12 @@ private module CleverGo {
388432
// Holds for a call that sets the content-type (implicit).
389433
private predicate setsStaticContentType(
390434
string package, string receiverName, DataFlow::CallNode contentTypeSetterCall,
391-
string contentType
435+
string contentType, DataFlow::Node receiverNode
392436
) {
393437
exists(string methodName, Method m |
394438
m.hasQualifiedName(package, receiverName, methodName) and
395-
contentTypeSetterCall = m.getACall()
439+
contentTypeSetterCall = m.getACall() and
440+
receiverNode = contentTypeSetterCall.getReceiver()
396441
|
397442
package = packagePath() and
398443
(
@@ -422,11 +467,12 @@ private module CleverGo {
422467
// Holds for a call that sets the content-type via a parameter.
423468
private predicate setsDynamicContentType(
424469
string package, string receiverName, DataFlow::CallNode contentTypeSetterCall,
425-
DataFlow::Node contentTypeNode
470+
DataFlow::Node contentTypeNode, DataFlow::Node receiverNode
426471
) {
427472
exists(string methodName, Method m |
428473
m.hasQualifiedName(package, receiverName, methodName) and
429-
contentTypeSetterCall = m.getACall()
474+
contentTypeSetterCall = m.getACall() and
475+
receiverNode = contentTypeSetterCall.getReceiver()
430476
|
431477
package = packagePath() and
432478
(

0 commit comments

Comments
 (0)