2010-06-28 29 views
7

Tôi đang sử dụng đoạn mã sau để khởi tạo kết nối cơ sở dữ liệu:FindBugs và bảo mật mật khẩu cơ sở dữ liệu vấn đề


public Connection getConnection() { 
     try { 
      if (null == connection) { 
       String driverName = "com.mysql.jdbc.Driver"; // MySQL MM JDBC driver 
       Class.forName(driverName); 

       // Create a connection to the database 
       String serverName = "localhost"; 
       String database = "database"; 
       String url = "jdbc:mysql://" + serverName + "/" + mydatabase; // a JDBC url 
       String username = "username"; 
       String password = "password"; 
       connection = DriverManager.getConnection(url, username, password); 
      } 
      return connection; 
     } catch (ClassNotFoundException cnfe) { 
      cnfe.printStackTrace(); 
     } catch (SQLException sqle) { 
      sqle.printStackTrace(); 
     } 
     throw new NullPointerException("Cannot establish database connection..."); 
    } 

và tôi biết đó là thói quen xấu để làm điều đó, tôi cũng chạy FindBugs chống lại các mã, và nhận được sự an toàn vấn đề nói như sau: This code creates a database connect using a hardcoded, constant password. Anyone with access to either the source code or the compiled code can easily learn the password.

Cách tốt nhất để khởi tạo kết nối cơ sở dữ liệu mà không bị vi phạm bảo mật này là gì?

Trả lời

1

Phần lớn các ứng dụng web sử dụng tên người dùng mã hóa cứng/mật khẩu để kết nối SQL của họ. Kiểm tra thông tin sản xuất vào kiểm soát nguồn, hoặc cho thực tập khả năng xóa cơ sở dữ liệu sản xuất thường bị cau mày. Thông tin sản xuất cần được bảo vệ và chỉ những nhân viên đặc quyền mới có quyền truy cập vào chúng.

Thông thường các ứng dụng web sẽ bị rò rỉ tệp cấu hình của chúng. Ví dụ: nếu tệp .xml được lưu trữ trong webroot thì tệp có thể được truy cập từ xa: http://localhost/configs/db_config.xml.

Thực tiễn phổ biến là không cho phép truy cập vào cơ sở dữ liệu của bạn (chặn cổng tcp 3306 cho mysql). Trong thực tế, đây là một yêu cầu của PCI-DSS. Ngay cả khi tên người dùng và mật khẩu cần lấy, nó sẽ là vô dụng.

+0

Nó thực sự là một vấn đề nếu bạn có nhiều hơn một nhà phát triển trong công ty của bạn. ** Không được ** sản xuất ** mật khẩu ** cho tất cả các nhà phát triển cho môi trường an toàn. Mã nguồn thường được lan truyền trên nhiều hệ thống: SCM, CI, máy tính để bàn, v.v. Xem các câu trả lời khác. – h3xStream

+1

@ h3xStream hoàn toàn chính xác. Bài đăng này rất cũ, tha thứ cho tôi. – rook

+0

Tôi sẽ yêu cầu chỉnh sửa .. và sau đó thấy rằng bạn đã làm. +1 – h3xStream

2

Đọc mật khẩu từ tệp thuộc tính hoặc LDAP hoặc quyền truy cập tương tự và an toàn vào tài khoản được sử dụng để chạy phần mềm (mà không có nhà phát triển nào có quyền truy cập).

+0

Để cụ thể: Không sử dụng thuộc tính Hệ thống vì tùy chọn -D sẽ hiển thị với bất kỳ ai có thể liệt kê các quy trình đang hoạt động trên máy. –

+0

whats ngăn chặn các nhà phát triển từ viết một backdoor? Trong trường hợp này, lỗ hổng tiêm sql cố ý. – rook

+0

@rook Mã có thể được kiểm toán bởi các nhà phát triển và kiểm toán viên an ninh. Vấn đề không chỉ là các nhà phát triển có ác ý mà là một nhà phát triển mất chìa khóa USB hoặc bị máy tính của mình bị xâm phạm. – h3xStream

2

Sử dụng các tệp đơn giản để lưu trữ thuộc tính cơ sở dữ liệu và đọc chúng trong mã thay vì mã hóa cứng. Điều này không chỉ sạch sẽ mà còn có thể hạn chế quyền truy cập tệp.

Điều này link có thể giúp bạn.

+0

Nếu mã hóa của bạn, bạn sẽ đặt khóa ở đâu? – rook

+0

@rook: Bạn không thể. Không có cách nào để lưu mật khẩu "lưu" trong một tập tin nếu bạn cần truyền nó trong văn bản rõ ràng đến phía máy chủ VÀ không muốn người dùng nhập một cụm từ mật khẩu hoặc một cái gì đó. Bạn chỉ có thể làm xáo trộn nó. Nếu máy chủ chấp nhận mật khẩu băm, bạn chỉ có thể lưu trữ băm. –

0

Bạn có thể lưu mật khẩu trong tệp cấu hình và sau đó mã hóa tệp/phần của tệp bằng DPAPI nếu bạn đang sử dụng hộp Windows. Bằng cách này, bạn cũng sẽ không phải lo lắng về việc quản lý khóa.

1

Mã này tạo cơ sở dữ liệu kết nối bằng mật khẩu không đổi, được mã hóa cứng. .

Sự cố bảo mật phát sinh do bạn đã sử dụng tên, tên người dùng và mật khẩu DB. Nhưng chắc chắn bạn không thể giải quyết vấn đề "Bất kỳ ai có quyền truy cập vào mã nguồn hoặc mã được biên dịch đều có thể dễ dàng tìm hiểu mật khẩu". Tôi đặt cược U có thể giải quyết vấn đề đầu tiên.

Bạn có thể sử dụng Thuộc tính để bao gồm tên và mật khẩu DB mà bạn có thể mã hóa vào đối tượng Thuộc tính bằng cách sử dụng phương pháp setproperty().

Bây giờ bạn có thể bao gồm các đối tượng sở hữu vào phương pháp getConnection():

conn = DriverManager(url, properyObject); 
Các vấn đề liên quan