Skip to content

Conversation

@geofranzi
Copy link
Member

No description provided.

DavidBlaa and others added 30 commits September 10, 2025 09:57
cookie.Domain = Request.Url.Host; // Set the domain
cookie.Path = "/"; // Set the path

cookieJwt.Expires = DateTime.Now.AddDays(1); // Expires in 1 day

Check failure

Code scanning / CodeQL

Cookie security: persistent cookie High

Avoid persistent cookies.

Copilot Autofix

AI about 7 hours ago

In general, to fix this type of issue you either (1) avoid making the cookie persistent (omit Expires so it becomes a session cookie held only in memory), or (2) drastically reduce the lifetime to the minimum necessary (ideally a few minutes) and ensure other security attributes (HttpOnly, Secure, SameSite) are set. For authentication tokens like JWTs, best practice is usually to keep the cookie as a session cookie and control token lifetime inside the token itself.

For this specific snippet, the minimal, behavior‑preserving fix is to stop making the JWT cookie persist for a full day. The safest change is to remove the explicit Expires assignment entirely so the cookie becomes a session cookie. If you still need a short persistence, you could set a much shorter expiry (e.g., AddMinutes(5)), but that changes user experience more; turning it into a session cookie aligns with typical login behavior and still lets the JWT control its own validity. Alongside this, we should explicitly strengthen cookie flags where possible: set HttpOnly = true and Secure = true so the token cannot be read by JavaScript and is only sent over HTTPS. These flags do not change functional behavior from the user’s perspective but significantly harden security.

Concretely, in Console/BExIS.Web.Shell/Controllers/AccountController.cs, in the block where cookieJwt is created (around line 305+), we will:

  • Remove the line cookieJwt.Expires = DateTime.Now.AddDays(1);.
  • Optionally adjust the comment to reflect that we’re not setting a long‑lived expiry anymore.
  • Add cookieJwt.HttpOnly = true; and cookieJwt.Secure = true; to better protect the JWT in transit and at rest.
  • Keep existing domain and path settings unchanged.

No new imports or external dependencies are required; HttpCookie.HttpOnly and HttpCookie.Secure are part of System.Web.

