diff --git a/src/Shared/CertificateGeneration/UnixCertificateManager.cs b/src/Shared/CertificateGeneration/UnixCertificateManager.cs index 059a9e04e14d..664c6a24ab69 100644 --- a/src/Shared/CertificateGeneration/UnixCertificateManager.cs +++ b/src/Shared/CertificateGeneration/UnixCertificateManager.cs @@ -617,6 +617,9 @@ private static bool TryTrustCertificateInWindowsStore(string certificatePath) // PowerShell command to import the certificate into the CurrentUser Root store. // We use Import-Certificate which can handle PEM files on modern Windows. // The -CertStoreLocation parameter specifies the store location. + // Using -EncodedCommand with Base64 encoding to avoid command shell escaping issues. + // We still need to escape single quotes within the PowerShell script itself to prevent + // PowerShell injection vulnerabilities. var escapedPath = certificatePath.Replace("'", "''"); var escapedFriendlyName = WslFriendlyName.Replace("'", "''"); var powershellScript = $@" @@ -628,7 +631,10 @@ private static bool TryTrustCertificateInWindowsStore(string certificatePath) $store.Close() "; - var startInfo = new ProcessStartInfo(PowerShellCommand, $"-NoProfile -NonInteractive -Command \"{powershellScript}\"") + // Encode the PowerShell script to Base64 (UTF-16LE as required by PowerShell) + var encodedCommand = Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes(powershellScript)); + + var startInfo = new ProcessStartInfo(PowerShellCommand, $"-NoProfile -NonInteractive -EncodedCommand {encodedCommand}") { RedirectStandardOutput = true, RedirectStandardError = true,