From 3be703d5c94047cfd9e858eb3c3d09f1aa2f2b20 Mon Sep 17 00:00:00 2001 From: sysadmin Date: Tue, 9 Jun 2026 02:30:35 +0100 Subject: [PATCH] fix(welcome): escape bootstrapUser + assert daily user is not admin --- .../src/SilverOS.Welcome.Core/Apply/BootstrapService.cs | 4 +++- .../tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/windows/welcome/src/SilverOS.Welcome.Core/Apply/BootstrapService.cs b/windows/welcome/src/SilverOS.Welcome.Core/Apply/BootstrapService.cs index 9f059a1..4cbcd19 100644 --- a/windows/welcome/src/SilverOS.Welcome.Core/Apply/BootstrapService.cs +++ b/windows/welcome/src/SilverOS.Welcome.Core/Apply/BootstrapService.cs @@ -6,8 +6,10 @@ public sealed class BootstrapService(IProcessRunner runner) : IBootstrapService const string key = "'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon'"; await Ps($"Set-ItemProperty {key} -Name AutoAdminLogon -Value 0; " + $"Remove-ItemProperty {key} -Name DefaultPassword -EA SilentlyContinue", ct); - await Ps($"Remove-LocalUser -Name '{bootstrapUser}' -EA SilentlyContinue", ct); + var u = Esc(bootstrapUser); + await Ps($"Remove-LocalUser -Name '{u}' -EA SilentlyContinue", ct); } + private static string Esc(string s) => s.Replace("'", "''"); private Task Ps(string s, CancellationToken ct) => runner.RunAsync("powershell.exe", $"-NoProfile -ExecutionPolicy Bypass -Command \"{s}\"", ct); } diff --git a/windows/welcome/tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs b/windows/welcome/tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs index 5113487..6ee446a 100644 --- a/windows/welcome/tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs +++ b/windows/welcome/tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs @@ -19,6 +19,10 @@ public class ApplyServicesTests // daily user is a Standard user (added to Users, NOT Administrators) run.Verify(r => r.RunAsync("powershell.exe", It.Is(s => s.Contains("New-LocalUser") && s.Contains("alice")), It.IsAny())); + // negative: the daily-user New-LocalUser call must never mention Administrators + run.Verify(r => r.RunAsync("powershell.exe", It.Is(s => + s.Contains("New-LocalUser") && s.Contains("alice") && !s.Contains("Administrators")), + It.IsAny()), Times.Once); run.Verify(r => r.RunAsync("powershell.exe", It.Is(s => s.Contains("'SilverOS Admin'") && s.Contains("Administrators")), It.IsAny())); }