diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs index da075286c34..dd4b77062ba 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs @@ -425,9 +425,7 @@ internal static object ConvertFromCimToDotNet(object cimObject, Type expectedDot var cimIntrinsicValue = (byte[])LanguagePrimitives.ConvertTo(cimObject, typeof(byte[]), CultureInfo.InvariantCulture); return exceptionSafeReturn(delegate { - #pragma warning disable SYSLIB0057 - return new X509Certificate2(cimIntrinsicValue); - #pragma warning restore SYSLIB0057 + return X509CertificateLoader.LoadCertificate(cimIntrinsicValue); }); } diff --git a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs index 4cbb346fb14..133412fd8fd 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs @@ -280,7 +280,17 @@ private static string GetHomeOrCreateTempHome() try { s_tempHome = Path.Combine(Path.GetTempPath(), StringUtil.Format(tempHomeFolderName, Environment.UserName)); - Directory.CreateDirectory(s_tempHome); + + // Create the temporary home directory with the user-only permission. + UnixFileMode userOnlyMode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute; + var dirInfo = Directory.CreateDirectory(s_tempHome, userOnlyMode); + if (dirInfo.UnixFileMode != userOnlyMode) + { + // The permission is not as expected, which indicates the directory may be pre-created by a different user. + // Throw an exception and fail PowerShell in this case for security reason. + throw new InvalidOperationException( + StringUtil.Format(CoreClrStubResources.TempHomeDirectoryUnsafePermission, s_tempHome)); + } } catch (UnauthorizedAccessException) { diff --git a/src/System.Management.Automation/engine/serialization.cs b/src/System.Management.Automation/engine/serialization.cs index add0eab25dc..7e524e14a44 100644 --- a/src/System.Management.Automation/engine/serialization.cs +++ b/src/System.Management.Automation/engine/serialization.cs @@ -7292,9 +7292,7 @@ internal static PSSenderInfo RehydratePSSenderInfo(PSObject pso) private static System.Security.Cryptography.X509Certificates.X509Certificate2 RehydrateX509Certificate2(PSObject pso) { byte[] rawData = GetPropertyValue(pso, "RawData"); - #pragma warning disable SYSLIB0057 - return new System.Security.Cryptography.X509Certificates.X509Certificate2(rawData); - #pragma warning restore SYSLIB0057 + return System.Security.Cryptography.X509Certificates.X509CertificateLoader.LoadCertificate(rawData); } private static System.Security.Cryptography.X509Certificates.X500DistinguishedName RehydrateX500DistinguishedName(PSObject pso) diff --git a/src/System.Management.Automation/resources/CoreClrStubResources.resx b/src/System.Management.Automation/resources/CoreClrStubResources.resx index 7be2f9081f6..25eb1f4bf1f 100644 --- a/src/System.Management.Automation/resources/CoreClrStubResources.resx +++ b/src/System.Management.Automation/resources/CoreClrStubResources.resx @@ -138,4 +138,8 @@ Unknown error "{0}". + + The temporary HOME directory '{0}' already exists but does not have the expected user-only permission. It may have been created by a different user, which is a potential security risk. PowerShell will not start until this directory is removed, its permission is corrected, or the 'HOME' environment variable is set. + {StrContains="HOME"} + diff --git a/src/System.Management.Automation/security/SecuritySupport.cs b/src/System.Management.Automation/security/SecuritySupport.cs index dc6d048c5b1..1bb31cbe160 100644 --- a/src/System.Management.Automation/security/SecuritySupport.cs +++ b/src/System.Management.Automation/security/SecuritySupport.cs @@ -908,11 +908,11 @@ internal static string Encrypt(byte[] contentBytes, CmsMessageRecipient[] recipi return encodedContent; } - internal static readonly string BEGIN_CMS_SIGIL = "-----BEGIN CMS-----"; - internal static readonly string END_CMS_SIGIL = "-----END CMS-----"; + internal const string BEGIN_CMS_SIGIL = "-----BEGIN CMS-----"; + internal const string END_CMS_SIGIL = "-----END CMS-----"; - internal static readonly string BEGIN_CERTIFICATE_SIGIL = "-----BEGIN CERTIFICATE-----"; - internal static readonly string END_CERTIFICATE_SIGIL = "-----END CERTIFICATE-----"; + internal const string BEGIN_CERTIFICATE_SIGIL = "-----BEGIN CERTIFICATE-----"; + internal const string END_CERTIFICATE_SIGIL = "-----END CERTIFICATE-----"; /// /// Adds Ascii armour to a byte stream in Base64 format. @@ -1088,6 +1088,8 @@ private void ResolveFromBase64Encoding(ResolutionPurpose purpose, out ErrorRecor byte[] messageBytes = null; try { + // The base64 encoded string should represent a single DER-encoded X.509 public certificate. + // So we check it against the "BEGIN/END CERTIFICATE" PEM labels. messageBytes = CmsUtils.RemoveAsciiArmor(_identifier, CmsUtils.BEGIN_CERTIFICATE_SIGIL, CmsUtils.END_CERTIFICATE_SIGIL, out startIndex, out endIndex); } catch (FormatException) @@ -1105,11 +1107,7 @@ private void ResolveFromBase64Encoding(ResolutionPurpose purpose, out ErrorRecor var certificatesToProcess = new X509Certificate2Collection(); try { - #pragma warning disable SYSLIB0057 - X509Certificate2 newCertificate = new X509Certificate2(messageBytes); - #pragma warning restore SYSLIB0057 - - certificatesToProcess.Add(newCertificate); + certificatesToProcess.Add(X509CertificateLoader.LoadCertificate(messageBytes)); } catch (Exception) {