2013-02-27 41 views
8

Tôi đã chơi xung quanh với các bảng băm trong PowerShell, và tôi nhận thấy một số hành vi kỳ lạ liên quan đến các mục truy cập. Như chúng ta đã biết, PowerShell cho phép ít nhất ba cách khác nhau để gán giá trị cho băm mục bảng:Lỗ hổng bảng băm (ghi đè thuộc tính)?

$hashtable["foo"] = "bar"  #1 
$hashtable.Item("foo") = "bar" #2 
$hashtable.foo = "bar"   #3 

Trong khi đó, chúng ta sử dụng cú pháp # 3 để truy cập các thuộc tính của đối tượng Hashtable bản thân, chẳng hạn như Count, Keys, Values, v.v. Và nếu chúng ta thêm một mục có khóa mâu thuẫn với tên của một thuộc tính nội bộ, PowerShell cho phép chúng ta làm như vậy và chúng ta không còn có thể đọc giá trị của thuộc tính (ngoại trừ việc sử dụng Reflection).

Tôi đoán rằng trong trường hợp các khóa đến từ nguồn không đáng tin cậy (ví dụ: từ tệp hoặc mạng bên ngoài), điều này có thể có tác động không mong muốn đối với kiểm soát luồng và có thể bị người dùng độc hại khai thác.

đoạn này cho thấy vấn đề này:

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" 

Output:

---------- 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 = ] 

Câu hỏi: là có một cách để bảo vệ chống lại vấn đề này, ngoại trừ tay kiểm tra tất cả các chìa khóa trước khi phân công và/hoặc sử dụng Reflection ở khắp mọi nơi trong mã khi chúng ta cần truy cập vào giá trị của một số tài sản Hashtable?

+0

Bạn có thể tạo phương pháp của riêng mình để lọc ra trước khi thêm? 'foreach ($ key trong $ wanttoadd) {if (! (CheckProtectedKeys ($ key)) {....}}'. Tại sao bạn sử dụng một hashtable để lưu trữ một cái gì đó gọi là "Đếm"? Hashtables chỉ có thể chứa một mục cho mỗi và "đếm" là một cái tên nghe có vẻ giống một cái gì đó bạn nên sử dụng trong một đối tượng (và thu thập trong mảng) .Tôi thấy vấn đề, nhưng tôi nghĩ rằng dễ dàng hơn để tránh những đặc tính đó (theo ý kiến ​​của tôi không phải là " ^^ –

+0

@Graimer: Tôi đồng ý rằng cơ hội sử dụng "Đếm" là khóa có thể bắt đầu là khá thấp, nhưng đây là vấn đề ngữ nghĩa ngôn ngữ lập trình và người dùng ngôn ngữ được tự do Trong tình huống của tôi, câu hỏi này khá lý thuyết, cá nhân tôi cũng sẽ tránh được điều này trong một kịch bản thực sự –

Trả lời

6

Trong loại này của một kịch bản mà bạn có thể truy cập vào bất động sản số của Hashtable như vậy:

C:\PS> $ht = @{Count = 99} 
$ht.psbase.Count 
1 

Các hệ thống kiểu mở rộng trong PowerShell cung cấp tầm khác nhau trên một đối tượng thông qua các đặc tính này PS *. Xem chi tiết PowerShell team blog post.

+0

Làm việc cho đến khi bạn nhận được '$ ht = @ {Count = 99; PSBase = 1. .5} ';) [' select'] (http://go.microsoft.com/fwlink/?LinkID=113387) có thể giúp truy cập các thuộc tính cơ bản. e 'Đếm' và' Phím', mặc dù không chắc chắn cách bỏ ẩn 'PSBase' mà không xóa khóa khỏi bảng. –

+0

Có nhưng có một lý do khiến nhóm chọn tiền tố ETS của họ bằng "PS". Một va chạm với "PSBase" là trường hợp góc nhiều hơn "Đếm". :-) –

Các vấn đề liên quan