What is Server-side Template Injection?

Template engine được thiết kế để tạo các trang web bằng cách kết hợp các template cố định với dữ liệu động. Các cuộc tấn công server-side template injection có thể xảy ra khi input của người dùng được nối trực tiếp vào một template, thay vì được truyền vào dưới dạng dữ liệu. Điều này cho phép kẻ tấn công chèn các chỉ thị template tùy ý để thao túng template engine, thường cho phép họ kiểm soát hoàn toàn server.

What is the Impact of Server-side Template Injection?

Ở mức độ nghiêm trọng, kẻ tấn công có thể thực thi mã từ xa, kiểm soát hoàn toàn back-end server và sử dụng nó để thực hiện các cuộc tấn công khác vào cơ sở hạ tầng nội bộ.

How Do Server-side Template Injection Vulnerabilities Arise?

Các template tĩnh chỉ cung cấp các placeholder để render nội dung động thường không có lỗ hổng server-side template injection. Ví dụ:

$output = $twig->render("Dear {first_name},", array("first_name" => $user.first_name) );

Trường hợp này không có lỗ hổng server-side template injection vì first name của người dùng chỉ được truyền vào template dưới dạng dữ liệu.

Tuy nhiên, vì các template chỉ là các chuỗi, các nhà phát triển web đôi khi nối trực tiếp input của người dùng vào template trước khi render:

$output = $twig->render("Dear " . $_GET['name']);

Ở một khía cạnh nào đó, điều này tương tự như các lỗ hổng SQL Injection xảy ra trong các prepared statements được viết kém.

Constructing a Server-side Template Injection Attack

Detect

Cách tiếp cận ban đầu đơn giản nhất là thử fuzzing template bằng cách chèn một chuỗi các ký tự đặc biệt thường được sử dụng trong các biểu thức template, chẳng hạn như ${{<%[%'"}}%\.

Lỗ hổng server-side template injection xảy ra trong hai bối cảnh riêng biệt, mỗi bối cảnh đòi hỏi phương pháp phát hiện riêng:

  • Plaintext context
  • Code context

Bất kể kết quả fuzzing của chúng ta là gì, điều quan trọng là phải thử các cách tiếp cận cụ thể theo từng bối cảnh sau đây.

Trong plaintext context, kẻ tấn công có thể kiểm tra SSTI bằng cách chèn các phép toán như ${7*7} vào các trường input. Nếu output được đánh giá ở phía server (ví dụ: hiển thị Hello 49), điều đó cho thấy có lỗ hổng.

Trong code context, SSTI xảy ra khi các biến do người dùng kiểm soát được chèn trực tiếp vào các biểu thức template:

greeting = getQueryParameter('greeting')
engine.render("Hello {{"+greeting+"}}", data

Để kiểm tra, trước tiên hãy xác minh rằng tham số không có lỗ hổng XSS bằng cách chèn HTML:

http://vulnerable-website.com/?greeting=data.username<tag>

Nếu không có XSS, điều này thường sẽ dẫn đến một mục trống trong output (chỉ Hello không có username), các thẻ được mã hóa hoặc một thông báo lỗi. Bước tiếp theo là thoát khỏi template bằng cách sử dụng cú pháp phổ biến để chèn HTML tùy ý:

http://vulnerable-website.com/?greeting=data.username}}<tag>

Nếu điều này lại dẫn đến lỗi hoặc output trống, chúng ta đã sử dụng cú pháp từ sai ngôn ngữ template hoặc, nếu không có cú pháp kiểu template nào có vẻ hợp lệ, thì không thể thực hiện server-side template injection.

Note

Các template engine khác nhau yêu cầu cú pháp cụ thể cho các bài kiểm tra như vậy.

Identify

Khi chúng ta đã phát hiện ra khả năng bị template injection, bước tiếp theo là xác định template engine.

Chỉ cần gửi cú pháp không hợp lệ thường là đủ vì thông báo lỗi kết quả sẽ cho chúng ta biết chính xác template engine là gì và đôi khi ngay cả phiên bản nào. Nếu không, chúng ta sẽ cần phải kiểm tra thủ công các payload dành riêng cho từng ngôn ngữ và nghiên cứu cách chúng được diễn giải bởi template engine.

Exploiting Server-Side Template Injection Vulnerabilities

How to Prevent Server-side Template Injection Vulnerabilities

Để ngăn chặn server-side template injection (SSTI), hãy tránh cho phép người dùng sửa đổi hoặc gửi template bất cứ khi nào có thể. Nếu cần thiết, hãy sử dụng một template engine “logic-less” như Mustache để tách biệt logic khỏi phần trình bày và giảm thiểu rủi ro.

Để tăng cường an toàn, hãy thực thi mã của người dùng trong một môi trường sandboxed với quyền truy cập bị hạn chế vào các hàm nguy hiểm. Vì sandboxing có thể bị bypass, hãy xem xét việc triển khai template engine trong một môi trường an toàn, bị cô lập, chẳng hạn như một container Docker đã được khóa chặt.

Resources