2010-09-07 25 views
5

Tôi không phải là nhà phát triển Java, nhưng khách hàng của tôi đã thuê một bản cập nhật một số tệp JAR trên trang web của họ. Trước khi làm như vậy, chúng tôi đã kiểm tra mã hiện có và tìm thấy một số lỗ hổng bảo mật. Một trong những giải pháp chúng tôi sử dụng để làm cho các tệp an toàn hơn là tạo một người dùng cơ sở dữ liệu mới với quyền truy cập chỉ đọc vào cơ sở dữ liệu và chỉ dành cho những bảng mà các tệp JAR cần để hoạt động. Sau đó tôi phát hiện ra rằng họ đang lưu trữ các thông tin đăng nhập này trong các tệp văn bản thuần túy cùng với các tệp JAR, chỉ có một số người được giáo dục đoán từ công chúng nói chung. Và cuối cùng hôm nay họ đang yêu cầu nhiều đặc quyền cơ sở dữ liệu lỏng lẻo hơn, nhưng tôi không nghĩ rằng cô ấy hiểu rằng cô ấy thực sự không cần chúng cho một tệp JAR được viết đúng cách.Các kết nối cơ sở dữ liệu an toàn thường được thực hiện như thế nào trong các tệp JAR?

Dù sao, tôi khá chắc chắn nhà phát triển này sẽ không biết lỗ hổng bảo mật nếu nó cắn cô ấy ở mặt sau. Và tôi không biết đủ về các tệp Java/JAR để tư vấn cho cô ấy về những gì cô ấy nên làm, chỉ đủ về infosec để nói cho cô ấy biết cô ấy không nên làm gì.

Vậy các cân nhắc bảo mật điển hình khi viết tệp JAR được phân phối kết nối với cơ sở dữ liệu MySQL từ xa là gì? Có cách nào tiêu chuẩn để mã hóa chi tiết kết nối (tên người dùng và/hoặc mật khẩu) không? IIRC, không phải tệp .jar vừa tôn vinh lưu trữ ZIP và không ai có thể giải nén tệp và xem chi tiết kết nối trong mã nguồn? Có cách nào để mã hóa nội dung tệp jar không?


CẬP NHẬT: Tôi đã nhận được giải thích rõ sau đây từ nhà phát triển. Điều này có đúng không?

Tất cả các lớp trong tệp jar được mã hóa. tôi luôn mã hóa tất cả các tệp lớp trước khi lưu trữ chúng trong tệp jar. nếu bạn mở bất kỳ lọ [redacted] nào, bạn sẽ chỉ thấy mã được mã hóa. do đó không có cơ hội để người dùng có thể xem mã nguồn bằng cách giải mã lớp được phân loại. các lớp học sử dụng jdbc để kết nối với db, tìm kiếm eangine cần kết nối với DB để chạy sqls. các sqls này nằm trong các clase được mã hóa trong tệp jar.

khi tôi hỏi bạn về việc mã hóa mật khẩu DB, ý tôi là những gì bạn nói bên dưới. chúng ta sẽ viết mã mã hóa/giải mã trong java và sử dụng nó. Lớp được biên dịch từ mã nguồn này một lần nữa sẽ được mã hóa như là một phần của thủ tục mã hóa lớp reoutine. Chúng tôi sử dụng một công cụ obfuscation Java gọi là Retroguard để mã hóa tất cả các lớp. chúng tôi cũng nhúng một khóa vào trang html để đảm bảo rằng ứng dụng sẽ chỉ hoạt động nếu nó đã được tải xuống biểu mẫu [redacted]. nếu người dùng sao chép bình vào máy cục bộ của mình và cố gắng chạy nó, nó sẽ thất bại.

+0

Hệ thống DB của bạn hỗ trợ tùy chọn đăng nhập nào? Nó có hỗ trợ sử dụng các phím đã ký (a la SSH) thay vì sử dụng/pass không? Có các cơ chế xác thực khác (LDAP, AD, PAM) trong môi trường có thể được sử dụng thay cho DB auth không? – Freiheit

