In our environment we detecting vulnerable code with Injection Hunter. See also: Security Auditing for PowerShell Scripts
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,)
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?
The rule apparently categorically flags uses of .
, the member-access operator that either use:
.$Property
, .('Prop' + $index)
, .$(++$i; 'Prop' + $i)
)."$Property"
, but not verbatim strings such as .'$Property'
)Can this than be considered as a false positive?
With a static, verbatim value such as 'Property'
assigned to $Property
in the same scope, arguably, yes - but that is a very specific scenario.
A less cumbersome workaround is to use index notation via the intrinsic psobject
property:
$Object.psobject.Properties[$Property].Value = 'SomethingElse'
That said, the fact that this is not flagged - irrespective of what value is assigned to $Property
- is arguably a problematic oversight on the part of the vulnerability analysis, as malicious code can use this technique precisely to bypass the warning.
I encourage you to provide feedback to the module maintainers.
Unfortunately, the InjectionHunter
module's PowerShell Gallery page provides no link to a GitHub repo, so the only obvious way to contact them is via the Contact Owners link.