2013-07-24 160 views
6

我看到了另一個答案post爲什麼可變字符串會導致安全問題?

字符串已被廣泛用作許多Java類的參數,例如打開網絡連接,打開數據庫連接,打開文件。如果字符串不是不可變的,這會導致嚴重的安全威脅。

我想在使用之前檢查字符串會解決問題。爲什麼這是字符串被設計爲不可變的原因?

任何人都可以給我一個具體的代碼示例嗎?

+3

「我認爲檢查我們之前的字符串它會解決問題「除非你明確使用某種鎖,否。 –

+0

如果執行不當,什麼阻止罪犯改變支票的參考? – Gamb

+0

有很多原因,字符串被設計爲不可變的,理解如下不可變:*當一個類是獨立的,完全具體的性質* – Azad

回答

4

在一般情況下,它更容易編寫和審查敏感的代碼時,值不會更改,因爲 可能會影響結果的操作的交叉存在較少。

想象一下這樣的代碼

void doSomethingImportant(String name) { 
    if (!isAlphaNumeric(name)) { throw new IllegalArgumentException(); } 
    Object o = lookupThingy(name); 
    // No chance of SQL-Injection because name is alpha-numeric. 
    connection.executeStatement("INSERT INTO MyTable (column) VALUES ('" + name + "')"); 
} 

的代碼做一些檢查,以防止權力的升級,但如果在參數executeStatement被稱爲isAlphaNumeric(name)是真的這隻適用。

如果前兩個語句被重新排序,那麼這不會是一個問題,所以不安全性部分來自於錯誤的交錯。但其他代碼可能會調用此函數並假定name未被更改,因此可能必須執行並重新執行有效性檢查。

如果String不是不可變的,那麼它可能已被lookupThingy更改。爲了確保安全檢查能夠正常工作,爲了防止SQL注入,這些代碼必須正確執行才能保證安全。

不僅需要正確執行大量代碼,而且對一個函數進行本地更改的維護人員可能會影響遠程其他函數的安全性。非局部效應使代碼維護變得困難。由於安全漏洞很少顯而易見,因此維護安全屬性始終是危險的,因此可變性可能會導致安全性隨着時間的推移而降低。


爲什麼一個原因,字符串被設計爲不可變的?

這與安全性差的原因是分開的。

人們普遍認爲,使用易於使用的不可變字符串類型的語言編寫的程序比不使用不必要的緩衝區副本少。不必要的緩衝區副本會消耗內存,導致GC流失,並且可能會導致大型輸入的簡單操作比小型輸入更糟糕。

人們普遍認爲,使用不可變字符串時編寫正確的程序更容易,因爲您不可能無法防禦地複製緩衝區。

+3

或更糟的是,也許字符串是可見的另一個線程,然後可以改變它完整性檢查和使用之間的價值 - 即使沒有明確的干預呼叫! –

+0

@HenryKeiter,好點。 –

2

這是本書中最古老的安全欺騙:向操作系統提供一些parm,讓它驗證parm,然後在操作系統引用parm時更新parm,因此它會執行與驗證操作不同的內容。

這是用來在60年代重新打破IBM OS/360:要請求磁盤I/O,您可以將操作系統傳遞給包含磁盤地址和內存地址以及其他內容的「通道程序」。操作系統會檢查磁盤和內存地址是否是您授權的位置,然後它會將該「通道程序」傳遞給要執行的I/O通道硬件,而不會先創建本地副本。這並不難,因爲在檢查之後但在I/O通道硬件執行之前修改通道程序,允許訪問未經授權的磁盤和內存。 (請記住,在這個時間段內存非常珍貴,所以不要複製頻道程序保存了不平凡的內存,但是一旦利用它的方式變得相當出名,這個漏洞很快就會關閉。 )

(當然,我們必須質疑,Objective-C程序是否可以被認爲是「安全的」,而不受其他代碼的影響。最好,使用不可變字符串更多的是防止意外修改而不是惡意修改)

相關問題