Suggested changeset 1
Console/BExIS.Web.Shell/Controllers/AccountController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Console/BExIS.Web.Shell/Controllers/AccountController.cs b/Console/BExIS.Web.Shell/Controllers/AccountController.cs
--- a/Console/BExIS.Web.Shell/Controllers/AccountController.cs
+++ b/Console/BExIS.Web.Shell/Controllers/AccountController.cs
@@ -304,13 +304,14 @@
                     {
                         var jwt = JwtHelper.GetTokenByUser(user);
       
-                        // Create a new cookie
+                        // Create a new cookie to store the JWT
                         HttpCookie cookieJwt = new HttpCookie("jwt", jwt);
 
-                        // Set additional properties if needed
-                        cookieJwt.Expires = DateTime.Now.AddDays(1); // Expires in 1 day
+                        // Set additional properties if needed (session cookie, hardened flags)
                         cookieJwt.Domain = Request.Url.Host; // Set the domain
                         cookieJwt.Path = "/"; // Set the path
+                        cookieJwt.HttpOnly = true; // Prevent access from client-side scripts
+                        cookieJwt.Secure = true; // Send only over HTTPS
 
                         // Add the cookie to the response
                         Response.Cookies.Add(cookieJwt);
EOF
@@ -304,13 +304,14 @@
{
var jwt = JwtHelper.GetTokenByUser(user);

// Create a new cookie
// Create a new cookie to store the JWT
HttpCookie cookieJwt = new HttpCookie("jwt", jwt);

// Set additional properties if needed
cookieJwt.Expires = DateTime.Now.AddDays(1); // Expires in 1 day
// Set additional properties if needed (session cookie, hardened flags)
cookieJwt.Domain = Request.Url.Host; // Set the domain
cookieJwt.Path = "/"; // Set the path
cookieJwt.HttpOnly = true; // Prevent access from client-side scripts
cookieJwt.Secure = true; // Send only over HTTPS

// Add the cookie to the response
Response.Cookies.Add(cookieJwt);
Copilot is powered by AI and may make mistakes. Always verify output.

cookieJwt.Expires = DateTime.Now.AddDays(1); // Expires in 1 day
cookieJwt.Domain = Request.Url.Host; // Set the domain
cookieJwt.Path = "/"; // Set the path

Check failure

Code scanning / CodeQL

Cookie security: overly broad path Critical

Overly broad path for cookie.

Copilot Autofix

AI about 7 hours ago

In general, to fix an overly broad cookie path, set the cookie’s Path to the actual application path (or a specific subpath that needs the cookie) instead of "/". This limits which parts of the server can receive and potentially access or manipulate that cookie.

In this specific case in Console/BExIS.Web.Shell/Controllers/AccountController.cs, update the cookie’s path assignment on line 313 so it is not hardcoded to "/". The safest, least intrusive change—without changing visible behavior for this application—is to set the path to ASP.NET’s Request.ApplicationPath, which is the root virtual path of the current application. That still allows all controllers/views within this app to receive the cookie but prevents other applications on the same domain (with different virtual roots) from accessing it. We don’t need new imports or methods; we just replace the literal "/" with Request.ApplicationPath ?? "/" to be robust if ApplicationPath is null, preserving current behavior as a fallback.

Suggested changeset 1
Console/BExIS.Web.Shell/Controllers/AccountController.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Console/BExIS.Web.Shell/Controllers/AccountController.cs b/Console/BExIS.Web.Shell/Controllers/AccountController.cs
--- a/Console/BExIS.Web.Shell/Controllers/AccountController.cs
+++ b/Console/BExIS.Web.Shell/Controllers/AccountController.cs
@@ -310,7 +310,7 @@
                         // Set additional properties if needed
                         cookieJwt.Expires = DateTime.Now.AddDays(1); // Expires in 1 day
                         cookieJwt.Domain = Request.Url.Host; // Set the domain
-                        cookieJwt.Path = "/"; // Set the path
+                        cookieJwt.Path = Request.ApplicationPath ?? "/"; // Restrict the path to the application
 
                         // Add the cookie to the response
                         Response.Cookies.Add(cookieJwt);
EOF
@@ -310,7 +310,7 @@
// Set additional properties if needed
cookieJwt.Expires = DateTime.Now.AddDays(1); // Expires in 1 day
cookieJwt.Domain = Request.Url.Host; // Set the domain
cookieJwt.Path = "/"; // Set the path
cookieJwt.Path = Request.ApplicationPath ?? "/"; // Restrict the path to the application

// Add the cookie to the response
Response.Cookies.Add(cookieJwt);
Copilot is powered by AI and may make mistakes. Always verify output.
}

private getReadableComment(): string {
return this.comment.replace(/\\/, '');

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding High

This replaces only the first occurrence of /\/.

Copilot Autofix

AI 2 months ago

To fully address the escaping/encoding issue, we need to ensure that the replace call in getReadableComment() removes all backslashes, not just the first. This is done by adding the g (global) flag to the regular expression. No other files or regions need to be changed. No new imports or helper methods are required—just replace /\\/ with /\\/g on line 62. This minimizes side effects while ensuring all unwanted characters are stripped.


Suggested changeset 1
Console/BExIS.Web.Shell/Areas/DDM/BExIS.Modules.Ddm.UI.Svelte/src/lib/models/CurationNote.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/Console/BExIS.Web.Shell/Areas/DDM/BExIS.Modules.Ddm.UI.Svelte/src/lib/models/CurationNote.ts b/Console/BExIS.Web.Shell/Areas/DDM/BExIS.Modules.Ddm.UI.Svelte/src/lib/models/CurationNote.ts
--- a/Console/BExIS.Web.Shell/Areas/DDM/BExIS.Modules.Ddm.UI.Svelte/src/lib/models/CurationNote.ts
+++ b/Console/BExIS.Web.Shell/Areas/DDM/BExIS.Modules.Ddm.UI.Svelte/src/lib/models/CurationNote.ts
@@ -59,7 +59,7 @@
 	}
 
 	private getReadableComment(): string {
-		return this.comment.replace(/\\/, '');
+		return this.comment.replace(/\\/g, '');
 	}
 
 	private getCommandType(): CurationNoteCommandType {
EOF
@@ -59,7 +59,7 @@
}

private getReadableComment(): string {
return this.comment.replace(/\\/, '');
return this.comment.replace(/\\/g, '');
}

private getCommandType(): CurationNoteCommandType {
Copilot is powered by AI and may make mistakes. Always verify output.
// Create a new cookie
HttpCookie cookie = new HttpCookie("jwt", jwt);

HttpCookie cookieJwt = new HttpCookie("jwt", jwt);

Check warning

Code scanning / CodeQL

Cookie 'Secure' attribute is not set to true Medium

Cookie attribute 'Secure' is not set to true.
Comment on lines 10 to 35
runs-on: windows-latest

steps:
- name: Checkout repository

uses: actions/checkout@v4

- name: Install .NET SDK
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.x'

- name: Install .NET Upgrade Assistant
run: dotnet tool install -g upgrade-assistant

- name: Run Upgrade Assistant in analyze mode
run: |
upgrade-assistant analyze BExIS%2B%2B.sln --format json > upgrade-report.json

- name: Upload report artifact

uses: actions/upload-artifact@v4

with:
name: upgrade-report
path: upgrade-report.json

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 1 day ago

To fix the problem, add an explicit permissions block that limits the GITHUB_TOKEN to the least privileges needed. This workflow only checks out code, installs tools, runs a read-only analysis, and uploads an artifact. None of these require write access to repo contents, issues, or PRs, so contents: read at either the workflow root or the job level is sufficient.

The best fix with minimal functional impact is to add permissions: contents: read at the job level for the upgrade-check job. This keeps the scope tightly bound to this job and avoids affecting other workflows. Concretely, in .github/workflows/main.yml, insert:

    permissions:
      contents: read

between runs-on: windows-latest (line 10) and steps: (line 12). No additional methods, imports, or definitions are needed.

Suggested changeset 1
.github/workflows/main.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -8,6 +8,8 @@
 jobs:
   upgrade-check:
     runs-on: windows-latest
+    permissions:
+      contents: read
 
     steps:
       - name: Checkout repository
EOF
@@ -8,6 +8,8 @@
jobs:
upgrade-check:
runs-on: windows-latest
permissions:
contents: read

steps:
- name: Checkout repository
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants