Add tests for secure cookie using aspnetcore

This commit is contained in:
Joe Farebrother
2025-10-23 21:46:38 +01:00
parent 3cdfa8e0ac
commit bb010fee6b
17 changed files with 216 additions and 6 deletions

View File

@@ -104,14 +104,12 @@ predicate insecureSecurePolicyAssignment(Assignment a, Expr val) {
)
}
from Expr secureSink, string msg
from Expr secureSink
where
insecureCookieCall(secureSink) and
msg = "Cookie attribute 'Secure' is not set to true."
insecureCookieCall(secureSink)
or
exists(Assignment a |
secureSink = a.getRValue() and
insecureSecurePolicyAssignment(a, _)
) and
msg = "Cookie security policy sets cookies as insecure by default."
select secureSink, msg
)
select secureSink, "Cookie attribute 'Secure' is not set to true."

View File

@@ -0,0 +1,2 @@
| Program.cs:14:37:14:85 | access to constant None | Cookie attribute 'Secure' is not set to true. |
| Program.cs:19:43:19:91 | access to constant None | Cookie attribute 'Secure' is not set to true. |

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-614/CookieWithoutSecure.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authentication;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication().AddCookie(o =>
{
o.Cookie.HttpOnly = false;
o.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None; // $ Alert
});
services.AddSession(options =>
{
options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None; // $ Alert
options.Cookie.HttpOnly = false;
});
}
}

View File

@@ -0,0 +1,4 @@
| Program.cs:5:9:5:48 | call to method Append | Cookie attribute 'Secure' is not set to true. |
| Program.cs:10:29:10:73 | object creation of type CookieOptions | Cookie attribute 'Secure' is not set to true. |
| Program.cs:35:29:35:73 | object creation of type CookieOptions | Cookie attribute 'Secure' is not set to true. |
| Program.cs:42:29:42:92 | object creation of type CookieOptions | Cookie attribute 'Secure' is not set to true. |

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-614/CookieWithoutSecure.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -0,0 +1,75 @@
public class MyController : Microsoft.AspNetCore.Mvc.Controller
{
public void CookieDefault()
{
Response.Cookies.Append("name", "value"); // $Alert // BAD: Secure is set to false by default
}
public void CookieDefault2()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $Alert
Response.Cookies.Append("name", "value", cookieOptions); // BAD: Secure is set to false by default
}
public void CookieDelete()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
Response.Cookies.Delete("name", cookieOptions); // GOOD: Delete call
}
void CookieDirectTrue()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
cookieOptions.Secure = true;
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
}
void CookieDirectTrueInitializer()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = true };
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
}
void CookieDirectFalse()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $Alert
cookieOptions.Secure = false;
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD
}
void CookieDirectFalseInitializer()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = false }; // $Alert
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD
}
void CookieIntermediateTrue()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
bool v = true;
cookieOptions.Secure = v;
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow
}
void CookieIntermediateTrueInitializer()
{
bool v = true;
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = v };
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow
}
void CookieIntermediateFalse()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $MISSING:Alert
bool v = false;
cookieOptions.Secure = v;
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD, but not detected
}
void CookieIntermediateFalseInitializer()
{
bool v = false;
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = v }; // $MISSING:Alert
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD, but not detected
}
}

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-614/CookieWithoutSecure.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -0,0 +1,25 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
public class MyController : Microsoft.AspNetCore.Mvc.Controller
{
public void CookieDefault()
{
Response.Cookies.Append("auth", "secret"); // GOOD: Secure is set in policy
}
public void CookieDefault2()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: Secure is set in policy
}
}
public class Startup
{
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCookiePolicy(new CookiePolicyOptions() { Secure = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always });
}
}

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-614/CookieWithoutSecure.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
public class MyController : Microsoft.AspNetCore.Mvc.Controller
{
public void CookieDefault()
{
Response.Cookies.Append("auth", "secret"); // GOOD: Secure is set in callback
}
public void CookieDefault2()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: Secure is set in callback
}
}
public class Startup
{
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCookiePolicy();
}
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.OnAppendCookie = cookieContext => SetCookies(cookieContext.CookieOptions);
});
}
private void SetCookies(CookieOptions options)
{
options.Secure = true;
options.HttpOnly = true;
}
}

View File

@@ -0,0 +1,2 @@
| Program.cs:8:9:8:49 | call to method Append | Cookie attribute 'Secure' is not set to true. |
| Program.cs:13:29:13:73 | object creation of type CookieOptions | Cookie attribute 'Secure' is not set to true. |

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-614/CookieWithoutSecure.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -0,0 +1,25 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
public class MyController : Microsoft.AspNetCore.Mvc.Controller
{
public void CookieDefault()
{
Response.Cookies.Append("auth", "secret"); // $ Alert // Bad: Secure policy set to None
}
public void CookieDefault2()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $ Alert
Response.Cookies.Append("auth", "secret", cookieOptions); // Bad: Secure policy set to None
}
}
public class Startup
{
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCookiePolicy(new CookiePolicyOptions() { Secure = Microsoft.AspNetCore.Http.CookieSecurePolicy.None });
}
}

View File

@@ -0,0 +1,3 @@
semmle-extractor-options: /nostdlib /noconfig
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj