2013-07-24 29 views
6

Tôi thấy câu trả lời từ một số khác là post:Tại sao chuỗi có thể thay đổi có thể gây ra vấn đề bảo mật?

Chuỗi được sử dụng rộng rãi làm thông số cho nhiều lớp java, v.d. để mở kết nối mạng, để mở kết nối cơ sở dữ liệu, mở tệp. Nếu String không phải là bất biến, điều này sẽ dẫn đến mối đe dọa bảo mật nghiêm trọng.

Tôi nghĩ rằng việc kiểm tra chuỗi trước khi sử dụng nó sẽ giải quyết được sự cố. Tại sao nó là một lý do mà chuỗi được thiết kế để không thay đổi?

Có ai cho tôi một ví dụ mã cụ thể không?

+3

"Tôi nghĩ rằng việc kiểm tra chuỗi trước chúng ta e nó sẽ giải quyết vấn đề "Trừ khi bạn đang sử dụng một cách rõ ràng một số loại khóa, không. –

+0

Nếu được triển khai không đúng cách, điều gì sẽ ngăn một người phạm tội thay đổi tham chiếu của séc? – Gamb

+0

Có nhiều lý do mà chuỗi được thiết kế là không thay đổi, hiểu được sự bất biến như thế: * khi một lớp độc lập và hoàn toàn cụ thể. * – Azad

Trả lời

4

Nói chung, nó dễ dàng hơn để viết và xem xét mã nhạy cảm khi giá trị không thay đổi , bởi vì có ít sự xen kẽ các hoạt động có thể ảnh hưởng đến kết quả.

Imagine mã như

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 + "')"); 
} 

Mã này làm một số kiểm tra để ngăn chặn một sự leo thang của cơ quan, nhưng điều này chỉ đúng nếu isAlphaNumeric(name) là đúng khi lập luận để executeStatement được gọi.

Nếu hai câu lệnh đầu tiên được sắp xếp lại thì đây không phải là vấn đề, do đó, sự bất an phát sinh, một phần, từ sự xen kẽ xấu. Nhưng mã khác có thể gọi hàm này và giả định rằng name không bị thay đổi bởi nó, do đó có thể phải thực hiện và thực hiện lại kiểm tra tính hợp lệ.

Nếu String không phải là không thay đổi, thì có thể nó đã bị thay đổi bởi lookupThingy. Để đảm bảo công việc kiểm tra bảo mật hoạt động, có một số lượng mã lớn hơn phải thực hiện chính xác cho mã này để bảo mật chống lại SQL injection.

Không chỉ là số lượng mã phải thực hiện chính xác lớn hơn, mà người duy trì thay đổi cục bộ thành một chức năng có thể ảnh hưởng đến tính bảo mật của các chức năng khác ở xa. Các hiệu ứng không cục bộ làm cho việc bảo trì mã khó khăn. Duy trì các thuộc tính bảo mật luôn dicey vì lỗ hổng bảo mật hiếm khi rõ ràng, do đó, khả năng đột biến có thể dẫn đến sự xuống cấp của bảo mật theo thời gian.


Tại sao nó một lý do chuỗi được thiết kế để không thay đổi?

Điều này tách biệt với lý do tại sao tính năng bảo mật kém. Nó được tin tưởng rộng rãi rằng các chương trình được viết bằng ngôn ngữ với các loại chuỗi không thay đổi sẵn có làm ít bản sao đệm không cần thiết hơn so với những bản không có. Các bản sao đệm không cần thiết ăn bộ nhớ, gây ra hiện tượng rung GC, và có thể gây ra các thao tác đơn giản trên các đầu vào lớn để thực hiện tồi tệ hơn nhiều so với các đầu vào nhỏ. Nó cũng được nhiều người tin rằng nó dễ dàng hơn để viết chương trình chính xác khi sử dụng dây bất biến, bởi vì bạn không có khả năng không phòng thủ sao chép một bộ đệm.

+3

Hoặc tệ hơn, có lẽ Chuỗi hiển thị với một chuỗi khác. giá trị giữa kiểm tra tính toàn vẹn và sử dụng - ngay cả khi không có cuộc gọi can thiệp rõ ràng! –

+0

@ HenryKeiter, điểm tốt. –

2

Đó là phần mềm bảo mật lâu đời nhất trong sách: Trình bày một số parm cho hệ điều hành, có xác nhận parm, sau đó cập nhật parm trong khi hệ điều hành đang đề cập đến parm, vì vậy nó sẽ làm những việc khác với những gì nó đã xác minh .

Điều này đã được sử dụng để phá vỡ IBM OS/360 vào những năm 60: Để yêu cầu đĩa I/O, bạn sẽ vượt qua hệ điều hành là "chương trình kênh" chứa địa chỉ đĩa và địa chỉ bộ nhớ và các nội dung khác. Hệ điều hành sẽ kiểm tra xem địa chỉ đĩa và bộ nhớ có phải là địa điểm mà bạn đã được ủy quyền hay không, sau đó nó sẽ chuyển "chương trình kênh" đó cùng với phần cứng kênh I/O được thực hiện mà không cần tạo bản sao cục bộ trước. Nó không khó để thời gian mọi thứ để bạn muốn sửa đổi chương trình kênh sau khi nó đã được kiểm tra nhưng trước khi phần cứng kênh I/O thực hiện nó, cho phép truy cập vào đĩa và bộ nhớ trái phép.

(Hãy nhớ rằng trong bộ nhớ khung thời gian này rất quý giá, vì vậy không sao chép chương trình kênh đã lưu một lượng bộ nhớ không nhỏ. Nhưng lỗ hổng này đã nhanh chóng đóng lại khi cách khai thác nó trở nên khá nổi tiếng.)

(Tất nhiên, người ta phải đặt câu hỏi liệu bất kỳ chương trình Mục tiêu-C nào có thể được coi là "an toàn" từ mã khác đang chạy trong cùng một quy trình hay không. Sử dụng các chuỗi không thay đổi được bảo vệ chống lại sự sửa đổi vô tình hơn là chống lại sửa đổi độc hại.)