@@ -7,6 +7,7 @@ private import python
77private import experimental.dataflow.DataFlow
88private import experimental.dataflow.RemoteFlowSources
99private import experimental.semmle.python.Concepts
10+ import semmle.python.regex
1011
1112/**
1213 * Provides models for the `django` PyPI package.
@@ -229,6 +230,22 @@ private module Django {
229230 }
230231 }
231232
233+ /**
234+ * A regex that is used in a call to `django.urls.re_path`.
235+ *
236+ * Needs this subclass to be considered a RegexString.
237+ */
238+ private class DjangoUrlsRePathRegex extends RegexString {
239+ DjangoUrlsRePathCall rePathCall ;
240+
241+ DjangoUrlsRePathRegex ( ) {
242+ this instanceof StrConst and
243+ DataFlow:: localFlow ( DataFlow:: exprNode ( this ) , rePathCall .getUrlPatternArg ( ) )
244+ }
245+
246+ DjangoUrlsRePathCall getRePathCall ( ) { result = rePathCall }
247+ }
248+
232249 /**
233250 * A call to `django.urls.re_path`.
234251 *
@@ -250,6 +267,29 @@ private module Django {
250267 )
251268 }
252269
253- override Parameter getARoutedParameter ( ) { none ( ) }
270+ override Parameter getARoutedParameter ( ) {
271+ // If we don't know the URL pattern, we simply mark all parameters as a routed
272+ // parameter. This should give us more RemoteFlowSources but could also lead to
273+ // more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
274+ exists ( DjangoRouteHandler routeHandler | routeHandler = this .getARouteHandler ( ) |
275+ not exists ( this .getUrlPattern ( ) ) and
276+ result in [ routeHandler .getArg ( _) , routeHandler .getArgByName ( _) ] and
277+ not result = any ( int i | i <= routeHandler .getRequestParamIndex ( ) | routeHandler .getArg ( i ) )
278+ )
279+ or
280+ exists ( DjangoRouteHandler routeHandler , DjangoUrlsRePathRegex regex |
281+ routeHandler = this .getARouteHandler ( ) and
282+ regex .getRePathCall ( ) = this
283+ |
284+ // either using named capture groups (passed as keyword arguments) or using
285+ // unnamed capture groups (passed as positional arguments)
286+ not exists ( regex .getGroupName ( _, _) ) and
287+ // first group will have group number 1
288+ result =
289+ routeHandler .getArg ( routeHandler .getRequestParamIndex ( ) + regex .getGroupNumber ( _, _) )
290+ or
291+ result = routeHandler .getArgByName ( regex .getGroupName ( _, _) )
292+ )
293+ }
254294 }
255295}
0 commit comments