我是Java新手,在學習時發現String
是不可變的。當我讀到背後的原因時,出現了一些原因,例如性能提升,因爲它的值不能被修改,並且它可以被多個線程共享。這些理由我明白。
但我不明白它與安全有關。 String
如何在Java安全性中不可變?Java字符串如何不可變增加安全性?
請幫我理解。提前致謝。
我是Java新手,在學習時發現String
是不可變的。當我讀到背後的原因時,出現了一些原因,例如性能提升,因爲它的值不能被修改,並且它可以被多個線程共享。這些理由我明白。
但我不明白它與安全有關。 String
如何在Java安全性中不可變?Java字符串如何不可變增加安全性?
請幫我理解。提前致謝。
一個非常普遍的做法書面類庫被存儲傳遞到你的API,比如參數,在構造函數,像這樣:
public class MyApi {
final String myUrl;
public MyApi(String urlString) {
// Verify that urlString points to an approved server
if (!checkApprovedUrl(urlString)) throw new IllegalArgumentException();
myUrl = urlString;
}
}
String
可變,這會導致一個微妙的利用:攻擊者會傳遞一個好的URL,等待幾微秒,然後將URL設置爲指向攻擊站點。
由於沒有存儲複製是一個相當普遍的做法,因爲字符串是最常用的數據類型中,留下串可變將開闢還未被寫入開放的一個嚴重的安全問題,許多API。使字符串不可變將關閉所有API的特定安全漏洞,包括那些尚未寫入的API。
(「部分」)可變性的一個很好的例子是File。本質上它只是包裝一個'String'。然而,有很多情況下它已被用於安全檢查。惡意的子類可以在檢查和使用之間改變(TOCTOU/TOC2TOU漏洞)。 – 2013-03-07 17:17:49
我不知道微妙的漏洞是如何完成的,但假設該方法會被另一個線程以某種方式攔截。基本上,因爲如果使用urlString「ABC」調用MyApi構造函數時,String是不可變的,則內容不能從構造函數外部更改。如果它不是不可變的,則可以通過調用urlString =「someMaliciousUrl」在另一個線程上進行變異。在checkApprovedUrl調用之後。這種理解是否正確? – Mercury 2016-04-30 12:22:33
@Mercury是的,這是對上述攻擊的正確理解。 – dasblinkenlight 2016-04-30 12:25:58
字符串是,你不能改變對象本身不變的手段,但你可以改變課程的參考。當你調用(例如)a =「ty」時,實際上是將a的引用更改爲由字符串字面值「ty」創建的新對象。更改對象表示使用它的方法來改變它的領域之一,例如:
Foo x = new Foo("the field");
x.setField("a new field");
System.out.println(x.getField()); // prints "a new field"
而不可變類(聲明爲final),例如字符串,你不能改變當前的字符串,但您可以返回一個新的String,即:
String s = "some text";
s.substring(0,4);
System.out.println(s); // still printing "some text"
String a = s.substring(0,4);
System.out.println(a); // prints "some"
不可改變的字符串是必需的安全管理器的概念工作。 dasbklinkenlight已經在他的回答中處於正確的軌道上,但可變字符串將完全打破沙箱概念。
例如,當你做一個new FileInputStream("foo");
讀取文件時,API的實現將在內部等等做:
如果調用就能夠修改這兩個步驟之間的字符串,安全檢查可以爲一個成功文件,而實際上將打開一個不同的文件。
不知道如果我理解正確,我有一個疑問,因爲Java通過價值安全檢查發生了foo只有foo將被打開 – 2017-11-25 10:20:16
它說它有助於安全嗎?的 – ivant 2013-03-07 15:24:03
可能重複[Java繼承,如何延伸的一類效果的實際類](http://stackoverflow.com/questions/15165619/java-inheritance-how-does-a-extending-a-class-effect- 「實際」類) – jtahlborn 2013-03-07 15:33:19