2012-01-21 4 views
17

Hi Tôi nhận được vi phạm như sau:độc hại lỗ hổng mã - Có thể khiến đại diện nội bộ bằng cách trả lại tham chiếu đến đối tượng có thể thay đổi

lỗ hổng Mã độc hại - Có thể khiến đại diện nội bộ bởi trở về tham chiếu đến đối tượng có thể thay đổi

trong mã của tôi đã viết như thế này

public String[] chkBox() { 
    return chkBox; 
} 

Làm thế nào chúng ta có thể giải quyết nó.

Trả lời

31

Theo các tiểu bang thông báo lỗi, bạn đang trở về trạng thái nội bộ (chkBox là - rất có thể - một phần của tình trạng nội bộ của một đối tượng ngay cả khi bạn không hiển thị định nghĩa của nó)

Điều này có thể gây ra vấn đề nếu bạn - ví dụ - làm

String[] box = obj.chkBox(); 
box[0] = null; 

Vì một đối tượng mảng, như tất cả các đối tượng Java, được chuyển qua tham chiếu, điều này sẽ thay đổi mảng ban đầu được lưu trữ bên trong đối tượng của bạn.

Những gì bạn có khả năng nhất muốn làm gì để khắc phục điều này là một đơn giản

return (String[])chkBox.clone(); 

mà trả về một bản sao của mảng thay vì mảng thực tế.

+1

trong giải pháp trên, chúng ta sẽ kết thúc việc tạo một đối tượng String [] mới mỗi khi chúng ta truy cập nó qua clone() Tôi chỉ cần so sánh (và không kết thúc việc tạo một đối tượng mới) không ai có giải pháp tốt hơn? –

+1

Tôi không hiểu điều này hữu ích như thế nào ngoài việc đánh bại Findbugs. Mảng sao chép vẫn có tham chiếu đến các chuỗi bao gồm trạng thái của obj. – David

+1

@David Strings chỉ đọc, vì vậy chúng không thể thay đổi. –

9

Giả sử như sau:

  1. lớp học của bạn làm việc gì đó quan trọng từ góc độ bảo mật hoặc tính riêng tư, và rằng tình trạng chkbox được bằng cách nào đó được sử dụng trong việc thực hiện các lớp học của cơ chế riêng tư/an ninh của nó.

  2. Phương thức chkBox() có thể được gọi bằng một số mã không đáng tin cậy.

Bây giờ xem xét mã này:

// ... in an untrusted method ... 

Foo foo = ... 
String[] mwahaha = foo.chkBox(); 
mwahaha[0] = "Gotcha!"; // ... this changes the effective state of `Foo` 

Bằng cách trả về một tham chiếu đến các mảng thực tế đại diện cho chkbox, bạn cho phép mã bên ngoài đến lớp Foo đạt trong và thay đổi trạng thái của nó.

Điều này là xấu từ quan điểm thiết kế (nó được gọi là "trừu tượng bị rò rỉ"). Tuy nhiên, nếu lớp này được sử dụng trong ngữ cảnh có thể có mã không tin cậy, thì phương thức này (phương pháp chkBox()) là lỗ hổng bảo mật tiềm năng. Đó là những gì thông báo vi phạm đang cho bạn biết.

(Tất nhiên, kiểm tra mã có không có cách nào biết được nếu lớp học đặc biệt này là thực sự bảo mật quan trọng. Đó là để bạn có thể hiểu được. Những gì nó đang thực sự nói với bạn là "Hey! Nhìn đây! Đây là đáng ngờ!")


Việc sửa chữa phụ thuộc vào việc mã này (hoặc thực sự toàn bộ thư viện hoặc ứng dụng) là bảo mật quan trọng ... hoặc mã được bảo mật quan trọng trong một số triển khai trong tương lai. Nếu đây là một báo động giả, bạn chỉ có thể ngăn chặn các vi phạm; tức là đánh dấu nó vì thế sẽ bỏ qua kiểm tra Nếu đây là một vấn đề thực tế (hoặc có thể trở thành một vấn đề thực tế), sau đó, hoặc trả về một bản sao của mảng:.

return (String[]) chkBox.clone(); 

Nhưng rõ ràng, có một chi phí hiệu suất trong nhân bản mảng mỗi khi bạn gọi chkBox. Ngoài ra, bạn có thể sửa đổi chkBox phương pháp để trả lại một phần được chọn của mảng:

public String chkBox(int i) { 
     return chkBox[i]; 
    } 

Trong trường hợp này, tôi nghi ngờ rằng cách tiếp cận thay thế sẽ tốt hơn ... mặc dù nó phụ thuộc vào cách phương pháp này hiện đang được sử dụng.

+1

Tôi vẫn tự hỏi tại sao sonar chỉ báo cáo sự cố này cho mảng và không, ví dụ: đối với danh sách hoặc bất kỳ loại cấu trúc dữ liệu có thể thay đổi nào khác. Có nhiều hơn đến nó, có lẽ do cách mảng được lưu trữ trong bộ nhớ? –

+0

* "Có nhiều hơn không, có lẽ do cách mảng được lưu trữ trong bộ nhớ?" * - Theo như tôi biết, không. –

+1

Sự khác biệt thực sự là với một mảng nó là không thể ngăn chặn một người nào đó với tham chiếu mảng từ việc thay đổi nội dung. Với các kiểu đối tượng, truy cập nó qua trung gian bởi API đối tượng (nếu API được chọn đúng thực hiện), điều này làm cho khó phân biệt giữa các cách sử dụng an toàn và không an toàn. (Nếu kiểm tra lỗi "sói khóc" quá thường xuyên, nó sẽ không được sử dụng.) –