Python: Model routed parameter flow to *args and **kwargs in Django + rest framework

This commit is contained in:
Rasmus Wriedt Larsen
2023-10-23 17:15:26 +02:00
parent 24687b4156
commit e8f548ab52
4 changed files with 29 additions and 10 deletions

View File

@@ -928,7 +928,10 @@ module Http {
override Parameter getARoutedParameter() {
result = rs.getARoutedParameter() and
result in [this.getArg(_), this.getArgByName(_)]
result in [
this.getArg(_), this.getArgByName(_), this.getVararg().(Parameter),
this.getKwarg().(Parameter)
]
}
override string getFramework() { result = rs.getFramework() }

View File

@@ -2416,7 +2416,10 @@ module PrivateDjango {
// Since we don't know the URL pattern, we simply mark all parameters as a routed
// parameter. This should give us more RemoteFlowSources but could also lead to
// more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
result in [this.getArg(_), this.getArgByName(_)] and
result in [
this.getArg(_), this.getArgByName(_), //
this.getVararg().(Parameter), this.getKwarg().(Parameter), // TODO: These sources should be modeled as storing content!
] and
not result = any(int i | i < this.getFirstPossibleRoutedParamIndex() | this.getArg(i))
}
@@ -2452,13 +2455,20 @@ module PrivateDjango {
// more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
exists(DjangoRouteHandler routeHandler | routeHandler = this.getARequestHandler() |
not exists(this.getUrlPattern()) and
result in [routeHandler.getArg(_), routeHandler.getArgByName(_)] and
result in [
routeHandler.getArg(_), routeHandler.getArgByName(_), //
routeHandler.getVararg().(Parameter), routeHandler.getKwarg().(Parameter), // TODO: These sources should be modeled as storing content!
] and
not result =
any(int i | i < routeHandler.getFirstPossibleRoutedParamIndex() | routeHandler.getArg(i))
)
or
exists(string name |
result = this.getARequestHandler().getArgByName(name) and
(
result = this.getARequestHandler().getKwarg() // TODO: These sources should be modeled as storing content!
or
result = this.getARequestHandler().getArgByName(name)
) and
exists(string match |
match = this.getUrlPattern().regexpFind(pathRoutedParameterRegex(), _, _) and
name = match.regexpCapture(pathRoutedParameterRegex(), 2)
@@ -2475,7 +2485,10 @@ module PrivateDjango {
// more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
exists(DjangoRouteHandler routeHandler | routeHandler = this.getARequestHandler() |
not exists(this.getUrlPattern()) and
result in [routeHandler.getArg(_), routeHandler.getArgByName(_)] and
result in [
routeHandler.getArg(_), routeHandler.getArgByName(_), //
routeHandler.getVararg().(Parameter), routeHandler.getKwarg().(Parameter), // TODO: These sources should be modeled as storing content!
] and
not result =
any(int i | i < routeHandler.getFirstPossibleRoutedParamIndex() | routeHandler.getArg(i))
)

View File

@@ -172,7 +172,10 @@ private module RestFramework {
// Since we don't know the URL pattern, we simply mark all parameters as a routed
// parameter. This should give us more RemoteFlowSources but could also lead to
// more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
result in [this.getArg(_), this.getArgByName(_)] and
result in [
this.getArg(_), this.getArgByName(_), //
this.getVararg().(Parameter), this.getKwarg().(Parameter), // TODO: These sources should be modeled as storing content!
] and
not result = any(int i | i < this.getFirstPossibleRoutedParamIndex() | this.getArg(i))
}

View File

@@ -174,11 +174,11 @@ class ClassView(View):
)
def kwargs_param(request, **kwargs): # $ requestHandler
def kwargs_param(request, **kwargs): # $ requestHandler routedParameter=kwargs
ensure_tainted(
kwargs, # $ MISSING: tainted
kwargs["foo"], # $ MISSING: tainted
kwargs["bar"] # $ MISSING: tainted
kwargs, # $ tainted
kwargs["foo"], # $ tainted
kwargs["bar"] # $ tainted
)
ensure_tainted(request) # $ tainted