Add httponly tests for aspnet core + fixes

This commit is contained in:
Joe Farebrother
2025-10-24 13:09:19 +01:00
parent ae0b997c31
commit 6ba7ece2f0
17 changed files with 220 additions and 3 deletions

View File

@@ -0,0 +1,2 @@
| Program.cs:13:33:13:37 | false | Cookie attribute 'HttpOnly' is not set to true. |
| Program.cs:20:39:20:43 | false | Cookie attribute 'HttpOnly' is not set to true. |

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-1004/CookieWithoutHttpOnly.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; // $ Alert
o.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None;
});
services.AddSession(options =>
{
options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None;
options.Cookie.HttpOnly = false; // $ Alert
});
}
}

View File

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

View File

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

View File

@@ -0,0 +1,82 @@
public class MyController : Microsoft.AspNetCore.Mvc.Controller
{
public void CookieDefault()
{
Response.Cookies.Append("auth", "value"); // $Alert // BAD: HttpOnly is set to false by default
}
public void CookieDefault2()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $Alert
Response.Cookies.Append("auth", "value", cookieOptions); // BAD: HttpOnly is set to false by default
}
public void CookieDelete()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
Response.Cookies.Delete("auth", cookieOptions); // GOOD: Delete call
}
void CookieDirectFalseForgery()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
cookieOptions.HttpOnly = false;
Response.Cookies.Append("antiforgerytoken", "secret", cookieOptions); // GOOD: not an auth cookie
}
void CookieDirectTrue()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
cookieOptions.HttpOnly = true;
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
}
void CookieDirectTrueInitializer()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = true };
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD
}
void CookieDirectFalse()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $Alert
cookieOptions.HttpOnly = false;
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD
}
void CookieDirectFalseInitializer()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = false }; // $Alert
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD
}
void CookieIntermediateTrue()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
bool v = true;
cookieOptions.HttpOnly = 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() { HttpOnly = 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.HttpOnly = v;
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD, but not detected
}
void CookieIntermediateFalseInitializer()
{
bool v = false;
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = v }; // $MISSING:Alert
Response.Cookies.Append("auth", "secret", cookieOptions); // BAD, but not detected
}
}

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-1004/CookieWithoutHttpOnly.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: HttpOnly is set in policy
}
public void CookieDefault2()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: HttpOnly 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() { HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always });
}
}

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-1004/CookieWithoutHttpOnly.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: HttpOnly is set in callback
}
public void CookieDefault2()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions();
Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: HttpOnly 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 'HttpOnly' is not set to true. |
| Program.cs:13:29:13:73 | object creation of type CookieOptions | Cookie attribute 'HttpOnly' is not set to true. |

View File

@@ -0,0 +1,2 @@
query: Security Features/CWE-1004/CookieWithoutHttpOnly.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: HttpOnly policy set to None
}
public void CookieDefault2()
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); // $ Alert
Response.Cookies.Append("auth", "secret", cookieOptions); // Bad: HttpOnly 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() { HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.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