+2

Nếu bạn mã hóa các chi tiết, thì bạn sẽ cần phải giải mã chúng trên máy khách. Trò chơi kết thúc. Sau đó, bạn có thể sẽ gửi cho họ trong rõ ràng trên dây - có nghĩa là một kẻ thù không cần phải thậm chí bận tâm có Java cài đặt. –

+0

Cảm ơn Tom, tôi đã không nghĩ rằng kết quả cuối cùng vượt trội hơn bất kỳ bảo mật nào chúng tôi thực hiện trong thiết kế. Người dùng mysql đặc biệt này có quyền truy cập chỉ đọc, vì vậy tôi gần như bị cám dỗ để nói "OK, bất cứ điều gì, ít nhất họ không thể thay đổi dữ liệu nếu họ nhận được các thông số kết nối" nhưng tôi không cảm thấy rất tốt về nó trong thời gian dài. –

Trả lời

3

Có, JAR chỉ là tệp ZIP, vì vậy hoàn toàn có thể mở một tệp bằng WinZip và xem nội dung. Nếu bạn biết mình đang làm gì, bạn có thể tìm thấy mật khẩu văn bản thuần tuý bên trong.

Có vẻ như JAR của bạn chứa khách hàng kết nối trực tiếp với cơ sở dữ liệu. Bạn không nói điều này được thực hiện qua Internet hay VPN hay mạng LAN. Cơ sở dữ liệu được triển khai từ xa từ máy khách?

Đây là một lý do khiến ứng dụng máy khách/máy chủ biến mất: thật khó để bảo mật chúng qua Internet.

Ứng dụng của bạn có vẻ giống như máy khách-máy chủ cổ điển đối với tôi. Tôi có đúng không?

Cấp trung bình thường được giới thiệu giữa khách hàng và cơ sở dữ liệu để kiểm tra bảo mật, xác nhận và ràng buộc các đầu vào và yêu cầu đưa đón đến trình xử lý thích hợp để thực hiện.Yêu cầu người dùng trình bày bằng chứng xác thực rằng tầng giữa của bạn phải xác thực trước khi chuyển chúng đến cơ sở dữ liệu.

Nó cũng có thể cung cấp cho bạn cơ hội chiến đấu chống lại các cuộc tấn công SQL injection.

Nếu bạn mã hóa nội dung JAR, bạn sẽ phải viết trình tải lớp tùy chỉnh để giải mã chúng khi tải. Không dành cho người yếu tim.

Nếu khách hàng của bạn là một ứng dụng Swing, với tất cả các công cụ logic và cơ sở dữ liệu được tích hợp vào trình xử lý sự kiện và người nghe đã đăng ký cho mỗi thành phần, bạn sẽ có một viết lại nghiêm túc trên tay. Bạn sẽ chuyển sang một kiến ​​trúc hướng dịch vụ, nơi mà tất cả công việc được thực hiện bởi các dịch vụ ở phía máy chủ. Các khách hàng chỉ làm những gì nó được cho là trong MVC cổ điển: vượt qua các sự kiện cùng với phía máy chủ và kết quả hiển thị. Khách hàng của bạn sẽ nhẹ hơn rất nhiều.

Đó sẽ là cú sốc lớn nhất đối với nhóm phát triển và doanh nghiệp của bạn.

+0

Bình sẽ được nhúng vào một trang HTML và sẽ yêu cầu trở lại cơ sở dữ liệu MySQL mà phần còn lại của trang web sử dụng. Trung thực không chắc chắn lý do tại sao họ đã đi với Java về điều này. Tôi đoán là một số kỹ sư biết điều đó và không muốn bị làm phiền với việc học PHP. Vui lòng xem nội dung cập nhật của tôi trong thư gốc để biết thêm thông tin. –

