Rèn nhật ký JVM

1. Khái quát chung

Trong bài viết nhanh này, chúng ta sẽ khám phá một trong những vấn đề bảo mật phổ biến nhất trong thế giới JVM - Log Forging. Chúng tôi cũng sẽ hiển thị một kỹ thuật ví dụ có thể bảo vệ chúng tôi khỏi mối lo ngại về bảo mật này.

2. Log Forging là gì?

Theo OWASP , giả mạo nhật ký là một trong những kỹ thuật tấn công phổ biến nhất.

Lỗ hổng giả mạo nhật ký xảy ra khi dữ liệu xâm nhập vào ứng dụng từ một nguồn không đáng tin cậy hoặc dữ liệu được ghi vào tệp nhật ký ứng dụng / hệ thống bởi một thực thể bên ngoài.

Theo hướng dẫn của OWASP, giả mạo hoặc chèn nhật ký là một kỹ thuật ghi đầu vào của người dùng chưa được xác thực vào các tệp nhật ký để nó có thể cho phép kẻ tấn công giả mạo các mục nhật ký hoặc đưa nội dung độc hại vào nhật ký.

Nói một cách đơn giản, bằng cách giả mạo nhật ký, kẻ tấn công cố gắng thêm / sửa đổi nội dung bản ghi bằng cách khám phá các lỗ hổng bảo mật trong ứng dụng.

3. Ví dụ

Hãy xem xét một ví dụ trong đó người dùng gửi yêu cầu thanh toán từ web. Từ cấp độ ứng dụng, khi yêu cầu này được xử lý, một mục nhập sẽ được ghi lại với số tiền:

private final Logger logger = LoggerFactory.getLogger(LogForgingDemo.class); public void addLog( String amount ) { logger.info( "Amount credited = {}" , amount ); } public static void main( String[] args ) { LogForgingDemo demo = new LogForgingDemo(); demo.addLog( "300" ); }

Nếu chúng ta nhìn vào bảng điều khiển, chúng ta sẽ thấy một cái gì đó như thế này:

web - 2017-04-12 17:45:29,978 [main] INFO com.baeldung.logforging.LogForgingDemo - Amount credited = 300

Bây giờ, giả sử kẻ tấn công cung cấp thông tin đầu vào là “\ n \ nweb - 2017-04-12 17: 47: 08,957 [main] INFO Số tiền được hoàn nguyên thành công”, thì nhật ký sẽ là:

web - 2017-04-12 17:52:14,124 [main] INFO com.baeldung.logforging. LogForgingDemo - Amount credited = 300 web - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully

Cố ý, kẻ tấn công đã có thể tạo một mục nhập giả mạo trong nhật ký ứng dụng, điều này làm hỏng giá trị của nhật ký và gây nhầm lẫn cho bất kỳ hoạt động loại kiểm toán nào trong tương lai. Đây là bản chất của việc rèn khúc gỗ.

4. Phòng ngừa

Giải pháp rõ ràng nhất là không ghi bất kỳ đầu vào nào của người dùng vào các tệp nhật ký.

Tuy nhiên, điều đó có thể không thực hiện được trong mọi trường hợp vì dữ liệu người dùng cung cấp là cần thiết để gỡ lỗi hoặc kiểm tra hoạt động ứng dụng trong tương lai.

Chúng tôi phải sử dụng một số thay thế khác để giải quyết loại kịch bản này.

4.1. Giới thiệu xác thực

Một trong những giải pháp đơn giản nhất là luôn xác thực đầu vào trước khi ghi nhật ký. Một vấn đề với cách tiếp cận này là chúng ta sẽ phải xác thực rất nhiều dữ liệu trong thời gian chạy, điều này sẽ ảnh hưởng đến hiệu suất tổng thể của hệ thống.

Ngoài ra, nếu việc xác nhận không thành công, dữ liệu sẽ không được ghi lại và bị mất vĩnh viễn, đây thường không phải là một kịch bản chấp nhận được.

4.2. Ghi nhật ký cơ sở dữ liệu

Một tùy chọn khác là đăng nhập dữ liệu vào cơ sở dữ liệu. Cách đó an toàn hơn cách tiếp cận khác vì '\ n' hoặc dòng mới không có ý nghĩa gì đối với ngữ cảnh này. Tuy nhiên, điều này sẽ làm dấy lên một mối lo ngại khác về hiệu suất vì một số lượng lớn các kết nối cơ sở dữ liệu sẽ được sử dụng để ghi dữ liệu người dùng.

Hơn nữa, kỹ thuật này giới thiệu một lỗ hổng bảo mật khác - đó là SQL Injection . Để giải quyết vấn đề này, chúng ta có thể phải viết nhiều dòng mã bổ sung.

4.3. ESAPI

Sử dụng ESAPI là kỹ thuật được chia sẻ và khuyến khích nhất theo ngữ cảnh này. Ở đây, mỗi và mọi dữ liệu người dùng được mã hóa trước khi ghi vào nhật ký. ESAPI là một API mã nguồn mở có sẵn từ OWASP :

 org.owasp.esapi esapi 2.1.0.1 

Nó có sẵn trong Kho lưu trữ Maven Trung tâm.

We can encode the data using ESAPI‘s Encoder interface:

public String encode(String message) { message = message.replace( '\n' , '_' ).replace( '\r' , '_' ) .replace( '\t' , '_' ); message = ESAPI.encoder().encodeForHTML( message ); return message; }

Here, we have created one wrapper method which replaces all carriage returns and line feeds with underscores and encodes the modified message.

In the earlier example if we encode the message using this wrapper function the log should look something like this:

web - 2017-04-12 18:15:58,528 [main] INFO com.baeldung.logforging. LogForgingDemo - Amount credited = 300 __web - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully

Here, the corrupted string fragment is encoded and can be easily identified.

Once important point to note is that to use ESAPI we need to include ESAPI.properties file in the classpath else the ESAPI API will throw an exception at runtime. It's available here.

5. Conclusion

In this quick tutorial, we learned about log forging and techniques to overcome this security concern.

Giống như mọi khi, mã nguồn đầy đủ có sẵn trên GitHub.