Created
August 25, 2015 12:38
-
-
Save stefanoc/1a8a3c2eb45cccd22247 to your computer and use it in GitHub Desktop.
XSS sanitizer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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