+0

PHP sẽ tốt hơn thế nào? Tôi không thấy rằng bản cập nhật làm tôi cảm thấy tốt hơn nhiều. Bạn có tính phí cho sản phẩm này không? Bạn có thực sự có một cơ sở dữ liệu MySQL tiếp xúc với toàn bộ Internet không? Chúc may mắn với điều đó. Bạn không biết ai đang xâm nhập vào cơ sở dữ liệu đó. Nó có thể làm điều này với Java, nhưng có vẻ như thiết kế của bạn là thiếu sót từ get-go. – duffymo

+0

Không, cơ sở dữ liệu hiện đang đứng sau tường lửa với một vài ngoại lệ IP. Nhưng bây giờ bạn đề cập đến nó, chúng tôi sẽ phải mở nó hoàn toàn cho điều này để làm việc. Về PHP, nó sẽ tốt hơn bởi vì tất cả các kết nối cơ sở dữ liệu sẽ xảy ra đằng sau cảnh trực tiếp tại máy chủ và chỉ dữ liệu cuối sẽ được truyền (cũng giống như mọi ứng dụng PHP/MySQL khác trên Internet) –

-1

Để đặt văn bản thuần tuý là (tôi nghĩ) rất dễ bị tổn thương. Thật vậy, người ta có thể trích xuất bình và đọc những gì được viết trong văn bản thuần tuý đó.

Nếu sử dụng bình là phải, tôi sẽ khuyên bạn nên tạo một lớp (chỉ là một lớp đơn giản) có chứa tên người dùng, mật khẩu, url, v.v ... với từ khóa cuối cùng. Mặc dù phương thức này không thực sự an toàn, ít nhất một lớp được biên dịch không thể đọc được dễ dàng. Một ưu điểm khác (hoặc có lẽ bất lợi) là thuộc tính kết nối 'mã hóa cứng' không thể dễ dàng sửa đổi. Ngay cả khi bạn có mã nguồn, bạn vẫn cần phải biên dịch lại mã nguồn và đóng lại.

+0

Vui lòng xem cập nhật của tôi cho câu hỏi ban đầu để biết thêm thông tin về cách thức đóng gói bình. –

0

Tôi nghĩ quy ước cho loại điều đó cho hầu hết các nhà phát triển là lưu trữ tệp cấu hình bên ngoài thư mục gốc của thư mục web. Tất nhiên nếu đây là một ứng dụng máy tính để bàn và không phải là trang web đó là không thể. Một cái gì đó tôi đã làm trước đây trong một ứng dụng dựa trên MySQL dựa trên SWING với số lượng người dùng hạn chế thay vì sử dụng tầng trung gian để xác thực và trình bày dữ liệu dưới dạng dịch vụ, sử dụng xác thực được tích hợp của MySQL để tất cả bảo mật sẽ được xác định trong và sau đó sao chép cài đặt quyền cho mọi người dùng. Loại cách tiếp cận đáng tin cậy nhưng đáng tin cậy.

+0

Tệp jar sẽ sử dụng tài khoản người dùng MySQL riêng biệt của nó với quyền truy cập chỉ đọc vào cơ sở dữ liệu. Nhưng nó sẽ chạy trên một trang web, và vì vậy tôi đoán là không có cách nào để lưu trữ tệp tài nguyên bên ngoài webroot bởi vì tệp jar sẽ không thể truy cập vào tệp đó (vì nó chạy dưới dạng ứng dụng cục bộ trên khách hàng kết thúc) –

+0

Ah, sau đó cho tất cả các ý định và mục đích nó bị hỏng bởi thiết kế, không có gì của bạn hoặc các chuyên gia tư vấn làm có thể sửa chữa nó theo ý kiến ​​của tôi. – Novikov

2

