Đó là chủ đề khá cũ nhưng vẫn được cập nhật và đáng ngạc nhiên là mang lại tác động cao hơn hiện nay. Như Jon đã đề cập, đó có thể chỉ là một sai lầm mà các nhà thiết kế của Java đã mắc phải ngay từ đầu. Nhưng tôi sẽ không tưởng tượng trước khi nó có thể ảnh hưởng đến an ninh.
Nhiều lập trình viên biết Apache Velocity, công cụ mẫu linh hoạt và mạnh mẽ. Nó mạnh đến mức cho phép cung cấp mẫu với một tập hợp các đối tượng được đặt tên - được coi là đối tượng từ ngôn ngữ lập trình (Java ban đầu). Các đối tượng đó có thể được truy cập từ bên trong khuôn mẫu giống như trong ngôn ngữ lập trình, ví dụ: cá thể Chuỗi của Java có thể được sử dụng với tất cả các trường, thuộc tính và phương thức chung của nó
$input.isEmpty()
trong đó đầu vào là một Chuỗi , chạy trực tiếp qua JVM và trả về true hoặc false cho đầu ra của trình phân tích cú pháp Velocity). Càng xa càng tốt.
Nhưng trong Java, tất cả các đối tượng đều kế thừa từ Object nên người dùng cuối của chúng tôi cũng có thể đưa nó vào mẫu
$input.getClass()
để lấy một thể hiện của Lớp chuỗi .
Và với tham chiếu này, họ cũng có thể gọi một phương thức tĩnh forName (String) trên
$input.getClass().forName("java.io.FileDescriptor")
sử dụng bất kỳ tên lớp nào và sử dụng nó cho bất kỳ tài khoản nào của máy chủ web có thể làm (deface, đánh cắp nội dung DB, kiểm tra tệp cấu hình, ...)
Khai thác này bằng cách nào đó (trong ngữ cảnh cụ thể) được mô tả ở đây: https://github.com/veracode-research/solr-injection#7-cve-2019-17558-rce-via-velocity-template-by-_s00py
Sẽ không thể thực hiện được nếu việc gọi các phương thức tĩnh từ tham chiếu đến thể hiện của lớp bị cấm.
Tôi không nói rằng một khung lập trình cụ thể tốt hơn một khung lập trình khác nhưng tôi chỉ muốn so sánh. Có một cổng Apache Velocity cho .NET. Trong C #, không thể gọi các phương thức tĩnh chỉ từ tham chiếu của instance, điều làm cho việc khai thác như thế này trở nên vô dụng:
$input.GetType().GetType("System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
String hello = null; hello.valueOf(123);
works!