Tấn công chéo trang trong ứng dụng rất phổ biến và làm cho ứng dụng phản hồi sai lệch nếu không được xử lý. Việc ngăn chặn XSS trong một ứng dụng là cần thiết từ góc độ bảo mật. Và đúng vậy, ai lại muốn bị tấn công bởi các yêu cầu và cửa sổ bật lên gây khó chịu ?! Một số cuộc tấn công XSS phổ biến cần được xử lý như sau
1 2 3 4 | <svg/onload=alert(1)> <svg.onload=confirm(document.cookie) y> {{constructor.constructor('alert(1)')()}} |
Tất cả các cuộc tấn công XSS ở trên khi hiển thị alert cảnh báo hoặc popup xác nhận tự động nhấp chọn yes và chạy tập lệnh trước khi bạn thậm chí biết điều đó.
Và điều này thực sự làm mọi thứ trở nên khó chịu!
Vậy, làm thế nào để ngăn chặn các cuộc tấn công XSS này trong ứng dụng?
Trong Rails, việc này trở nên khá dễ dàng.
Điều đầu tiên và quan trọng nhất chúng ta phải làm là sanitize các tham số. Và để làm như vậy, chúng ta cần module sanitizer để làm việc này với các loại tham số khác nhau.
Bạn có thể thấy module chỉ để sanitize bất kỳ loại tham số nào – đối tượng, mảng hoặc tệp. Bạn có thể sử dụng chúng bằng một function đơn giản và chuyển tất cả các tham số ActionController và sanitize chúng.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | frozen_string_literal: true module RailsSanitizer class << self def steralize(data) @sanitizer = Rails::Html::FullSanitizer.new sanitize_now(data) end def steralize_text(text) Loofah.fragment(text).text(encode_special_chars: false) end private def sanitize_hash(myHash) myHash.each do |key, value| if value.is_a?(Hash) sanitize_hash(value) else myHash[key] = if value.is_a?(Array) sanitize_array(value) else if value.is_a?(ActionDispatch::Http::UploadedFile) value else @sanitizer.sanitize(value.to_s) end end end end end def sanitize_array(myArray) myArray.each do |value| if value.is_a?(Array) sanitize_array(value) else if value.is_a?(Hash) sanitize_hash(value) else @sanitizer.sanitize(value.to_s) end end end end def sanitize_now(data) data_class = data.class if data_class == Integer @sanitizer.sanitize(data.to_s).to_i elsif data.is_a?(Hash) sanitize_hash(data) elsif data.is_a?(Array) sanitize_array(data) elsif data.is_a?(ActionDispatch::Http::UploadedFile) data else begin @sanitizer.sanitize(data.to_s) rescue StandardError data end end end end end Usage: sanitize_parameters(params) def sanitize_parameters(parameters) sanitized_parameters = parameters.to_h.each_with_object({}) do |(key, value), sanitize_parameters| sanitize_parameters[key] = RailsSanitizer.steralize(value) end end Usage: sanitize_text("Rails <> Sanitizer & Steralizer") Output: "Rails &lt;&gt; Sanitizer &amp; Steralizer" def sanitize_text(text) RailsSanitizer.steralize(text.to_s.html_safe) end Usage: sanitize_text("Rails <> Sanitizer & Steralizer") Output: "Rails <> Sanitizer & Steralizer" def steralize_text(text) RailsSanitizer.steralize_text(text.to_s.html_safe) end |
Module này có thể sanitize các tham số, nhưng có một số trường hợp chúng ta muốn giữ lại &, <,> như trong tên múi giờ. Đối với điều đó, thật không may, chúng ta phải lưu nó dưới dạng các tham số được phép và lưu chúng sau khi sanitize các tham số. Để hiển thị văn bản đã được sanitize, bạn có thể sử dụng sanitize_text cho những văn bản mà bạn không phải hiển thị <> và & nếu không, bạn có thể sử dụng steracy_text để hiển thị chúng trong dạng xem. Vì vậy, bây giờ bạn có thể sanitize cả tham số và chế độ xem trong Rails bằng một module hỗ trợ sanitize tham số đơn giản.