Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions SysManager/SysManager/Services/AppBlockerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace SysManager.Services;
/// effectively preventing it from running. Fully reversible by removing the key.
/// Requires administrator privileges.
/// </summary>
public sealed class AppBlockerService
public sealed partial class AppBlockerService
{
private const string IfeoPath = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options";
private const string BlockerDebugger = @"C:\Windows\System32\SysManager_Blocked.exe";
Expand All @@ -33,7 +33,7 @@ public static bool BlockApp(string exeName)
exeName += ".exe";

// SEC-004: reject path separators and invalid chars to prevent registry path injection
if (!System.Text.RegularExpressions.Regex.IsMatch(exeName, @"^[A-Za-z0-9_\-. ]+\.exe$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
if (!ExeNamePattern().IsMatch(exeName))
{
Log.Warning("Rejected invalid exeName: {ExeName}", exeName);
return false;
Expand Down Expand Up @@ -78,7 +78,7 @@ public static bool UnblockApp(string exeName)
exeName += ".exe";

// SEC-004: apply same validation as BlockApp to prevent registry path injection
if (!System.Text.RegularExpressions.Regex.IsMatch(exeName, @"^[A-Za-z0-9_\-. ]+\.exe$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
if (!ExeNamePattern().IsMatch(exeName))
{
Log.Warning("Rejected invalid exeName for unblock: {ExeName}", exeName);
return false;
Expand Down Expand Up @@ -190,4 +190,7 @@ public static IReadOnlyList<BlockedApp> GetBlockedApps()

return blocked;
}

[System.Text.RegularExpressions.GeneratedRegex(@"^[A-Za-z0-9_\-. ]+\.exe$", System.Text.RegularExpressions.RegexOptions.IgnoreCase)]
private static partial System.Text.RegularExpressions.Regex ExeNamePattern();
}
2 changes: 1 addition & 1 deletion SysManager/SysManager/Services/NetworkRepairService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace SysManager.Services;
/// Runs common network repair commands: DNS flush, Winsock reset, TCP/IP reset.
/// Each method captures stdout/stderr and returns a <see cref="NetworkRepairResult"/>.
/// </summary>
public class NetworkRepairService
public sealed class NetworkRepairService
{
private readonly PowerShellRunner _ps;

Expand Down
2 changes: 1 addition & 1 deletion SysManager/SysManager/Services/PerformanceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace SysManager.Services;
/// • NVIDIA GPU subkey is auto-detected (not hardcoded to 0000).
/// • Visual effects use SystemParametersInfo (instant), not registry-only.
/// </summary>
public class PerformanceService
public sealed class PerformanceService
{
private readonly PowerShellRunner _ps;

Expand Down
2 changes: 1 addition & 1 deletion SysManager/SysManager/Services/PowerShellRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace SysManager.Services;
/// same reason. Callers that use RunAsync or RunScriptViaPwshAsync must only pass
/// hard-coded script strings; never pass user input directly as a script.</para>
/// </summary>
public class PowerShellRunner
public sealed class PowerShellRunner
{
public event Action<PowerShellLine>? LineReceived;
public event Action<int>? ProgressChanged; // 0-100
Expand Down
7 changes: 5 additions & 2 deletions SysManager/SysManager/Services/ServiceManagerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace SysManager.Services;
/// Enumerates Windows services, provides gaming recommendations, and
/// allows starting/stopping/changing startup type. All mutations require admin.
/// </summary>
public class ServiceManagerService
public sealed partial class ServiceManagerService
{
/// <summary>
/// Gaming-oriented recommendations for common Windows services.
Expand Down Expand Up @@ -128,7 +128,7 @@ public static async Task SetStartupTypeAsync(string serviceName, string startTyp
// hyphens, underscores, dots, and dollar signs only (covers all valid
// Windows service names including instance names like MSSQL$INSTANCE).
if (string.IsNullOrWhiteSpace(serviceName) ||
!System.Text.RegularExpressions.Regex.IsMatch(serviceName, @"^[\w \-.$]+$"))
!ServiceNamePattern().IsMatch(serviceName))
throw new ArgumentException("Invalid service name.", nameof(serviceName));

var allowedTypes = new[] { "auto", "delayed-auto", "demand", "disabled" };
Expand Down Expand Up @@ -162,4 +162,7 @@ private static string GetServiceDescription(ServiceController sc)
catch (System.Security.SecurityException) { return ""; }
catch (UnauthorizedAccessException) { return ""; }
}

[System.Text.RegularExpressions.GeneratedRegex(@"^[\w \-.$]+$")]
private static partial System.Text.RegularExpressions.Regex ServiceNamePattern();
}
2 changes: 1 addition & 1 deletion SysManager/SysManager/Services/SystemInfoService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace SysManager.Services;
/// <summary>
/// Collects system information via WMI / CIM (no PowerShell spawn needed).
/// </summary>
public class SystemInfoService
public sealed class SystemInfoService
{
public Task<SystemSnapshot> CaptureAsync(CancellationToken ct = default)
=> Task.Run(() => Capture(), ct);
Expand Down
Loading