篩選器將在 finally 語句之前運行,這樣,如果可以執行其他代碼,則造成狀態更改的任何操作都可以帶來安全問題。例如:
try { Alter_Security_State(); // This means changing anything (state variables, // switching unmanaged context, impersonation, and so on) // that could be exploitable if malicious code ran before state is restored. Do_some_work(); } finally { Restore_Security_State(); // This simply restores the state change above. }該偽代碼允許篩選器備份堆棧以運行任意代碼。具有類似效果的其他操作示例是對另一個標識的臨時模擬,這樣會設置一個避開某個安全檢查的內部標志,并更改與線程關聯的區域性等等。
建議的解決方案是引入異常處理程序,將代碼的線程狀態更改與調用方的篩選器塊隔離開。但重要的是,要正確引入異常處理程序,否則將無法解決該問題。下面的 Microsoft Visual Basic(R) 示例將切換 UI 區域性,但可以類似地公開任何線程狀態更改。
YourObject.YourMethod() { CultureInfo saveCulture = Thread.CurrentThread.CurrentUICulture; try { Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); // Do something that throws an exception. } finally { Thread.CurrentThread.CurrentUICulture = saveCulture; } } Public Class UserCode Public Shared Sub Main() Try Dim obj As YourObject = new YourObject obj.YourMethod() Catch e As Exception When FilterFunc Console.WriteLine("An error occurred: '{0}'", e) Console.WriteLine("Current Culture: {0}", Thread.CurrentThread.CurrentUICulture) End Try End Sub Public Function FilterFunc As Boolean Console.WriteLine("Current Culture: {0}", Thread.CurrentThread.CurrentUICulture) Return True End Sub End Class在此例中,正確的修復措施是在 try/catch 塊中包裝現有的 try/finally 塊。只將 catch-throw 子句引入現有的 try/finally 塊中將無法解決問題:
YourObject.YourMethod() { CultureInfo saveCulture = Thread.CurrentThread.CurrentUICulture; try { Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); // Do something that throws an exception. } catch { throw; } finally { Thread.CurrentThread.CurrentUICulture = saveCulture; } }這不會解決問題,因為在 FilterFunc 獲得控制權之前尚未運行 finally 語句。
以下代碼通過確保在根據調用方的異常篩選塊提供異常之前執行 finally 子句,來解決該問題。
YourObject.YourMethod() { CultureInfo saveCulture = Thread.CurrentThread.CurrentUICulture; try { try { Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); // Do something that throws an exception. } finally { Thread.CurrentThread.CurrentUICulture = saveCulture; } } catch { throw; } } 非托管代碼某些庫代碼需要調用非托管代碼(例如,本機代碼 API,如 Win32)。因為這意味著脫離托管代碼的安全邊界,所以應十分謹慎。如果您的代碼是安全中立的(請參閱本文的安全中立代碼部分),則您的代碼和任何調用它的代碼都必須擁有非托管代碼權限 (SecurityPermission.UnmanagedCode)。
但是,要求您的調用方擁有這么大的權限通常是不合理的。在這種情況下,您的受信任代碼可以是“調解者”,類似于先前描述的托管包裝程序或庫代碼。如果基礎非托管代碼的功能是完全安全的,則可以直接公開它;否則,需要先進行適當的權限檢查 (demand)。
當您的代碼調用非托管代碼、但您不想讓調用方擁有該權限時,必須斷言您的權利。斷言會在您的幀處阻塞堆棧審核。您必須謹慎小心,不要在該過程中創建安全漏洞。通常,這意味著您必須請求適當的調用方權限,然后只使用非托管代碼來執行該權限允許的操作,但不能再執行其他操作。在某些情況下(例如,獲得一天中的時間),非托管代碼可以直接公開給調用方,而不需要進行任何安全檢查。在任何情況下,作出斷言的任何代碼都必須為安全性負責。
文章來源于領測軟件測試網 http://www.kjueaiud.com/