ref: master
vendor/plugins/xss_terminate/lib/xss_terminate.rb
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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
module XssTerminate def self.sanitize_by_default=(value) @@sanitize_by_default = value end def self.included(base) base.extend(ClassMethods) # sets up default of stripping tags for all fields # FIXME read value from environment.rb @@sanitize_by_default = false base.send(:xss_terminate) if @@sanitize_by_default end module ClassMethods def xss_terminate(options = {}) options[:with] ||= 'full' filter_with = 'sanitize_fields_with_' + options[:with] # :on is util when before_filter dont work for model case options[:on] when 'create' before_create filter_with when 'validation' before_validation filter_with else before_save filter_with end class_attribute "xss_terminate_#{options[:with]}_options".to_sym self.send("xss_terminate_#{options[:with]}_options=".to_sym, { :except => (options[:except] || []), :if => (options[:if] || true), :only => (options[:only] || options[:sanitize] || []) }) if include XssTerminate::InstanceMethods end end module InstanceMethods def sanitize_field(sanitizer, field, serialized = false) field = field.to_sym if serialized puts field self[field].each_key { |key| key = key.to_sym self[field][key] = sanitizer.sanitize(self[field][key], encode_special_chars: false, scrubber: permit_scrubber ) } else if self[field] self[field] = sanitizer.sanitize(self[field], encode_special_chars: false, scrubber: permit_scrubber ) else value = self.send("#{field}") return unless value value = sanitizer.sanitize(value, encode_special_chars: false, scrubber: permit_scrubber) self.send("#{field}=", value) end end end def permit_scrubber scrubber = Rails::Html::PermitScrubber.new scrubber.tags = Rails.application.config.action_view.sanitized_allowed_tags scrubber.attributes = Rails.application.config.action_view.sanitized_allowed_attributes scrubber end def sanitize_columns(with = :full) columns_serialized = self.class.serialized_attributes.keys only = eval "xss_terminate_#{with}_options[:only]" except = eval "xss_terminate_#{with}_options[:except]" unless except.empty? only.delete_if{ |i| except.include?( i.to_sym ) } end if_condition = eval "xss_terminate_#{with}_options[:if]" only = [] if !if_condition.nil? && if_condition.respond_to?(:call) && !if_condition.call(self) return only, columns_serialized end def sanitize_fields_with_full sanitize_fields_with(Rails::Html::FullSanitizer.new,:full) end def sanitize_fields_with_white_list sanitize_fields_with(Rails::Html::WhiteListSanitizer.new,:white_list) end def sanitize_fields_with_html5lib sanitize_fields_with(HTML5libSanitize.new,:html5lib) end def sanitize_fields_with sanitizer, type columns, columns_serialized = sanitize_columns(type) columns.each {|column| sanitize_field(sanitizer, column.to_sym, columns_serialized.include?(column))} end end end |