Commit db65013977f059e29757ed115180fa43d43a5d67
1 parent
31b28c41
Exists in
master
and in
20 other branches
rails4: use new rails sanitizer (loofah)
Showing
6 changed files
with
55 additions
and
18 deletions
Show diff stats
app/models/tiny_mce_article.rb
| ... | ... | @@ -9,7 +9,7 @@ class TinyMceArticle < TextArticle |
| 9 | 9 | def self.description |
| 10 | 10 | _('Not accessible for visually impaired users.') |
| 11 | 11 | end |
| 12 | - | |
| 12 | + | |
| 13 | 13 | xss_terminate :only => [ ] |
| 14 | 14 | |
| 15 | 15 | xss_terminate :only => [ :name, :abstract, :body ], :with => 'white_list', :on => 'validation' | ... | ... |
config/application.rb
| ... | ... | @@ -15,12 +15,6 @@ module Noosfero |
| 15 | 15 | |
| 16 | 16 | require 'noosfero/plugin' |
| 17 | 17 | |
| 18 | - # Adds custom attributes to the Set of allowed html attributes for the #sanitize helper | |
| 19 | - config.action_view.sanitized_allowed_attributes = 'align', 'border', 'alt', 'vspace', 'hspace', 'width', 'heigth', 'value', 'type', 'data', 'style', 'target', 'codebase', 'archive', 'classid', 'code', 'flashvars', 'scrolling', 'frameborder', 'controls', 'autoplay', 'colspan', 'rowspan' | |
| 20 | - | |
| 21 | - # Adds custom tags to the Set of allowed html tags for the #sanitize helper | |
| 22 | - config.action_view.sanitized_allowed_tags = 'object', 'embed', 'param', 'table', 'tr', 'th', 'td', 'applet', 'comment', 'iframe', 'audio', 'video', 'source' | |
| 23 | - | |
| 24 | 18 | config.action_controller.include_all_helpers = false |
| 25 | 19 | |
| 26 | 20 | # Settings in config/environments/* take precedence over those specified here. | ... | ... |
| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | +require 'loofah/helpers' | |
| 2 | + | |
| 3 | +ActionView::Base.full_sanitizer = Loofah::Helpers::ActionView::FullSanitizer.new | |
| 4 | +ActionView::Base.white_list_sanitizer = Loofah::Helpers::ActionView::WhiteListSanitizer.new | |
| 5 | + | |
| 6 | +Loofah::HTML5::WhiteList::ALLOWED_ELEMENTS_WITH_LIBXML2.merge %w[ | |
| 7 | + img object embed param table tr th td applet comment iframe audio video source | |
| 8 | +] | |
| 9 | + | |
| 10 | +Loofah::HTML5::WhiteList::ALLOWED_ATTRIBUTES.merge %w[ | |
| 11 | + align border alt vspace hspace width heigth value type data | |
| 12 | + style target codebase archive classid code flashvars scrolling frameborder controls autoplay colspan | |
| 13 | +] | |
| 14 | + | |
| 15 | +# do not escape COMMENT_NODE | |
| 16 | +require 'loofah/scrubber' | |
| 17 | +module Loofah | |
| 18 | + class Scrubber | |
| 19 | + private | |
| 20 | + | |
| 21 | + def html5lib_sanitize node | |
| 22 | + case node.type | |
| 23 | + when Nokogiri::XML::Node::ELEMENT_NODE | |
| 24 | + if HTML5::Scrub.allowed_element? node.name | |
| 25 | + HTML5::Scrub.scrub_attributes node | |
| 26 | + return Scrubber::CONTINUE | |
| 27 | + end | |
| 28 | + when Nokogiri::XML::Node::TEXT_NODE, Nokogiri::XML::Node::CDATA_SECTION_NODE,Nokogiri::XML::Node::COMMENT_NODE | |
| 29 | + return Scrubber::CONTINUE | |
| 30 | + end | |
| 31 | + Scrubber::STOP | |
| 32 | + end | |
| 33 | + | |
| 34 | + end | |
| 35 | +end | ... | ... |
test/test_helper.rb
| ... | ... | @@ -135,16 +135,23 @@ class ActiveSupport::TestCase |
| 135 | 135 | assert !text.index('<'), "Text '#{text}' expected to be sanitized" |
| 136 | 136 | end |
| 137 | 137 | |
| 138 | + def find_tag_in_string text, options | |
| 139 | + doc = Nokogiri::HTML.fragment text | |
| 140 | + tag = doc.css(options[:tag]).first | |
| 141 | + attributes = {}; tag.attributes.each do |a, v| | |
| 142 | + a = a.to_sym | |
| 143 | + next unless options[:attributes].has_key? a | |
| 144 | + attributes[a] = v.value | |
| 145 | + end | |
| 146 | + tag if (tag and attributes == options[:attributes]) | |
| 147 | + end | |
| 148 | + | |
| 138 | 149 | def assert_tag_in_string(text, options) |
| 139 | - doc = HTML::Document.new(text, false, false) | |
| 140 | - tag = doc.find(options) | |
| 141 | - assert tag, "expected tag #{options.inspect}, but not found in #{text.inspect}" | |
| 150 | + assert find_tag_in_string(text, options), "expected tag #{options.inspect}, but not found in #{text.inspect}" | |
| 142 | 151 | end |
| 143 | 152 | |
| 144 | 153 | def assert_no_tag_in_string(text, options) |
| 145 | - doc = HTML::Document.new(text, false, false) | |
| 146 | - tag = doc.find(options) | |
| 147 | - assert !tag, "expected no tag #{options.inspect}, but tag found in #{text.inspect}" | |
| 154 | + assert !find_tag_in_string(text, options), "expected no tag #{options.inspect}, but tag found in #{text.inspect}" | |
| 148 | 155 | end |
| 149 | 156 | |
| 150 | 157 | def assert_order(reference, original) | ... | ... |
test/unit/article_test.rb
| ... | ... | @@ -935,7 +935,7 @@ class ArticleTest < ActiveSupport::TestCase |
| 935 | 935 | article.name = "<h1 Malformed >> html >< tag" |
| 936 | 936 | article.valid? |
| 937 | 937 | |
| 938 | - assert_no_match /[<>]/, article.name | |
| 938 | + assert_equal '<h1>> html ></h1>', article.name | |
| 939 | 939 | end |
| 940 | 940 | |
| 941 | 941 | should 'return truncated title in short_title' do |
| ... | ... | @@ -1734,6 +1734,7 @@ class ArticleTest < ActiveSupport::TestCase |
| 1734 | 1734 | |
| 1735 | 1735 | should 'store first image in tracked action' do |
| 1736 | 1736 | a = create TinyMceArticle, :name => 'Tracked Article', :body => '<p>Foo<img src="foo.png" />Bar</p>', :profile_id => profile.id |
| 1737 | + assert_equal 'foo.png', a.first_image | |
| 1737 | 1738 | assert_equal 'foo.png', ActionTracker::Record.last.get_first_image |
| 1738 | 1739 | end |
| 1739 | 1740 | ... | ... |
test/unit/tiny_mce_article_test.rb
| ... | ... | @@ -82,16 +82,16 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
| 82 | 82 | assert_no_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://untrusted_site.com/videos.ogg"} |
| 83 | 83 | end |
| 84 | 84 | |
| 85 | - should 'remove iframe if it has 2 or more src' do | |
| 85 | + should 'consider first src if there is 2 or more src' do | |
| 86 | 86 | assert_includes Environment.default.trusted_sites_for_iframe, 'itheora.org' |
| 87 | 87 | |
| 88 | 88 | article = create(TinyMceArticle, :profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://itheora.org/videos.ogg' src='http://untrusted_site.com/videos.ogg'></iframe>") |
| 89 | - assert_equal '', article.body | |
| 89 | + assert_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://itheora.org/videos.ogg"} | |
| 90 | 90 | end |
| 91 | 91 | |
| 92 | 92 | should 'not sanitize html comments' do |
| 93 | 93 | article = TinyMceArticle.new |
| 94 | - article.body = '<p><!-- <asdf> << aasdfa >>> --> <h1> Wellformed html code </h1>' | |
| 94 | + article.body = '<!-- <asdf> << aasdfa >>> --> <h1> Wellformed html code </h1>' | |
| 95 | 95 | article.valid? |
| 96 | 96 | |
| 97 | 97 | assert_match /<!-- .* --> <h1> Wellformed html code <\/h1>/, article.body |
| ... | ... | @@ -232,7 +232,7 @@ end |
| 232 | 232 | :profile => profile |
| 233 | 233 | ) |
| 234 | 234 | assert_tag_in_string article.body, :tag => 'table', |
| 235 | - :attributes => { :colspan => 2, :rowspan => 3 } | |
| 235 | + :attributes => { :colspan => '2', :rowspan => '3' } | |
| 236 | 236 | end |
| 237 | 237 | |
| 238 | 238 | end | ... | ... |