From 8e3a0cd5f1f7e5d591e7123960232fccdd438a70 Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Tue, 10 Nov 2015 13:47:40 -0800 Subject: [PATCH 1/2] Updated Engine to use AddCommand to prevent Script Based injection attacks --- Engine/ScriptAnalyzer.cs | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/Engine/ScriptAnalyzer.cs b/Engine/ScriptAnalyzer.cs index c6cbcd528..6dfb257b5 100644 --- a/Engine/ScriptAnalyzer.cs +++ b/Engine/ScriptAnalyzer.cs @@ -26,6 +26,7 @@ using System.Globalization; using System.Collections.Concurrent; using System.Threading.Tasks; +using System.Collections.ObjectModel; namespace Microsoft.Windows.PowerShell.ScriptAnalyzer { @@ -545,18 +546,19 @@ private List GetExternalRule(string[] moduleNames) using (System.Management.Automation.PowerShell posh = System.Management.Automation.PowerShell.Create(state)) { - string script = string.Format(CultureInfo.CurrentCulture, "Get-Module -Name '{0}' -ListAvailable", moduleName); - shortModuleName = posh.AddScript(script).Invoke().First().Name; + posh.AddCommand("Get-Module").AddParameter("Name", moduleName).AddParameter("ListAvailable"); + shortModuleName = posh.Invoke().First().Name; // Invokes Update-Help for this module // Required since when invoking Get-Help later on, the cmdlet prompts for Update-Help interactively // By invoking Update-Help first, Get-Help will not prompt for downloading help later - script = string.Format(CultureInfo.CurrentCulture, "Update-Help -Module '{0}' -Force", shortModuleName); - posh.AddScript(script).Invoke(); - + posh.AddCommand("Update-Help").AddParameter("Module", shortModuleName).AddParameter("Force"); + posh.Invoke(); + // Invokes Get-Command and Get-Help for each functions in the module. - script = string.Format(CultureInfo.CurrentCulture, "Get-Command -Module '{0}'", shortModuleName); - var psobjects = posh.AddScript(script).Invoke(); + posh.Commands.Clear(); + posh.AddCommand("Get-Command").AddParameter("Module", shortModuleName); + var psobjects = posh.Invoke(); foreach (PSObject psobject in psobjects) { @@ -570,10 +572,22 @@ private List GetExternalRule(string[] moduleNames) //Only add functions that are defined as rules. if (param != null) { - script = string.Format(CultureInfo.CurrentCulture, "(Get-Help -Name {0}).Description | Out-String", funcInfo.Name); - string desc = posh.AddScript(script).Invoke()[0].ImmediateBaseObject.ToString() - .Replace("\r\n", " ").Trim(); + posh.AddCommand("Get-Help").AddParameter("Name", funcInfo.Name); + Collection helpContent = posh.Invoke(); + + // Retrieve "Description" field in the help content + string desc = String.Empty; + + if ((null != helpContent) && ( 1 == helpContent.Count)) + { + dynamic description = helpContent[0].Properties["Description"].Value; + if (null != description) + { + desc = description[0].Text; + } + } + rules.Add(new ExternalRule(funcInfo.Name, funcInfo.Name, desc, param.Name, param.ParameterType.FullName, funcInfo.ModuleName, funcInfo.Module.Path)); } @@ -784,8 +798,8 @@ public Dictionary> CheckRuleExtension(string[] path, PathIn using (System.Management.Automation.PowerShell posh = System.Management.Automation.PowerShell.Create()) { - string script = string.Format(CultureInfo.CurrentCulture, "Get-Module -Name '{0}' -ListAvailable", resolvedPath); - PSModuleInfo moduleInfo = posh.AddScript(script).Invoke().First(); + posh.AddCommand("Get-Module").AddParameter("Name", resolvedPath).AddParameter("ListAvailable"); + PSModuleInfo moduleInfo = posh.Invoke().First(); // Adds original path, otherwise path.Except(validModPaths) will fail. // It's possible that user can provide something like this: From 4454618b0d7e8bab6869995197d0838b9388df5d Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Tue, 10 Nov 2015 14:26:26 -0800 Subject: [PATCH 2/2] Check for null Description Property in the returned help content --- Engine/ScriptAnalyzer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/ScriptAnalyzer.cs b/Engine/ScriptAnalyzer.cs index 6dfb257b5..d82ebd1d7 100644 --- a/Engine/ScriptAnalyzer.cs +++ b/Engine/ScriptAnalyzer.cs @@ -580,11 +580,11 @@ private List GetExternalRule(string[] moduleNames) if ((null != helpContent) && ( 1 == helpContent.Count)) { - dynamic description = helpContent[0].Properties["Description"].Value; + dynamic description = helpContent[0].Properties["Description"]; if (null != description) { - desc = description[0].Text; + desc = description.Value[0].Text; } }