我在PowerShell中使用了哈希表,並且發現了一些與訪問項目相關的奇怪行爲。正如我們所知,PowerShell的可分配值的至少三種不同的方式哈希表項:哈希表漏洞(屬性覆蓋)?
$hashtable["foo"] = "bar" #1
$hashtable.Item("foo") = "bar" #2
$hashtable.foo = "bar" #3
同時,我們使用了#3語法訪問Hashtable對象本身的屬性,如Count
,Keys
, Values
等等。如果我們添加一個與內部屬性名衝突的項,PowerShell允許我們這樣做,並且我們實際上不再能夠讀取屬性的值(除了使用Reflection)。
我猜想在密鑰來自不可信任的來源(例如來自外部文件或網絡)的情況下,這可能會對流量控制產生不良影響,並可能被惡意用戶利用。
本段說明問題:
function Get-HashtableProperties($hashTable, $header)
{
"{0} {1} {0}" -f ("-" * 10), $header
"Count : {0}" -f $hashtable.Count
"Keys.Count : {0}" -f $hashtable.Keys.Count
"Values.Count : {0}" -f $hashtable.Values.Count
"Actual Count (Reflection) : {0}" -f $hashtable.GetType().GetProperty("Count").GetValue($hashtable)
"`nItems (Keys iteration):"
$hashtable.Keys | ForEach-Object { " [ {0} = {1} ]" -f $_, $hashtable.Item($_) }
"`nItems (Enumerator iteration):"
$enumerator = $hashTable.GetEnumerator()
while ($enumerator.MoveNext())
{
" [ {0} = {1} ]" -f $enumerator.Current.Key, $enumerator.Current.Value
}
}
$fileContent = @"
Foo = a
Bar = b
"@
$maliciousFileContent = @"
Foo = a
Bar = b
Count = 0
Keys =
Values =
"@
$hashtable = ConvertFrom-StringData $fileContent
$damagedHashtable = ConvertFrom-StringData $maliciousFileContent
Get-HashtableProperties $hashtable "Normal Hash Table"
Get-HashtableProperties $damagedHashtable "Damaged Hash Table"
輸出:
---------- Normal Hash Table ----------
Count : 2
Keys.Count : 2
Values.Count : 2
Actual Count (Reflection) : 2
Items (Keys iteration):
[ Bar = b ]
[ Foo = a ]
Items (Enumerator iteration):
[ Bar = b ]
[ Foo = a ]
---------- Damaged Hash Table ----------
Count : 0
Keys.Count : 1
Values.Count : 1
Actual Count (Reflection) : 5
Items (Keys iteration):
[ = ]
Items (Enumerator iteration):
[ Count = 0 ]
[ Bar = b ]
[ Foo = a ]
[ Values = ]
[ Keys = ]
問題:有沒有防止這個問題,除了手動檢查任務之前每個鍵的方式和/或當我們需要訪問某些Hashtable
屬性的值時,在代碼中處處使用Reflection?
您可以創建自己的方法在添加之前將其過濾掉? 'foreach($ key to $ wanttoadd){if(!(CheckProtectedKeys($ key)){....}}'。爲什麼要使用散列表來存儲一個叫做「Count」的東西?散列表每次只能包含一個項目關鍵字和「count」是一個名字,聽起來更像是你應該在對象中使用的東西(並且在數組中收集)。我看到了這個問題,但我認爲避免這些屬性名稱更容易(在我看來,它不是「 hashtable「-material)^^ – 2013-02-27 21:51:34
@Graimer:我同意使用」Count「作爲散列表鍵的機率很低,但這是一種編程語言語義問題,並且語言用戶可以自由使用將「Count」與他們喜歡的任何含義聯繫起來。在我的情況下,這個問題是相當理論化的,我個人也會避免在真實腳本中使用這個問題。 – 2013-02-27 22:08:06