Skip to content

Commit ac28372

Browse files
Add httponly tests for aspnet core + fixes
1 parent fa52514 commit ac28372

File tree

17 files changed

+220
-3
lines changed

17 files changed

+220
-3
lines changed

csharp/ql/src/Security Features/CWE-1004/CookieWithoutHttpOnly.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ predicate cookieAppendHttpOnlyByDefault() {
2222
getAValueForCookiePolicyProp("HttpOnly").getValue() = "1"
2323
or
2424
// there is an `OnAppendCookie` callback that sets `HttpOnly` to true
25-
not OnAppendCookieHttpOnlyTracking::flowTo(_)
25+
OnAppendCookieHttpOnlyTracking::flowTo(_)
2626
}
2727

2828
predicate httpOnlyFalse(ObjectCreation oc) {
@@ -90,7 +90,7 @@ predicate nonHttpOnlyCookieCall(Call c) {
9090
)
9191
}
9292

93-
predicate nonHttpOnlyPolicyAssignment(Assignment a, Expr val) {
93+
predicate nonHttpOnlyCookieBuilderAssignment(Assignment a, Expr val) {
9494
val.getValue() = "false" and
9595
exists(PropertyWrite pw |
9696
(
@@ -111,7 +111,7 @@ where
111111
or
112112
exists(Assignment a |
113113
httpOnlySink = a.getRValue() and
114-
nonHttpOnlyPolicyAssignment(a, _)
114+
nonHttpOnlyCookieBuilderAssignment(a, _)
115115
)
116116
)
117117
select httpOnlySink, "Cookie attribute 'HttpOnly' is not set to true."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| Program.cs:13:33:13:37 | false | Cookie attribute 'HttpOnly' is not set to true. |
2+
| Program.cs:20:39:20:43 | false | Cookie attribute 'HttpOnly' is not set to true. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: Security Features/CWE-1004/CookieWithoutHttpOnly.ql
2+
postprocess: utils/test/InlineExpectationsTestQuery.ql
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Microsoft.AspNetCore.Builder;
2+
using Microsoft.AspNetCore.Hosting;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.AspNetCore.Http;
5+
using Microsoft.AspNetCore.Authentication;
6+
7+
public class Startup
8+
{
9+
public void ConfigureServices(IServiceCollection services)
10+
{
11+
services.AddAuthentication().AddCookie(o =>
12+
{
13+
o.Cookie.HttpOnly = false; // $ Alert
14+
o.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None;
15+
});
16+
17+
services.AddSession(options =>
18+
{
19+
options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None;
20+
options.Cookie.HttpOnly = false; // $ Alert
21+
});
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| Program.cs:5:9:5:48 | call to method Append | Cookie attribute 'HttpOnly' is not set to true. |
2+
| Program.cs:10:29:10:73 | object creation of type CookieOptions | Cookie attribute 'HttpOnly' is not set to true. |
3+
| Program.cs:42:29:42:73 | object creation of type CookieOptions | Cookie attribute 'HttpOnly' is not set to true. |
4+
| Program.cs:49:29:49:94 | object creation of type CookieOptions | Cookie attribute 'HttpOnly' is not set to true. |
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: Security Features/CWE-1004/CookieWithoutHttpOnly.ql
2+
postprocess: utils/test/InlineExpectationsTestQuery.ql
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
public class MyController : Microsoft.AspNetCore.Mvc.Controller
2+
{
3+
public void CookieDefault()
4+
{
5+
Response.Cookies.Append("auth", "value"); // $Alert // BAD: HttpOnly is set to false by default
6+
}
7+
8+
public void CookieDefault2()
9+
{
10+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $Alert
11+
Response.Cookies.Append("auth", "value", cookieOptions); // BAD: HttpOnly is set to false by default
12+
}
13+
14+
public void CookieDelete()
15+
{
16+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
17+
Response.Cookies.Delete("auth", cookieOptions); // GOOD: Delete call
18+
}
19+
20+
void CookieDirectFalseForgery()
21+
{
22+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
23+
cookieOptions.HttpOnly = false;
24+
Response.Cookies.Append("antiforgerytoken", "secret", cookieOptions); // GOOD: not an auth cookie
25+
}
26+
27+
void CookieDirectTrue()
28+
{
29+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
30+
cookieOptions.HttpOnly = true;
31+
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
32+
}
33+
34+
void CookieDirectTrueInitializer()
35+
{
36+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = true };
37+
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
38+
}
39+
40+
void CookieDirectFalse()
41+
{
42+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $Alert
43+
cookieOptions.HttpOnly = false;
44+
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD
45+
}
46+
47+
void CookieDirectFalseInitializer()
48+
{
49+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = false }; // $Alert
50+
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD
51+
}
52+
53+
void CookieIntermediateTrue()
54+
{
55+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
56+
bool v = true;
57+
cookieOptions.HttpOnly = v;
58+
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow
59+
}
60+
61+
void CookieIntermediateTrueInitializer()
62+
{
63+
bool v = true;
64+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = v };
65+
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow
66+
}
67+
68+
void CookieIntermediateFalse()
69+
{
70+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $MISSING:Alert
71+
bool v = false;
72+
cookieOptions.HttpOnly = v;
73+
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD, but not detected
74+
}
75+
76+
void CookieIntermediateFalseInitializer()
77+
{
78+
bool v = false;
79+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = v }; // $MISSING:Alert
80+
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD, but not detected
81+
}
82+
}

csharp/ql/test/query-tests/Security Features/CWE-1004/HttpOnlyCookie/AspNetCore/PolicyAlways/CookieWithoutHttpOnly.expected

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: Security Features/CWE-1004/CookieWithoutHttpOnly.ql
2+
postprocess: utils/test/InlineExpectationsTestQuery.ql
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Microsoft.AspNetCore.Builder;
2+
using Microsoft.AspNetCore.Hosting;
3+
4+
public class MyController : Microsoft.AspNetCore.Mvc.Controller
5+
{
6+
public void CookieDefault()
7+
{
8+
Response.Cookies.Append("auth", "secret"); // GOOD: HttpOnly is set in policy
9+
}
10+
11+
public void CookieDefault2()
12+
{
13+
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
14+
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: HttpOnly is set in policy
15+
}
16+
}
17+
18+
public class Startup
19+
{
20+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
21+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
22+
{
23+
app.UseCookiePolicy(new CookiePolicyOptions() { HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always });
24+
}
25+
}

0 commit comments

Comments
 (0)