Bài viết này trình bày một số vấn đề về bảo mật trong giao thức HTTP, được nêu ra trong hai tài liệu RFC 7230 và RFC 7231. Các ví dụ trong bài viết về các lỗi cụ thể được tham khảo từ OWASP.
- Rủi ro từ các yếu tố trung gian
HTTP cho phép sử dụng các yếu tố trung gian để đáp ứng các request thông qua một chuỗi các kết nối. Có 3 yếu tố trung gian phổ biến, đó là proxy, gateway và tunnel.
Một request hay response sẽ phải đi qua điểm A, B và C này. Chúng có thể truy cập vào các thông tin nhạy cảm được truyền đi, chẳng hạn thông tin cá nhân của người dùng hay tổ chức. Việc các yếu tố trung gian không được chú trọng đến vấn đề bảo mật và tính riêng tư có thể dẫn đến một loạt các cuộc tấn công tiềm năng.
Các nhà triển khai, xây dựng hệ thống nên xem xét các yếu tố riêng tư và bảo mật, trong quá trình thiết kế, code và triển khai hệ thống.
Người dùng cần ý thức được những mối nguy hiểm từ việc sử dụng các proxy hay gateway không tin cậy.
- Response Splitting
Response splitting (a.k.a CRLF injection) là một kỹ thuật khai thác web phổ biến. Kẻ tấn công gửi đi dữ liệu được encode, nằm trong một vài tham số của request, dữ liệu này sau đó được decode và lặp lại trong một trường nào đó của response header.
Nếu dữ liệu này là một ký hiệu thể hiện sự kết thúc của response, và một response tiếp theo được bắt đầu, response ban đầu sẽ bị chia tách thành hai và nội dung của response thứ hai sẽ bị điều khiển bởi kẻ tấn công. Kẻ tấn công sau đó có thể tạo một request khác trong cùng một kết nối liên tục, và lừa người nhận (bao gồm cả các yếu tố trung gian) tin rằng response thứ hai này là để trả lời cho request thứ hai.
- Request Smuggling
Request smuggling là kỹ thuật khai thác sự khác nhau trong việc xử lý các request của các loại server khác nhau để giấu đi những request được gắn thêm vào request ban đầu tưởng như vô hại.
Chúng ta cùng xem xét ví dụ sau đây:
Giả sử một POST request chứa hai trường “Content-length” trong header với hai giá trị khác nhau. Một số server sẽ từ chối request này (IIS và Apache), nhưng những server khác lại không. Chẳng hạn, SunONE W/S 6.1 sử dụng trường Content-length đầu tiên, trong khi sunONE Proxy 3.6 lại lấy trường Content-length thứ hai.
Giả sử SITE là DNS của một SunONE W/S, đặt phía sau một SunONE Proxy, có một file poison.html nằm trên SunONE W/S. Đây là cách khai thác HTTP Request Suggling dựa trên sự không nhất quán trong cách xử lý giữa hai server:
[Chú ý rằng mỗi dòng đều kết thúc với một CRLF (“”), ngoại trừ dòng 10]Hãy xem xét chuyện gì sẽ xảy ra khi request được gửi đến W/S thông qua Proxy server. Đầu tiên, proxy sẽ phân tích request từ dòng 1 đến dòng 7 (màu xanh) và gặp phải 2 trường Content-Length. Như đã nói ở trên, nó sẽ bỏ qua trường đầu tiên và hiểu là request body có độ dài 44 byte. Do đó, nó xử lý dữ liệu từ dòng 8 đến dòng 10 như request body đầu tiên (từ dòng 8 đến 10, dữ liệu có độ dài chính xác 44 byte). Proxy sau đó sẽ phân tích tích tiếp từ dòng 11 đến 14 (màu đỏ) như là request thứ hai của client.
Bây giờ, hãy xem W/S diễn giải như thế nào với dữ liệu ở trên, khi nó được chuyển tiếp đến từ proxy. Không như proxy, W/S sẽ sử dụng trường Content-Length đầu tiên và hiểu như sau: request đầu tiên không có body, và request thứ hai bắt đầu từ dòng thứ 8 (lưu ý rằng W/S sẽ phân tích từ dòng 11 trở đi như là giá trị của trường Bla).
Tiếp theo, hãy xem response trả về client như thế nào. Request mà W/S hiểu là “POST /foobar.html” (từ dòng 1) và “GET /poison.html” (từ dòng 8), vì thế nó sẽ gửi về cho client 2 response với nội dung của trang foobar.html và poison.html. Còn proxy lại hiểu 2 response này ứng với 2 request là “POST /foobar.html” (từ dòng 1) và “GET /page_to_poison.html” (dòng 11). Proxy sẽ lưu cache nội dung của trang poison.html tương ứng với URL “page_to_poison.html” (cache poisoning). Từ đó, khi nào client request đến “page_to_poison.html” sẽ nhận được nội dung của trang poison.html.
- Tấn công dựa vào đường dẫn file
Các web server thường xuyên sử dụng hệ thống file cục bộ của chúng để quản lý việc ánh xạ tên file trong URI đến tài nguyên thật trên server. Hầu hết các file hệ thống không được thiết kế để chống lại các đường dẫn file độc hại. Do đó, server cần tránh truy cập vào các file quan trọng của hệ thống.
Ví dụ, UNIX, Microsoft Windows, và một vài hệ điều hành khác sử dụng “..” như là một thành phần đường dẫn để biểu diễn thư mục cấp bên trên so với file/thư mục hiện tại. Nếu không kiểm soát đầu vào và phân quyền hợp lý, các file/thư mục nhạy cảm của hệ thống đều có thể bị truy cập bằng cách nhập vào các đường dẫn trỏ đến các file/thư mục này.
- Các kiểu tấn công Command Injection, Code Injection, Query Injection
Ví dụ, SQL Injection là một kiểu tấn công phổ biến, trong đó web server nhận các tham số trong URI là một phần của câu truy vấn SQL. Do đó, kẻ tấn công có thể lừa web server để thực hiện các câu truy vấn SQL bất hợp pháp, nhằm đánh cắp hoặc phá hoại cơ sở dữ liệu.
Nhìn chung, không nên sử dụng trực tiếp dữ liệu do người dùng gửi lên để thực hiện các thao tác trên server. Những dữ liệu này cần phải đi qua các bộ lọc, trong đó định nghĩa như thế nào là hợp lệ, như thế nào là bất hợp lệ, từ đó loại bỏ đi các dữ liệu không mong muốn.
- Lộ thông tin cá nhân
Client thường chứa nhiều thông tin cá nhân, bao gồm cả những thông tin do người dùng cung cấp để tương tác với server (chẳng hạn username, password, nơi ở, địa chỉ email,…) và các thông tin về hoạt động duyệt web của người dùng (lịch sử, dấu trang,…). Khi triển khai, cần chú ý ngăn chặn các điểm có thể để lộ những thông tin riêng tư này.
- Lộ thông tin nhạy cảm trong URI
URI, theo thiết kế, là để chia sẻ với mọi người dùng, không được đảm bảo an toàn. URI thường được hiển thị trong mã nguồn của website, và được lưu trong danh sách bookmark mà không có các cơ chế bảo vệ. Do đó, sẽ là không an toàn nếu trong URI có chứa các thông tin nhạy cảm, thông tin cá nhân,…
Nên tránh việc sử dụng phương thức GET để gửi các thông tin cá nhân lên server, vì chúng sẽ được hiển thị trong URI. Thay vào đó, hãy sử dụng phương thức POST.
- Lộ thông tin phần mềm sử dụng
Các trường User-Agent, Via, Server trong header thường cho biết thông tin về các phần mềm mà bên gửi sử dụng. Theo lý thuyết, điều đó cho phép kẻ tấn công có thể dễ dàng hơn trong việc khai thác các lỗ hổng đã biết của các phần mềm này.