Skip to content

Replace MD5 with SHA256 in security-sensitive operations and fix CodeQL analysis#18

Merged
sphildreth merged 6 commits intomainfrom
copilot/fix-code-scanning-issues-again
Dec 20, 2025
Merged

Replace MD5 with SHA256 in security-sensitive operations and fix CodeQL analysis#18
sphildreth merged 6 commits intomainfrom
copilot/fix-code-scanning-issues-again

Conversation

Copy link
Contributor

Copilot AI commented Dec 20, 2025

Code scanning identified 21 security concerns, primarily weak cryptographic hash usage (MD5) in security-sensitive contexts and weak random number generation.

Changes

Cryptographic Hash Migration

  • Cookie security: Replaced MD5 with SHA256 for session cookie generation and validation
    • MelodeeBlazorCookieMiddleware.cs
    • Controllers/OpenSubsonic/ControllerBase.cs
  • File operations: Replaced MD5 with SHA256 for duplicate detection and ETag generation
    • FileSystemDirectoryInfoExtensions.cs
    • OpenSubsonicApiService.cs (4 locations)
  • HashHelper: Added SHA256 methods using streaming I/O instead of loading entire files into memory

Random Number Generation

  • Replaced new Random() with Random.Shared in OpenSubsonicApiService.cs for thread-safe song shuffling

API-Mandated MD5 (Unchanged)

Two MD5 usages remain by external API requirement:

  • OpenSubsonic protocol: Token authentication requires MD5(password + salt) per spec
  • Last.fm API: Signature computation requires MD5 per authentication protocol

Both documented with inline comments explaining the external constraint.

Security Hardening

  • ShellHelper: Enhanced warnings about shell injection limitations (only escapes quotes, not metacharacters)
  • XML parsing: Documented XXE protection (enabled by default in .NET Core)

CodeQL Configuration Fix

  • JavaScript/TypeScript Analysis: Fixed CodeQL analysis failures by updating .github/codeql/codeql-config.yml to exclude:
    • Documentation directory (contains Jekyll templates and vendored JavaScript)
    • Vendored libraries (jQuery, Lunr.js, minified files)
    • Benchmark and test directories

This focuses CodeQL analysis on actual application JavaScript in the src directory, preventing parsing errors from non-application code.

Example

// Before: Weak hash for cookies
var cookie = HashHelper.CreateMd5(date + secret);

// After: Strong hash for cookies
var cookie = HashHelper.CreateSha256(date + secret);

// API-mandated MD5 remains (documented)
// NOTE: MD5 required by OpenSubsonic API specification.
// Token = MD5(password + salt) per protocol.
var token = HashHelper.CreateMd5($"{password}{salt}");

See SECURITY-FIXES.md for detailed security audit results.

[!WARNING]

Original prompt

Help me resolve the Code scanning issues as of this PR there are 21 security concerns


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits December 20, 2025 21:01
Co-authored-by: sphildreth <193334+sphildreth@users.noreply.github.com>
Co-authored-by: sphildreth <193334+sphildreth@users.noreply.github.com>
… warnings

Co-authored-by: sphildreth <193334+sphildreth@users.noreply.github.com>
Copilot AI changed the title [WIP] Resolve 21 security concerns from code scanning Replace MD5 with SHA256 in security-sensitive operations Dec 20, 2025
Copilot AI requested a review from sphildreth December 20, 2025 21:12
@sphildreth
Copy link
Collaborator

@copilot Resolve why CodeQL (javascript-typescript) is failing on this PR

@sphildreth sphildreth marked this pull request as ready for review December 20, 2025 21:18
Copilot AI review requested due to automatic review settings December 20, 2025 21:18
…red libraries

Co-authored-by: sphildreth <193334+sphildreth@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 20, 2025

@copilot Resolve why CodeQL (javascript-typescript) is failing on this PR

Fixed in commit 9f26a67.

The CodeQL javascript-typescript analysis was failing because it was attempting to analyze the entire repository, including:

  • Documentation directory with Jekyll templates
  • Vendored JavaScript libraries (jQuery, Lunr.js)
  • Minified JavaScript files

