In our environment we detecting vulnerable code with Injection Hunter. See also: Security Auditing for PowerShell Scripts
Use case
In this specific case it concerns a PvsServerBiosBootstrap
object, that looks like:
$BootStrap = [ordered]@{Bootserver1_Ip='1.2.3.4';Bootserver1_Netmask='0.0.0.0';Bootserver1_Gateway='0.0.0.0';Bootserver1_Port='1234';Bootserver2_Ip='1.2.3.4';Bootserver2_Netmask='0.0.0.0';Bootserver2_Gateway='0.0.0.0';Bootserver2_Port='1234';Bootserver3_Ip='1.2.3.4';Bootserver3_Netmask='0.0.0.0';Bootserver3_Gateway='0.0.0.0';Bootserver3_Port='1234';Bootserver4_Ip='1.2.3.4';Bootserver4_Netmask='0.0.0.0';Bootserver4_Gateway='0.0.0.0';Bootserver4_Port='1234';VerboseMode='True';InterruptSafeMode='True';PaeMode='True';BootFromHdOnFail='False';RecoveryTime='50';PollingTimeout='5000';GeneralTimeout='30000';ServerId='12345678-1234-1234-1234-1234567890ab';Guid='12345678-1234-1234-1234-1234567890ab';Name='ARDBP32.BIN'}
Where it is evident to iterate trough the Bootserver*
properties like: $BootStrap."Bootserver$($Counter)_Ip"
. This PvsServerBiosBootstrap
object might be quiet seldom but commonly, objects are often flattened. (even I think that this should be generally avoided,)
False positive?
For some reason the Injection Hunter detects a risk on a simplified syntax like $Object.$Property = 'Something'
and $Object.$Property
for a $Property
and $Object
like: $Property = 5; $Object = [PSCustomObject]@{ Property = 'Something' }
Invoke-ScriptAnalyzer -CustomRulePath $InjectionHunterPath -ScriptDefinition {
$Object = [PSCustomObject]@{ Property = 'Something' }
$Property = 'Property'
$Object.$Property = 'SomethingElse'
}.ToString()
RuleName Severity ScriptName Line Message
-------- -------- ---------- ---- -------
InjectionRisk.StaticPropertyInjecti Warning 4 Possible property access injection via dynamic member
on access. Untrusted input can cause arbitrary static
properties to be accessed: $Object.$Property
But I fail to see how one might exploit this if the $Property
is defined in the same script (or even the same scope). Can this than be considered as a false positive?
Besides, I wonder what the cleanest syntax would be to prevent the warning (apart from just suppressing the warning). I have tried things along with $Object.[String]$Property
but the best substitute I have been able to find so far is which is rather cumbersome:
$Object.PSObject.Properties.where{$_.Name -eq 'Property'}[0].Value = 'SomethingElse'
In other words, how do I safely modify a dynamic object member?