Skip to content

Commit b28d799

Browse files
Update ConceptsTests and make a fix
1 parent be87eb5 commit b28d799

File tree

9 files changed

+61
-34
lines changed

9 files changed

+61
-34
lines changed

python/ql/lib/semmle/python/Concepts.qll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,13 +1254,13 @@ module Http {
12541254
exists(this.getHeaderArg()) and
12551255
(
12561256
exists(StringLiteral sl |
1257-
sl.getText().regexpMatch("(?i).*;\\s*secure;.*") and
1257+
sl.getText().regexpMatch("(?i).*;\\s*secure(;.*|\\s*)") and
12581258
TaintTracking::localTaint(DataFlow::exprNode(sl), this.getHeaderArg()) and
12591259
b = true
12601260
)
12611261
or
12621262
exists(StringLiteral sl |
1263-
not sl.getText().regexpMatch("(?i).*;\\s*secure;.*") and
1263+
not sl.getText().regexpMatch("(?i).*;\\s*secure(;.*|\\s*)") and
12641264
DataFlow::localFlow(DataFlow::exprNode(sl), this.getHeaderArg()) and
12651265
b = false
12661266
)
@@ -1274,13 +1274,13 @@ module Http {
12741274
exists(this.getHeaderArg()) and
12751275
(
12761276
exists(StringLiteral sl |
1277-
sl.getText().regexpMatch("(?i).*;\\s*httponly;.*") and
1277+
sl.getText().regexpMatch("(?i).*;\\s*httponly(;.*|\\s*)") and
12781278
TaintTracking::localTaint(DataFlow::exprNode(sl), this.getHeaderArg()) and
12791279
b = true
12801280
)
12811281
or
12821282
exists(StringLiteral sl |
1283-
not sl.getText().regexpMatch("(?i).*;\\s*httponly;.*") and
1283+
not sl.getText().regexpMatch("(?i).*;\\s*httponly(;.*|\\s*)") and
12841284
DataFlow::localFlow(DataFlow::exprNode(sl), this.getHeaderArg()) and
12851285
b = false
12861286
)
@@ -1294,25 +1294,25 @@ module Http {
12941294
exists(this.getHeaderArg()) and
12951295
(
12961296
exists(StringLiteral sl |
1297-
sl.getText().regexpMatch("(?i).*;\\s*samesite=strict;.*") and
1297+
sl.getText().regexpMatch("(?i).*;\\s*samesite=strict(;.*|\\s*)") and
12981298
TaintTracking::localTaint(DataFlow::exprNode(sl), this.getHeaderArg()) and
12991299
v instanceof SameSiteStrict
13001300
)
13011301
or
13021302
exists(StringLiteral sl |
1303-
sl.getText().regexpMatch("(?i).*;\\s*samesite=lax;.*") and
1303+
sl.getText().regexpMatch("(?i).*;\\s*samesite=lax(;.*|\\s*)") and
13041304
TaintTracking::localTaint(DataFlow::exprNode(sl), this.getHeaderArg()) and
13051305
v instanceof SameSiteLax
13061306
)
13071307
or
13081308
exists(StringLiteral sl |
1309-
sl.getText().regexpMatch("(?i).*;\\s*samesite=none;.*") and
1309+
sl.getText().regexpMatch("(?i).*;\\s*samesite=none(;.*|\\s*)") and
13101310
TaintTracking::localTaint(DataFlow::exprNode(sl), this.getHeaderArg()) and
13111311
v instanceof SameSiteNone
13121312
)
13131313
or
13141314
exists(StringLiteral sl |
1315-
not sl.getText().regexpMatch("(?i).*;\\s*samesite=(strict|lax|none);.*") and
1315+
not sl.getText().regexpMatch("(?i).*;\\s*samesite=(strict|lax|none)(;.*|\\s*)") and
13161316
DataFlow::localFlow(DataFlow::exprNode(sl), this.getHeaderArg()) and
13171317
v instanceof SameSiteLax // Lax is the default
13181318
)

python/ql/test/experimental/meta/ConceptsTest.qll

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,10 @@ module HttpServerHttpRedirectResponseTest implements TestSig {
405405

406406
module HttpServerCookieWriteTest implements TestSig {
407407
string getARelevantTag() {
408-
result in ["CookieWrite", "CookieRawHeader", "CookieName", "CookieValue"]
408+
result in [
409+
"CookieWrite", "CookieRawHeader", "CookieName", "CookieValue", "CookieSecure",
410+
"CookieHttpOnly", "CookieSameSite"
411+
]
409412
}
410413

411414
predicate hasActualResult(Location location, string element, string tag, string value) {
@@ -428,6 +431,20 @@ module HttpServerCookieWriteTest implements TestSig {
428431
element = cookieWrite.toString() and
429432
value = prettyNodeForInlineTest(cookieWrite.getValueArg()) and
430433
tag = "CookieValue"
434+
or
435+
element = cookieWrite.toString() and
436+
value = any(boolean b | cookieWrite.hasSecureFlag(b)).toString() and
437+
tag = "CookieSecure"
438+
or
439+
element = cookieWrite.toString() and
440+
value = any(boolean b | cookieWrite.hasHttpOnlyFlag(b)).toString() and
441+
tag = "CookieHttpOnly"
442+
or
443+
element = cookieWrite.toString() and
444+
value =
445+
any(Http::Server::CookieWrite::SameSiteValue v | cookieWrite.hasSameSiteAttribute(v))
446+
.toString() and
447+
tag = "CookieSameSite"
431448
)
432449
)
433450
}

python/ql/test/library-tests/frameworks/aiohttp/response_test.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,12 @@ async def streaming_response(request): # $ requestHandler
9696
async def setting_cookie(request): # $ requestHandler
9797
resp = web.Response(text="foo") # $ HttpResponse mimetype=text/plain responseBody="foo"
9898
resp.cookies["key"] = "value" # $ CookieWrite CookieName="key" CookieValue="value"
99-
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2"
100-
resp.set_cookie("key3", "value3") # $ CookieWrite CookieName="key3" CookieValue="value3"
101-
resp.set_cookie(name="key3", value="value3") # $ CookieWrite CookieName="key3" CookieValue="value3"
99+
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
100+
resp.set_cookie("key3", "value3") # $ CookieWrite CookieName="key3" CookieValue="value3" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
101+
resp.set_cookie(name="key3", value="value3") # $ CookieWrite CookieName="key3" CookieValue="value3" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
102102
resp.del_cookie("key4") # $ CookieWrite CookieName="key4"
103+
resp.set_cookie(name="key5", value="value5", secure=True, httponly=True, samesite="Strict") # $ CookieWrite CookieName="key5" CookieValue="value5" CookieSecure=true CookieHttpOnly=true CookieSameSite=Strict
104+
resp.headers["Set-Cookie"] = "key6=value6; Secure; HttpOnly; SameSite=Strict" # $ headerWriteName="Set-Cookie" headerWriteValue="key6=value6; Secure; HttpOnly; SameSite=Strict" CookieWrite CookieRawHeader="key6=value6; Secure; HttpOnly; SameSite=Strict" CookieSecure=true CookieHttpOnly=true CookieSameSite=Strict
103105
return resp
104106

105107

python/ql/test/library-tests/frameworks/django-v2-v3/response_test.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,12 @@ def safe__custom_json_response(request):
128128

129129
def setting_cookie(request):
130130
resp = HttpResponse() # $ HttpResponse mimetype=text/html
131-
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
132-
resp.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value"
133-
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2"
131+
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
132+
resp.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
133+
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
134134
resp.cookies["key3"] = "value3" # $ CookieWrite CookieName="key3" CookieValue="value3"
135135
resp.delete_cookie("key4") # $ CookieWrite CookieName="key4"
136136
resp.delete_cookie(key="key4") # $ CookieWrite CookieName="key4"
137-
resp["Set-Cookie"] = "key5=value5" # $ headerWriteName="Set-Cookie" headerWriteValue="key5=value5" CookieWrite CookieRawHeader="key5=value5"
137+
resp["Set-Cookie"] = "key5=value5" # $ headerWriteName="Set-Cookie" headerWriteValue="key5=value5" CookieWrite CookieRawHeader="key5=value5" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
138+
resp.set_cookie(key="key6", value="value6", secure=True, httponly=False, samesite="None") # $ CookieWrite CookieName="key6" CookieValue="value6" CookieSecure=true CookieHttpOnly=false CookieSameSite=None
138139
return resp

python/ql/test/library-tests/frameworks/fastapi/response_test.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99

1010
@app.get("/response_parameter") # $ routeSetup="/response_parameter"
1111
async def response_parameter(response: Response): # $ requestHandler
12-
response.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
13-
response.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value"
14-
response.headers.append("Set-Cookie", "key2=value2") # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2"
15-
response.headers.append(key="Set-Cookie", value="key2=value2") # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2"
12+
response.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
13+
response.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
14+
response.set_cookie(key="key", value="value", secure=False, httponly=True, samesite="Lax") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=true CookieSameSite=Lax
15+
response.headers.append("Set-Cookie", "key2=value2") # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
16+
response.headers.append(key="Set-Cookie", value="key2=value2") # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
1617
response.headers["X-MyHeader"] = "header-value" # $ headerWriteName="X-MyHeader" headerWriteValue="header-value"
1718
response.status_code = 418
1819
return {"message": "response as parameter"} # $ HttpResponse mimetype=application/json responseBody=Dict
@@ -44,7 +45,7 @@ async def response_parameter_custom_type(response: MyXmlResponse): # $ requestHa
4445
# propagated to the final response though.
4546
print(type(response))
4647
assert type(response) == fastapi.responses.Response
47-
response.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
48+
response.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
4849
response.headers["Custom-Response-Type"] = "yes, but only after function has run" # $ headerWriteName="Custom-Response-Type" headerWriteValue="yes, but only after function has run"
4950
xml_data = "<foo>FOO</foo>"
5051
return xml_data # $ HttpResponse responseBody=xml_data mimetype=application/xml

python/ql/test/library-tests/frameworks/flask/response_test.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,17 @@ def redirect_simple(): # $requestHandler
203203
# Cookies
204204
################################################################################
205205

206+
def unk():
207+
return
208+
206209
@app.route("/setting_cookie") # $routeSetup="/setting_cookie"
207210
def setting_cookie(): # $requestHandler
208211
resp = make_response() # $ HttpResponse mimetype=text/html
209-
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
210-
resp.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value"
211-
resp.headers.add("Set-Cookie", "key2=value2") # $ headerWriteNameUnsanitized="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2"
212+
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
213+
resp.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
214+
resp.set_cookie(key="key", value="value", secure=True, httponly=True, samesite="Strict") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=true CookieHttpOnly=true CookieSameSite=Strict
215+
resp.set_cookie(key="key", value="value", secure=unk(), httponly=unk(), samesite=unk()) # $ CookieWrite CookieName="key" CookieValue="value"
216+
resp.headers.add("Set-Cookie", "key2=value2") # $ headerWriteNameUnsanitized="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
212217
resp.delete_cookie("key3") # $ CookieWrite CookieName="key3"
213218
resp.delete_cookie(key="key3") # $ CookieWrite CookieName="key3"
214219
return resp # $ SPURIOUS: HttpResponse mimetype=text/html responseBody=resp

python/ql/test/library-tests/frameworks/pyramid/pyramid_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ def test2(request): # $ requestHandler
8686
def test3(ctx, req): # $ requestHandler
8787
ensure_tainted(req) # $ tainted
8888
resp = req.response # $ HttpResponse mimetype=text/html
89-
resp.set_cookie("hi", "there") # $ CookieWrite CookieName="hi" CookieValue="there"
90-
resp.set_cookie(value="there", name="hi") # $ CookieWrite CookieName="hi" CookieValue="there"
89+
resp.set_cookie("hi", "there") # $ CookieWrite CookieName="hi" CookieValue="there" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
90+
resp.set_cookie(value="there", name="hi") # $ CookieWrite CookieName="hi" CookieValue="there" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
91+
resp.set_cookie("hi", "there", secure=True, httponly=True, samesite="Strict") # $ CookieWrite CookieName="hi" CookieValue="there" CookieSecure=true CookieHttpOnly=true CookieSameSite=Strict
9192
return "Ok" # $ HttpResponse responseBody="Ok" mimetype=text/html
9293

9394
@view_config(route_name="test4", renderer="string") # $ routeSetup

python/ql/test/library-tests/frameworks/rest_framework/response_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ def normal_response(request): # $ requestHandler
77
# has no pre-defined content type, since that will be negotiated
88
# see https://www.django-rest-framework.org/api-guide/responses/
99
data = "data"
10-
resp = Response(data) # $ HttpResponse responseBody=data
10+
resp = Response(data) # $ HttpResponse responseBody=data mimetype=text/html
1111
return resp
1212

1313
@api_view()
@@ -25,10 +25,10 @@ def plain_text_response(request): # $ requestHandler
2525

2626
@api_view
2727
def setting_cookie(request):
28-
resp = Response() # $ HttpResponse
29-
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
30-
resp.set_cookie(key="key4", value="value") # $ CookieWrite CookieName="key4" CookieValue="value"
31-
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2"
28+
resp = Response() # $ HttpResponse mimetype=text/html
29+
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
30+
resp.set_cookie(key="key4", value="value") # $ CookieWrite CookieName="key4" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
31+
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
3232
resp.cookies["key3"] = "value3" # $ CookieWrite CookieName="key3" CookieValue="value3"
3333
resp.delete_cookie("key4") # $ CookieWrite CookieName="key4"
3434
resp.delete_cookie(key="key4") # $ CookieWrite CookieName="key4"

python/ql/test/library-tests/frameworks/rest_framework/testapp/views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ def function_based_view(request: Request): # $ requestHandler
6868
@api_view(["GET", "POST"])
6969
def cookie_test(request: Request): # $ requestHandler
7070
resp = Response("wat") # $ HttpResponse
71-
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
72-
resp.set_cookie(key="key4", value="value") # $ CookieWrite CookieName="key4" CookieValue="value"
73-
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2"
71+
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
72+
resp.set_cookie(key="key4", value="value") # $ CookieWrite CookieName="key4" CookieValue="value" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
73+
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2" CookieSecure=false CookieHttpOnly=false CookieSameSite=Lax
7474
resp.cookies["key3"] = "value3" # $ CookieWrite CookieName="key3" CookieValue="value3"
7575
return resp
7676

0 commit comments

Comments
 (0)