Skip to content

Commit 9834659

Browse files
committed
Polish CookieWrite
1 parent 6504429 commit 9834659

3 files changed

Lines changed: 28 additions & 8 deletions

File tree

python/ql/src/experimental/Security/CWE-614/InsecureCookie.ql

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@ import semmle.python.dataflow.new.DataFlow
1515
import semmle.python.Concepts
1616
import experimental.semmle.python.Concepts
1717

18-
from HeaderDeclaration headerWrite, False f, None n
18+
from Expr cookieExpr, False f, None n
1919
where
20-
exists(StrConst headerName, StrConst headerValue |
20+
exists(HeaderDeclaration headerWrite, StrConst headerName, StrConst headerValue |
2121
headerName.getText() = "Set-Cookie" and
2222
DataFlow::exprNode(headerName).(DataFlow::LocalSourceNode).flowsTo(headerWrite.getNameArg()) and
2323
not headerValue.getText().regexpMatch(".*; *Secure;.*") and
24-
DataFlow::exprNode(headerValue).(DataFlow::LocalSourceNode).flowsTo(headerWrite.getValueArg())
24+
DataFlow::exprNode(headerValue).(DataFlow::LocalSourceNode).flowsTo(headerWrite.getValueArg()) and
25+
cookieExpr = headerWrite.asExpr()
2526
)
2627
or
27-
[DataFlow::exprNode(f), DataFlow::exprNode(n)]
28-
.(DataFlow::LocalSourceNode)
29-
.flowsTo(headerWrite.(DataFlow::CallCfgNode).getArgByName("secure"))
30-
select headerWrite, "Cookie is added to response without the 'secure' flag being set."
28+
exists(ExperimentalHTTP::CookieWrite cookieWrite |
29+
[DataFlow::exprNode(f), DataFlow::exprNode(n)]
30+
.(DataFlow::LocalSourceNode)
31+
.flowsTo(cookieWrite.(DataFlow::CallCfgNode).getArgByName("secure")) and
32+
cookieExpr = cookieWrite.asExpr()
33+
)
34+
select cookieExpr, "Cookie is added to response without the 'secure' flag being set."

python/ql/src/experimental/semmle/python/frameworks/Flask.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,20 @@ module ExperimentalFlask {
8181

8282
override DataFlow::Node getValueArg() { result.asExpr() = item.getValue() }
8383
}
84+
85+
class DjangoSetCookieCall extends DataFlow::CallCfgNode, ExperimentalHTTP::CookieWrite::Range {
86+
DjangoSetCookieCall() {
87+
this =
88+
[Flask::Response::classRef(), flaskMakeResponse()]
89+
.getReturn()
90+
.getMember("set_cookie")
91+
.getACall()
92+
}
93+
94+
override DataFlow::Node getHeaderArg() { none() }
95+
96+
override DataFlow::Node getNameArg() { result = this.getArg(0) }
97+
98+
override DataFlow::Node getValueArg() { result = this.getArg(1) }
99+
}
84100
}

python/ql/test/experimental/query-tests/Security/CWE-614/django_bad.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ def django_response(request):
99

1010
def django_response(request):
1111
resp = django.http.HttpResponse()
12-
resp.set_cookie("name", "value")
12+
resp.set_cookie("name", "value", secure=False)
1313
return resp

0 commit comments

Comments
 (0)