2013-03-07 23 views
14

Tôi mới sử dụng Java và khi đang học, tôi đã thấy một thực tế rằng String là không thay đổi. Khi tôi đọc lý do đằng sau nó, một vài lý do nảy sinh, ví dụ như tăng hiệu suất, vì giá trị của nó không thể sửa đổi được, và nó có thể được chia sẻ bởi nhiều luồng. Những lý do này tôi hiểu.
Nhưng tôi không hiểu nó liên quan đến an ninh như thế nào. Làm thế nào để String trợ giúp không thay đổi trong bảo mật Java?Làm thế nào để chuỗi Java không thể tăng tính bảo mật?

Hãy giúp tôi hiểu. Cảm ơn trước.

+2

Trường hợp nói rằng nó giúp bảo mật? – ivant

+0

có thể trùng lặp của [Thừa kế Java, làm thế nào để mở rộng một lớp có hiệu lực lớp thực tế] (http://stackoverflow.com/questions/15165619/java-inheritance-how-does-a-extending-a-class-effect- lớp thực tế) – jtahlborn

Trả lời

15

một thực tế rất phổ biến trong các thư viện lớp viết được lưu trữ các thông số truyền vào API của bạn, chẳng hạn, trong một constructor, như thế này:

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; 
    } 
} 

Were String có thể thay đổi, điều này sẽ dẫn đến một sự khai thác tinh tế: kẻ tấn công sẽ chuyển một URL tốt, chờ một vài micro giây và sau đó đặt URL để trỏ đến một trang web tấn công.

Vì lưu trữ mà không sao chép là thực tiễn phổ biến hợp lý và vì chuỗi là một trong các loại dữ liệu được sử dụng phổ biến nhất, nên các chuỗi có thể thay đổi sẽ mở ra nhiều API chưa được viết cho vấn đề bảo mật nghiêm trọng. Việc tạo chuỗi không thay đổi sẽ đóng lỗ bảo mật cụ thể này cho tất cả các API, bao gồm cả các chuỗi chưa được viết.

+1

Một ví dụ điển hình về khả năng thay đổi ("một phần") là 'Tệp'. Về cơ bản nó chỉ bao bọc một 'Chuỗi'. Tuy nhiên, đã có một số trường hợp nó được sử dụng để kiểm tra bảo mật. Một lớp con độc hại có thể thay đổi kiểm tra và sử dụng betwixt (lỗ hổng TOCTOU/TOC2TOU). –

+1

Tôi không chắc chắn cách khai thác tinh tế được thực hiện nhưng giả sử phương pháp sẽ bị chặn bằng cách nào đó thông qua một chủ đề khác. Về cơ bản, vì String là bất biến nếu hàm tạo MyApi được gọi với urlString "ABC", thì nội dung không thể thay đổi từ bên ngoài hàm tạo. Nếu nó không phải là bất biến, nó có thể được đột biến trên thread khác chỉ đơn giản bằng cách gọi urlString = "someMaliciousUrl"; sau cuộc gọi checkApprovedUrl. Sự hiểu biết đó có đúng không? – Mercury

+0

@Mercury Vâng, đây là sự hiểu biết chính xác về cuộc tấn công được mô tả ở trên. – dasblinkenlight

0

Chuỗi là bất biến có nghĩa là bạn không thể thay đổi đối tượng, nhưng bạn có thể thay đổi tham chiếu của khóa học. Khi bạn gọi (ví dụ) a = "ty", bạn đang thực sự thay đổi tham chiếu của một đối tượng mới được tạo bởi chuỗi "ty" theo nghĩa đen. Thay đổi một đối tượng có nghĩa là sử dụng phương pháp của nó thay đổi một trong các lĩnh vực của nó, ví dụ:

Foo x = new Foo("the field"); 
x.setField("a new field"); 
System.out.println(x.getField()); // prints "a new field" 

trong khi ở một lớp học bất biến (khai báo là final), ví dụ String, bạn không thể thay đổi String hiện tại nhưng bạn có thể quay trở lại một string mới, ví dụ:

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" 
+4

"cuối cùng" không có nghĩa là nó không thay đổi. Đối với các lớp học có nghĩa là bạn không thể kế thừa nó. – ivant

+0

là không thay đổi bạn phải là cuối cùng để phân lớp của bạn không phá vỡ bất biến – topcat3

+0

có thể là trường hợp, nhưng nó không đủ để khai báo nó cuối cùng để làm cho nó bất biến. – ivant

3

Chuỗi không thể thay đổi được yêu cầu để khái niệm SecurityManager hoạt động. dasbklinkenlight đã đi đúng hướng với câu trả lời của anh ta, nhưng các chuỗi có thể thay đổi sẽ phá vỡ hoàn toàn khái niệm sandbox.

Ví dụ, khi bạn làm một new FileInputStream("foo"); để đọc một tập tin, việc thực hiện API sẽ nội bộ làm số những người khác:

  • gọi phương thức checkRead quản lý bảo mật với "foo" như một cuộc tranh cãi và ném một ngoại lệ nếu việc kiểm tra không
  • hệ điều hành
  • sử dụng các cuộc gọi đến thực sự mở file nếu kiểm tra an ninh thông qua

Nếu Invoker có thể sửa đổi các chuỗi giữa hai bước này, việc kiểm tra an ninh có thể thành công trong một tệp, trong khi thực sự một tệp khác sẽ được mở.

+0

không chắc chắn Nếu tôi hiểu chính xác tôi có một nghi ngờ vì java đi qua Kiểm tra bảo mật giá trị đã xảy ra cho foo chỉ foo sẽ được mở –

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