2013-02-22 19 views
13

Nguyên tắc bảo mật Java phổ biến để xử lý dữ liệu nhạy cảm (== mật khẩu) khuyên bạn không bao giờ sử dụng đối tượng String để lưu trữ dữ liệu và thay vào đó sử dụng một mảng byte hoặc ký tự. Tôi đang cố gắng áp dụng hướng dẫn này trong trình xử lý HttpServlet. Đặc biệt, tôi đang sử dụng một cách tiếp cận cơ bản-xác thực giống như thông tin đăng nhập được truyền vào trong một tiêu đề (đây là một yêu cầu GET, vì vậy không có nội dung).Trong Java, làm thế nào để trích xuất một mật khẩu từ một tiêu đề HttpServletRequest mà không tạo ra một đối tượng String?

Vấn đề tôi đang gặp phải là dường như không thể truy cập dữ liệu tiêu đề mà không tạo đối tượng Chuỗi, vi phạm nguyên tắc từ đường đi. Tôi đã tìm kiếm một giải pháp khá kỹ lưỡng và không tìm thấy bất kỳ cuộc thảo luận nào có liên quan. Có ai có bất kỳ cái nhìn sâu sắc về vấn đề này?

LƯU Ý: điều này diễn ra qua HTTPS, do đó, không có sự cố bảo mật kết nối tại đây.

+0

Không phải mọi thứ 1s và 0s .. Chuỗi bị đe dọa bảo mật hơn byte [] như thế nào? – smk

+1

@smk: Bởi vì 'Chuỗi' có thể được tập trung, có nghĩa là chúng bám sát trong bộ nhớ lâu sau khi bạn sử dụng xong chúng. –

+6

@smk Strings không thay đổi. Một khi bạn có một, nó sẽ treo xung quanh trong bộ nhớ cho đến khi nó được thu thập rác (lâu sau khi bạn đang thực hiện với nó). Với một 'byte []', khi bạn đã hoàn thành nó, bạn có thể ghi đè lên các nội dung để ngăn không cho đọc dữ liệu. – cheeken

Trả lời

12

Câu trả lời đơn giản là bạn không thể lấy thông số dưới bất kỳ hình thức nào khác ngoài Chuỗi. Ít nhất, không sử dụng các API servlet tiêu chuẩn. Nhưng có một vài khả năng "thoát ra".

  1. Nếu bạn chuẩn bị thực sự xấu, bạn có thể phá vỡ sự trừu tượng của đối tượng String và tiếp cận và ghi đè các ký tự. (Chuỗi thực tế có thể thay đổi nếu bạn chuẩn bị phá vỡ các quy tắc. Đây là một trong số ít trường hợp mà điều này có thể được biện minh.)

  2. Có thể có một phần mở rộng API không chuẩn trong việc triển khai vùng chứa web của bạn (nói) HttpServletRequest để thực hiện việc này. Nếu không, bạn có thể giữ mã nguồn và thêm mã nguồn. (Giả sử bạn đang sử dụng một container web mã nguồn mở.)


Có nói rằng, IMO cách tiếp cận "không dây" đối với an ninh Java là sai lầm, hoặc ít nhất là qua đánh giá về những gì nó đạt được.

Trình bảo vệ phương pháp "không dây" chống lại khả năng có thể tìm kiếm thông tin trong không gian địa chỉ của ứng dụng, định vị những thứ giống như chuỗi và đánh dấu các mật khẩu có thể. Về lý thuyết, điều này có thể được thực hiện bằng cách:

  • một hack mà phá vỡ mô hình thực hiện của JVM và nhìn vào bộ nhớ liệu,
  • gắn một debugger Java và trawling thông qua các đối tượng có thể truy cập,
  • sử dụng "/ dev/mem "hoặc tương tự bộ nhớ đọc quá trình từ bên ngoài,
  • truy cập phần còn lại của hình ảnh hoán đổi của chương trình trên ổ cứng hoặc
  • bằng cách nào đó khiến nó đổ rác và đọc kết xuất.

Tuy nhiên, tất cả nhưng điều đầu tiên trong số này yêu cầu người xấu đã phá vỡ bảo mật trên hệ thống. Và nếu kẻ xấu đã làm điều đó có những cách khác (có lẽ đơn giản hơn) để ăn cắp mật khẩu từ chương trình của bạn ... mà cách tiếp cận "không dây" sẽ không ngăn cản.

Và nếu bạn lo lắng về việc hack khai thác lỗ hổng bảo mật Java để đọc bộ nhớ nguyên, lỗ hổng đó có thể được sử dụng theo các cách khác; ví dụ. để chèn mã để thay đổi cách mật khẩu được xử lý bởi mã.

Vì vậy, tóm lại, "không có chuỗi" đang bảo vệ chống lại các hacks thực sự khó khăn, hoặc chống lại các trường hợp an ninh của bạn đã được thổi. IMO, nó không phải là giá trị nỗ lực ... trừ khi bạn đang yêu cầu để thực hiện an ninh cấp quân sự.

+0

Theo như số 1 đi, Java có xác định những hậu quả có thể xảy ra ở đó không? Hãy nói rằng đã tồn tại một chuỗi bằng nhau trong bộ nhớ ở đâu đó, ví dụ như một khóa trong một hashtable. Việc triển khai Java có được phép ánh xạ cả hai chuỗi vào cùng một "cửa hàng sao lưu văn bản" trong trường hợp này không (xin lỗi tôi không biết thuật ngữ Java chính xác ở đây)? Nếu đó là như vậy, bằng cách rõ ràng thanh toán bù trừ các chuỗi đến với các gói HTTP tôi thực sự có thể được mở một lỗ hổng bảo mật DOS luẩn quẩn trong ứng dụng của tôi. –

+1

Nó có thể làm điều đó. Nhưng trong thực tế, nó sẽ chỉ làm điều đó nếu một cái gì đó gọi là 'String.intern()' trên cả hai dây. Khả năng khác là chuỗi mật khẩu chia sẻ sự ủng hộ với một chuỗi lớn hơn; ví dụ. chuỗi đại diện cho dòng tiêu đề. Tôi sẽ không mong đợi một trong những tình huống này là một vấn đề. –

+0

Thực tế, có một tình huống khác. Đó là các JVM cũ hơn, nơi việc thực thi 'String' sẽ chia sẻ mảng sao lưu' char [] 'giữa các chuỗi khác nhau trong một số trường hợp. Việc thực hiện String được viết lại trong Java 1.7.0_u6 để sửa lỗi này. (Đó là một nguồn rò rỉ bộ nhớ!) –

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