Skip to content

Instantly share code, notes, and snippets.

@stefanoc
Created August 25, 2015 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stefanoc/1a8a3c2eb45cccd22247 to your computer and use it in GitHub Desktop.
Save stefanoc/1a8a3c2eb45cccd22247 to your computer and use it in GitHub Desktop.
XSS sanitizer
module XssSanitizer
extend ActiveSupport::Concern
class Scrubber < Loofah::Scrubber
ALLOWED_TAGS = %w(
strong span em b u i a
h1 h2 h3
div p ul ol li blockquote br
)
ALLOWED_ATTRIBUTES = %w(href target)
def initialize
@direction = :top_down
end
def scrub(node)
case node.type
when Nokogiri::XML::Node::ELEMENT_NODE
if ALLOWED_TAGS.include?(node.name)
node.attributes.each do |attr|
node.remove_attribute(attr.first) unless ALLOWED_ATTRIBUTES.include?(attr.first)
# Sanitize href
end
return CONTINUE
end
when Nokogiri::XML::Node::TEXT_NODE, Nokogiri::XML::Node::CDATA_SECTION_NODE
return CONTINUE
end
node.before(node.children)
node.remove
return STOP
end
end
included do
def self.sanitize_html_content(*args)
# we keep a backup of the original input
args.each do |field|
self.field "unsafe_#{field}", type: String
end
before_save :sanitize_html_content
define_method('sanitize_html_content') do
args.each do |field|
unsafe_field = send(field)
send("unsafe_#{field}=", unsafe_field) if send("#{field}_changed?")
sanitized_field = ActionController::Base.helpers.sanitize(unsafe_field, scrubber: Scrubber.new)
send("#{field}=", sanitized_field)
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment