Skip to content

Commit a0867b4

Browse files
committed
Python: More HTTP request handler *args/**kwargs modeling
I looked through all `override Parameter getARoutedParameter() {` in our codebase, and we now modeling *args/**kwargs for all of them 👍
1 parent 37d03ee commit a0867b4

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

python/ql/lib/semmle/python/frameworks/FastApi.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ private module FastApi {
6666
result = this.getARequestHandler().getArgByName(_) and
6767
// type-annotated with `Response`
6868
not any(Response::RequestHandlerParam src).asExpr() = result
69+
or
70+
// **kwargs
71+
result = this.getARequestHandler().getKwarg()
6972
}
7073

7174
override DataFlow::Node getUrlPatternArg() {

python/ql/lib/semmle/python/frameworks/Flask.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ module Flask {
279279
name = match.regexpCapture(werkzeug_rule_re(), 4)
280280
)
281281
)
282+
or
283+
// **kwargs
284+
result = this.getARequestHandler().getKwarg()
282285
}
283286

284287
override string getFramework() { result = "Flask" }
@@ -347,6 +350,12 @@ module Flask {
347350
// more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
348351
result in [this.getArg(_), this.getArgByName(_)] and
349352
not result = this.getArg(0)
353+
or
354+
// *args
355+
result = this.getVararg()
356+
or
357+
// **kwargs
358+
result = this.getKwarg()
350359
}
351360

352361
override string getFramework() { result = "Flask" }

python/ql/lib/semmle/python/frameworks/Tornado.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,10 @@ module Tornado {
416416
// more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
417417
exists(Function requestHandler | requestHandler = this.getARequestHandler() |
418418
not exists(this.getUrlPattern()) and
419-
result in [requestHandler.getArg(_), requestHandler.getArgByName(_)] and
419+
result in [
420+
requestHandler.getArg(_), requestHandler.getArgByName(_),
421+
requestHandler.getVararg().(Parameter), requestHandler.getKwarg().(Parameter)
422+
] and
420423
not result = requestHandler.getArg(0)
421424
)
422425
or
@@ -429,6 +432,12 @@ module Tornado {
429432
result = requestHandler.getArg(regex.getGroupNumber(_, _))
430433
or
431434
result = requestHandler.getArgByName(regex.getGroupName(_, _))
435+
or
436+
exists(regex.getGroupNumber(_, _)) and
437+
result = requestHandler.getVararg()
438+
or
439+
exists(regex.getGroupName(_, _)) and
440+
result = requestHandler.getKwarg()
432441
)
433442
}
434443
}
@@ -446,7 +455,10 @@ module Tornado {
446455
// Since we don't know the URL pattern, we simply mark all parameters as a routed
447456
// parameter. This should give us more RemoteFlowSources but could also lead to
448457
// more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
449-
result in [this.getArg(_), this.getArgByName(_)] and
458+
result in [
459+
this.getArg(_), this.getArgByName(_), this.getVararg().(Parameter),
460+
this.getKwarg().(Parameter)
461+
] and
450462
not result = this.getArg(0)
451463
}
452464

0 commit comments

Comments
 (0)