Updated .github/codeql/codeql-config.yml to exclude these directories and focus only on application JavaScript in the src directory. This resolves the parsing errors while still scanning the actual application code for security issues.

Copilot AI changed the title Replace MD5 with SHA256 in security-sensitive operations Replace MD5 with SHA256 in security-sensitive operations and fix CodeQL analysis Dec 20, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses 21 security concerns identified by code scanning, primarily focusing on replacing weak MD5 cryptographic hashing with SHA256 in security-sensitive operations while preserving MD5 usage where mandated by external API specifications.

Key Changes:

  • Migrated internal security operations (session cookies, ETags, file duplicate detection) from MD5 to SHA256
  • Replaced new Random() with Random.Shared for thread-safe randomization
  • Added comprehensive documentation for unavoidable MD5 usage in OpenSubsonic and Last.fm APIs

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
HashHelper.cs Added SHA256 methods and streaming I/O for file hashing; documented MD5 retention for API compatibility
MelodeeBlazorCookieMiddleware.cs Replaced MD5 with SHA256 for session cookie generation and validation
ControllerBase.cs Updated cookie hash verification to use SHA256
FileSystemDirectoryInfoExtensions.cs Migrated file duplicate detection from MD5 to SHA256
OpenSubsonicApiService.cs Updated ETag generation to SHA256; replaced new Random() with Random.Shared
UserService.cs Documented MD5 requirement for OpenSubsonic API authentication
ScrobbleController.cs Documented MD5 requirement for Last.fm API authentication
JellyfinXmlDeserializer.cs Documented built-in XXE protection in .NET Core
ShellHelper.cs Enhanced security warnings about shell injection limitations
SECURITY-FIXES.md Comprehensive security audit documentation
codeql-config.yml Refined CodeQL analysis scope to exclude documentation and vendored code

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +91 to +106
using (var sha256 = SHA256.Create())
{
var data = sha256.ComputeHash(bytes);

// Create a new StringBuilder to collect the bytes and create a string.
var sBuilder = new StringBuilder();

// Loop through each byte of the hashed data and format each one as a hexadecimal string.
foreach (var t in data)
{
sBuilder.Append(t.ToString("x2"));
}

// Return the hexadecimal string.
return sBuilder.ToString();
}
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent resource disposal pattern. The CreateSha256(byte[]? bytes) method uses a using statement block, while CreateSha256(FileInfo file) uses using declarations. For consistency and readability, both methods should use the same pattern. Consider using using declarations (without braces) in the byte array overload to match the FileInfo overload.

Suggested change
using (var sha256 = SHA256.Create())
{
var data = sha256.ComputeHash(bytes);
// Create a new StringBuilder to collect the bytes and create a string.
var sBuilder = new StringBuilder();
// Loop through each byte of the hashed data and format each one as a hexadecimal string.
foreach (var t in data)
{
sBuilder.Append(t.ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
using var sha256 = SHA256.Create();
var data = sha256.ComputeHash(bytes);
// Create a new StringBuilder to collect the bytes and create a string.
var sBuilder = new StringBuilder();
// Loop through each byte of the hashed data and format each one as a hexadecimal string.
foreach (var t in data)
{
sBuilder.Append(t.ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +32
using var md5 = MD5.Create();
using var stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
var hash = md5.ComputeHash(stream);

var sBuilder = new StringBuilder();
foreach (var t in hash)
{
sBuilder.Append(t.ToString("x2"));
}
return sBuilder.ToString();
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hash-to-hex conversion logic is duplicated across multiple methods (CreateMd5(FileInfo), CreateSha256(FileInfo), and CreateSha256(byte[])). Consider extracting this into a private helper method like ConvertHashToHexString(byte[] hash) to reduce duplication and improve maintainability.

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@sphildreth sphildreth merged commit a570845 into main Dec 20, 2025
6 of 8 checks passed
@sphildreth sphildreth deleted the copilot/fix-code-scanning-issues-again branch December 20, 2025 21:35
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.

3 participants