@@ -5,37 +5,25 @@ private import semmle.python.web.django.Shared
55private import semmle.python.web.Http
66
77/**
8+ * DEPRECATED: This class is internal to the django library modeling, and should
9+ * never be used by anyone.
10+ *
811 * A django.http.response.Response object
912 * This isn't really a "taint", but we use the value tracking machinery to
1013 * track the flow of response objects.
1114 */
12- class DjangoResponse extends TaintKind {
13- DjangoResponse ( ) { this = "django.response.HttpResponse" }
14- }
15+ deprecated class DjangoResponse = DjangoResponseKind ;
1516
16- private ClassValue theDjangoHttpResponseClass ( ) {
17- (
18- // version 1.x
19- result = Value:: named ( "django.http.response.HttpResponse" )
20- or
21- // version 2.x
22- // https://docs.djangoproject.com/en/2.2/ref/request-response/#httpresponse-objects
23- result = Value:: named ( "django.http.HttpResponse" )
24- ) and
25- // TODO: does this do anything? when could they be the same???
26- not result = theDjangoHttpRedirectClass ( )
17+ /** INTERNAL class used for tracking a django response object. */
18+ private class DjangoResponseKind extends TaintKind {
19+ DjangoResponseKind ( ) { this = "django.response.HttpResponse" }
2720}
2821
29- /** internal class used for tracking a django response. */
22+ /** INTERNAL taint-source used for tracking a django response object . */
3023private class DjangoResponseSource extends TaintSource {
31- DjangoResponseSource ( ) {
32- exists ( ClassValue cls |
33- cls .getASuperType ( ) = theDjangoHttpResponseClass ( ) and
34- cls .getACall ( ) = this
35- )
36- }
24+ DjangoResponseSource ( ) { exists ( DjangoContentResponseClass cls | cls .getACall ( ) = this ) }
3725
38- override predicate isSourceOf ( TaintKind kind ) { kind instanceof DjangoResponse }
26+ override predicate isSourceOf ( TaintKind kind ) { kind instanceof DjangoResponseKind }
3927
4028 override string toString ( ) { result = "django.http.response.HttpResponse" }
4129}
@@ -45,7 +33,7 @@ class DjangoResponseWrite extends HttpResponseTaintSink {
4533 DjangoResponseWrite ( ) {
4634 exists ( AttrNode meth , CallNode call |
4735 call .getFunction ( ) = meth and
48- any ( DjangoResponse response ) .taints ( meth .getObject ( "write" ) ) and
36+ any ( DjangoResponseKind response ) .taints ( meth .getObject ( "write" ) ) and
4937 this = call .getArg ( 0 )
5038 )
5139 }
@@ -55,27 +43,42 @@ class DjangoResponseWrite extends HttpResponseTaintSink {
5543 override string toString ( ) { result = "django.Response.write(...)" }
5644}
5745
58- /** An argument to initialization of a django response, which is vulnerable to external data (xss) */
46+ /**
47+ * An argument to initialization of a django response.
48+ */
5949class DjangoResponseContent extends HttpResponseTaintSink {
50+ DjangoContentResponseClass cls ;
51+ CallNode call ;
52+
6053 DjangoResponseContent ( ) {
61- exists ( CallNode call , ClassValue cls |
62- cls .getASuperType ( ) = theDjangoHttpResponseClass ( ) and
63- call .getFunction ( ) .pointsTo ( cls )
64- |
65- call .getArg ( 0 ) = this
66- or
67- call .getArgByName ( "content" ) = this
68- )
54+ call = cls .getACall ( ) and
55+ this = cls .getContentArg ( call )
6956 }
7057
7158 override predicate sinks ( TaintKind kind ) { kind instanceof StringKind }
7259
7360 override string toString ( ) { result = "django.Response(...)" }
7461}
7562
63+ /**
64+ * An argument to initialization of a django response, which is vulnerable to external data (XSS).
65+ */
66+ class DjangoResponseContentXSSVulnerable extends DjangoResponseContent {
67+ override DjangoXSSVulnerableResponseClass cls ;
68+
69+ DjangoResponseContentXSSVulnerable ( ) {
70+ not exists ( cls .getContentTypeArg ( call ) )
71+ or
72+ exists ( StringValue s |
73+ cls .getContentTypeArg ( call ) .pointsTo ( s ) and
74+ s .getText ( ) .matches ( "text/html%" )
75+ )
76+ }
77+ }
78+
7679class DjangoCookieSet extends CookieSet , CallNode {
7780 DjangoCookieSet ( ) {
78- any ( DjangoResponse r ) .taints ( this .getFunction ( ) .( AttrNode ) .getObject ( "set_cookie" ) )
81+ any ( DjangoResponseKind r ) .taints ( this .getFunction ( ) .( AttrNode ) .getObject ( "set_cookie" ) )
7982 }
8083
8184 override string toString ( ) { result = CallNode .super .toString ( ) }
0 commit comments