Tôi sẽ bắt đầu câu trả lời của mình bằng cách nêu rõ điều gì đó thường được tuyên bố: "bất kỳ người nào cũng có thể tạo một chương trình bảo mật mà họ không thể phá vỡ".

Bây giờ, lưu ý cập nhật khi đề cập đến mã hóa và làm xáo trộn được thực hiện trong cùng một bản cập nhật, bạn nên lưu ý rằng mã hóa không giống như làm xáo trộn. Về mặt kỹ thuật, mã hóa liên quan đến việc sử dụng một khóa để chuyển đổi một số văn bản thô thành bản mã, với bản rõ chỉ có thể phục hồi bằng kiến ​​thức về khóa gốc. Obfuscation là hư không gần với mã hóa theo định nghĩa - nó liên quan đến việc loại bỏ các thông tin từ mã nguồn thực thi, mà làm cho thực thi được cho là "khó" để đảo ngược-kỹ sư. Thông thường, obfuscation liên quan đến việc thay thế các ký hiệu bằng các ký hiệu nhỏ hơn, và đôi khi, sắp xếp lại mã nguồn làm cho mã nguồn được thiết kế ngược khó đọc, trong khi giữ lại hồ sơ thực thi của mã nguồn gốc (mã nguồn bị xáo trộn có cùng mã và đường dẫn dữ liệu) như bản gốc).

Điều quan trọng ở đây, là mật khẩu được mã hóa vào mã nguồn. Nó là hợp lý để giả định rằng mã nguồn obfuscated cũng sẽ chứa mật khẩu mã hóa cứng. Giả thiết này là hợp lý vì hầu hết các obfuscators chưa bao giờ cố gắng đột biến constant pool within a class file - việc biến đổi một nhóm hằng số là nguy hiểm cho nó có thể dẫn đến những thay đổi trong hành vi thời gian chạy. Nếu mật khẩu đã được mã hóa cứng vào mã nguồn dưới dạng Chuỗi, thì tệp lớp (bị xáo trộn hay không) sẽ có mật khẩu trong String constant pool, sẽ được JVM tải vào bộ nhớ (không có quá trình giải mã hoặc giải mã trong giữa).

Thực tiễn tốt nhất trong trường hợp này là để người dùng cuối chỉ định ID người dùng và mật khẩu cơ sở dữ liệu (nếu họ quản lý thiết lập ứng dụng), để lưu trữ các thông tin người dùng được cung cấp một cách an toàn (điều này phụ thuộc vào bản chất của ứng dụng, các ứng dụng Java EE nên cố gắng để container chứa các thông tin đăng nhập này) và quản lý các thông tin này một cách an toàn khi chúng được truy xuất từ ​​cửa hàng an toàn. Bạn có thể muốn xem bài viết OWASP trên Insecure Storage để biết thêm chi tiết.

Với việc sử dụng một applet, bạn không nên có ID người dùng cơ sở dữ liệu và mật khẩu trong applet. Điều này cần phải được thực hiện vì nhiều lý do - các ứng dụng tốt cho phép thay đổi ID người dùng cơ sở dữ liệu và mật khẩu chỉ với những thay đổi cấu hình cho ứng dụng. Cứng mã hóa mật khẩu trong mã nguồn là ràng buộc để tăng chi phí quản lý; bạn có thể phải có được người dùng cuối để xóa bộ nhớ cache Java applet của họ mỗi khi DBA chọn thay đổi mật khẩu (và điều này nhất định xảy ra thỉnh thoảng trong một trung tâm dữ liệu lành mạnh). Hơn nữa, bạn cũng có thể cần phải bảo vệ chống lại các khóa tài khoản cơ sở dữ liệu, khi các thay đổi đối với applet đang được triển khai. Giống như các khuyến nghị khác được đăng, nó sẽ tạo ra một ý nghĩa kinh doanh tốt để quản lý các kết nối cơ sở dữ liệu từ bên trong tầng giữa.

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