Commit 3fe538f12e2bbe1eb4e77dc91abd93bfc9963da5
Committed by
Antonio Terceiro
1 parent
347fbb41
Exists in
staging
and in
42 other branches
Allowed environment to set trusted sites on iframes
Added setting trusted_sites_for_iframes to environment WhiteListFilter lib to filter iframes from fields Removed "on hand" iframe filter from plugins (ActionItem1631)
Showing
13 changed files
with
163 additions
and
23 deletions
Show diff stats
app/models/environment.rb
@@ -219,6 +219,8 @@ class Environment < ActiveRecord::Base | @@ -219,6 +219,8 @@ class Environment < ActiveRecord::Base | ||
219 | settings_items :currency_separator, :type => String, :default => '.' | 219 | settings_items :currency_separator, :type => String, :default => '.' |
220 | settings_items :currency_delimiter, :type => String, :default => ',' | 220 | settings_items :currency_delimiter, :type => String, :default => ',' |
221 | 221 | ||
222 | + settings_items :trusted_sites_for_iframe, :type => Array, :default => ['itheora.org', 'tv.softwarelivre.org', 'stream.softwarelivre.org'] | ||
223 | + | ||
222 | def news_amount_by_folder=(amount) | 224 | def news_amount_by_folder=(amount) |
223 | settings[:news_amount_by_folder] = amount.to_i | 225 | settings[:news_amount_by_folder] = amount.to_i |
224 | end | 226 | end |
@@ -468,6 +470,9 @@ class Environment < ActiveRecord::Base | @@ -468,6 +470,9 @@ class Environment < ActiveRecord::Base | ||
468 | 470 | ||
469 | xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' | 471 | xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' |
470 | 472 | ||
473 | + include WhiteListFilter | ||
474 | + filter_iframes :message_for_disabled_enterprise, :whitelist => lambda { trusted_sites_for_iframe } | ||
475 | + | ||
471 | 476 | ||
472 | # ################################################# | 477 | # ################################################# |
473 | # Business logic in general | 478 | # Business logic in general |
app/models/event.rb
@@ -26,6 +26,9 @@ class Event < Article | @@ -26,6 +26,9 @@ class Event < Article | ||
26 | {:conditions => ['start_date = :date AND end_date IS NULL OR (start_date <= :date AND end_date >= :date)', {:date => date}]} | 26 | {:conditions => ['start_date = :date AND end_date IS NULL OR (start_date <= :date AND end_date >= :date)', {:date => date}]} |
27 | } | 27 | } |
28 | 28 | ||
29 | + include WhiteListFilter | ||
30 | + filter_iframes :description, :link, :address, :whitelist => lambda { profile && profile.environment && profile.environment.trusted_sites_for_iframe } | ||
31 | + | ||
29 | def self.description | 32 | def self.description |
30 | _('A calendar event') | 33 | _('A calendar event') |
31 | end | 34 | end |
app/models/folder.rb
@@ -6,6 +6,9 @@ class Folder < Article | @@ -6,6 +6,9 @@ class Folder < Article | ||
6 | 6 | ||
7 | xss_terminate :only => [ :body ], :with => 'white_list', :on => 'validation' | 7 | xss_terminate :only => [ :body ], :with => 'white_list', :on => 'validation' |
8 | 8 | ||
9 | + include WhiteListFilter | ||
10 | + filter_iframes :body, :whitelist => lambda { profile && profile.environment && profile.environment.trusted_sites_for_iframe } | ||
11 | + | ||
9 | def self.select_views | 12 | def self.select_views |
10 | [[_('Folder'), 'folder'], [_('Image gallery'), 'image_gallery']] | 13 | [[_('Folder'), 'folder'], [_('Image gallery'), 'image_gallery']] |
11 | end | 14 | end |
app/models/product.rb
@@ -42,6 +42,9 @@ class Product < ActiveRecord::Base | @@ -42,6 +42,9 @@ class Product < ActiveRecord::Base | ||
42 | 42 | ||
43 | acts_as_mappable | 43 | acts_as_mappable |
44 | 44 | ||
45 | + include WhiteListFilter | ||
46 | + filter_iframes :description, :whitelist => lambda { enterprise && enterprise.environment && enterprise.environment.trusted_sites_for_iframe } | ||
47 | + | ||
45 | def self.units | 48 | def self.units |
46 | { | 49 | { |
47 | _('Litre') => 'litre', | 50 | _('Litre') => 'litre', |
app/models/profile.rb
@@ -314,6 +314,10 @@ class Profile < ActiveRecord::Base | @@ -314,6 +314,10 @@ class Profile < ActiveRecord::Base | ||
314 | xss_terminate :only => [ :name, :nickname, :address, :contact_phone, :description ], :on => 'validation' | 314 | xss_terminate :only => [ :name, :nickname, :address, :contact_phone, :description ], :on => 'validation' |
315 | xss_terminate :only => [ :custom_footer, :custom_header ], :with => 'white_list', :on => 'validation' | 315 | xss_terminate :only => [ :custom_footer, :custom_header ], :with => 'white_list', :on => 'validation' |
316 | 316 | ||
317 | + include WhiteListFilter | ||
318 | + filter_iframes :custom_header, :custom_footer, :whitelist => lambda { environment && environment.trusted_sites_for_iframe } | ||
319 | + | ||
320 | + | ||
317 | # returns the contact email for this profile. | 321 | # returns the contact email for this profile. |
318 | # | 322 | # |
319 | # Subclasses may -- and should -- override this method. | 323 | # Subclasses may -- and should -- override this method. |
app/models/tiny_mce_article.rb
@@ -9,6 +9,10 @@ class TinyMceArticle < TextArticle | @@ -9,6 +9,10 @@ class TinyMceArticle < TextArticle | ||
9 | end | 9 | end |
10 | 10 | ||
11 | xss_terminate :except => [ :abstract, :body ] | 11 | xss_terminate :except => [ :abstract, :body ] |
12 | + | ||
12 | xss_terminate :only => [ :abstract, :body ], :with => 'white_list', :on => 'validation' | 13 | xss_terminate :only => [ :abstract, :body ], :with => 'white_list', :on => 'validation' |
13 | 14 | ||
15 | + include WhiteListFilter | ||
16 | + filter_iframes :abstract, :body, :whitelist => lambda { profile && profile.environment && profile.environment.trusted_sites_for_iframe } | ||
17 | + | ||
14 | end | 18 | end |
@@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
1 | +module WhiteListFilter | ||
2 | + | ||
3 | + def check_iframe_on_content(content, trusted_sites) | ||
4 | + if content.blank? || !content.include?('iframe') | ||
5 | + return content | ||
6 | + end | ||
7 | + content.gsub!(/<iframe[^>]*>\s*<\/iframe>/i) do |iframe| | ||
8 | + result = '' | ||
9 | + unless iframe =~ /src=['"].*src=['"]/ | ||
10 | + trusted_sites.each do |trusted_site| | ||
11 | + re_dom = trusted_site.gsub('.', '\.') | ||
12 | + if iframe =~ /src=["']https?:\/\/(www\.)?#{re_dom}\// | ||
13 | + result = iframe | ||
14 | + end | ||
15 | + end | ||
16 | + end | ||
17 | + result | ||
18 | + end | ||
19 | + content | ||
20 | + end | ||
21 | + | ||
22 | + module ClassMethods | ||
23 | + def filter_iframes(*opts) | ||
24 | + options = opts.pop | ||
25 | + white_list_method = options[:whitelist] | ||
26 | + opts.each do |field| | ||
27 | + before_validation do |obj| | ||
28 | + obj.check_iframe_on_content(obj.send(field), obj.instance_eval(&white_list_method)) | ||
29 | + end | ||
30 | + end | ||
31 | + end | ||
32 | + end | ||
33 | + | ||
34 | + def self.included(c) | ||
35 | + c.send(:extend, WhiteListFilter::ClassMethods) | ||
36 | + end | ||
37 | +end |
public/stylesheets/application.css
@@ -1444,7 +1444,6 @@ input.disabled { | @@ -1444,7 +1444,6 @@ input.disabled { | ||
1444 | ***********************************************************/ | 1444 | ***********************************************************/ |
1445 | 1445 | ||
1446 | .block iframe { | 1446 | .block iframe { |
1447 | - width: 100%; | ||
1448 | border: none; | 1447 | border: none; |
1449 | } | 1448 | } |
1450 | 1449 |
test/unit/environment_test.rb
@@ -1074,4 +1074,15 @@ class EnvironmentTest < Test::Unit::TestCase | @@ -1074,4 +1074,15 @@ class EnvironmentTest < Test::Unit::TestCase | ||
1074 | assert_equal 15, env.profile_cache_in_minutes | 1074 | assert_equal 15, env.profile_cache_in_minutes |
1075 | end | 1075 | end |
1076 | 1076 | ||
1077 | + should 'have a list of trusted sites by default' do | ||
1078 | + assert_equal ['itheora.org', 'tv.softwarelivre.org', 'stream.softwarelivre.org'], Environment.new.trusted_sites_for_iframe | ||
1079 | + end | ||
1080 | + | ||
1081 | + should 'have a list of trusted sites' do | ||
1082 | + e = Environment.default | ||
1083 | + e.trusted_sites_for_iframe = ['trusted.site.org'] | ||
1084 | + e.save! | ||
1085 | + | ||
1086 | + assert_equal ['trusted.site.org'], Environment.default.trusted_sites_for_iframe | ||
1087 | + end | ||
1077 | end | 1088 | end |
test/unit/event_test.rb
@@ -265,5 +265,4 @@ class EventTest < ActiveSupport::TestCase | @@ -265,5 +265,4 @@ class EventTest < ActiveSupport::TestCase | ||
265 | assert_match /<!-- .* --> <h1> Wellformed html code <\/h1>/, event.description | 265 | assert_match /<!-- .* --> <h1> Wellformed html code <\/h1>/, event.description |
266 | assert_match /<!-- .* --> <h1> Wellformed html code <\/h1>/, event.address | 266 | assert_match /<!-- .* --> <h1> Wellformed html code <\/h1>/, event.address |
267 | end | 267 | end |
268 | - | ||
269 | end | 268 | end |
test/unit/tiny_mce_article_test.rb
@@ -54,19 +54,49 @@ class TinyMceArticleTest < Test::Unit::TestCase | @@ -54,19 +54,49 @@ class TinyMceArticleTest < Test::Unit::TestCase | ||
54 | assert_equal "the <!–-[if IE]> just for ie... <![endif]-–>", article.body | 54 | assert_equal "the <!–-[if IE]> just for ie... <![endif]-–>", article.body |
55 | end | 55 | end |
56 | 56 | ||
57 | - should 'not mess with <iframe and </iframe if it is from itheora' do | ||
58 | - article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://itheora.org'></iframe>") | ||
59 | - assert_equal "<iframe src=\"http://itheora.org\"></iframe>", article.body | 57 | + should 'remove iframe if it is not from a trusted site' do |
58 | + article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://anything/videos.ogg'></iframe>") | ||
59 | + assert_equal "", article.body | ||
60 | end | 60 | end |
61 | 61 | ||
62 | - should 'remove iframe if it is not from itheora or softwarelivre' do | ||
63 | - article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='anything'></iframe>") | ||
64 | - assert_equal "", article.body | 62 | + should 'not mess with <iframe and </iframe if it is from itheora by default' do |
63 | + assert_includes Environment.default.trusted_sites_for_iframe, 'itheora.org' | ||
64 | + article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://itheora.org/demo/index.php?v=example.ogv'></iframe>") | ||
65 | + assert_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://itheora.org/demo/index.php?v=example.ogv"} | ||
65 | end | 66 | end |
66 | 67 | ||
67 | - should 'allow iframe if it is from stream.softwarelivre.org' do | ||
68 | - article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://stream.softwarelivre.org'></iframe>") | ||
69 | - assert_equal "<iframe src=\"http://stream.softwarelivre.org\"></iframe>", article.body | 68 | + should 'allow iframe if it is from stream.softwarelivre.org by default' do |
69 | + assert_includes Environment.default.trusted_sites_for_iframe, 'stream.softwarelivre.org' | ||
70 | + article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://stream.softwarelivre.org/fisl10/sites/default/files/videos.ogg'></iframe>") | ||
71 | + assert_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://stream.softwarelivre.org/fisl10/sites/default/files/videos.ogg"} | ||
72 | + end | ||
73 | + | ||
74 | + should 'allow iframe if it is from tv.softwarelivre.org by default' do | ||
75 | + assert_includes Environment.default.trusted_sites_for_iframe, 'tv.softwarelivre.org' | ||
76 | + article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe id='player-base' src='http://tv.softwarelivre.org/embed/1170' width='482' height='406' align='right' frameborder='0' scrolling='no'></iframe>") | ||
77 | + assert_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://tv.softwarelivre.org/embed/1170", :width => "482", :height => "406", :align => "right", :frameborder => "0", :scrolling => "no"} | ||
78 | + end | ||
79 | + | ||
80 | + should 'allow iframe if it is from a trusted site' do | ||
81 | + env = Environment.default | ||
82 | + env.trusted_sites_for_iframe = ['avideosite.com'] | ||
83 | + env.save | ||
84 | + assert_includes Environment.default.trusted_sites_for_iframe, 'avideosite.com' | ||
85 | + article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://avideosite.com/videos.ogg'></iframe>") | ||
86 | + assert_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://avideosite.com/videos.ogg"} | ||
87 | + end | ||
88 | + | ||
89 | + should 'remove only the iframe from untrusted site' do | ||
90 | + article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://stream.softwarelivre.org/videos.ogg'></iframe><iframe src='http://untrusted_site.com/videos.ogg'></iframe>") | ||
91 | + assert_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://stream.softwarelivre.org/videos.ogg"} | ||
92 | + assert_no_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://untrusted_site.com/videos.ogg"} | ||
93 | + end | ||
94 | + | ||
95 | + should 'remove iframe if it has 2 or more src' do | ||
96 | + assert_includes Environment.default.trusted_sites_for_iframe, 'itheora.org' | ||
97 | + | ||
98 | + article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://itheora.org/videos.ogg' src='http://untrusted_site.com/videos.ogg'></iframe>") | ||
99 | + assert_equal '', article.body | ||
70 | end | 100 | end |
71 | 101 | ||
72 | #TinymMCE convert config={"key":(.*)} in config={"key":(.*)} | 102 | #TinymMCE convert config={"key":(.*)} in config={"key":(.*)} |
@@ -83,9 +113,4 @@ class TinyMceArticleTest < Test::Unit::TestCase | @@ -83,9 +113,4 @@ class TinyMceArticleTest < Test::Unit::TestCase | ||
83 | assert_match /<!-- .* --> <h1> Wellformed html code <\/h1>/, article.body | 113 | assert_match /<!-- .* --> <h1> Wellformed html code <\/h1>/, article.body |
84 | end | 114 | end |
85 | 115 | ||
86 | - should 'allow iframe if it is from tv.softwarelivre.org' do | ||
87 | - article = TinyMceArticle.create!(:profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe id='player-base' src='http://tv.softwarelivre.org/embed/1170' width='482' height='406' align='right' frameborder='0' scrolling='no'></iframe>") | ||
88 | - assert_tag_in_string article.body, :tag => 'iframe', :attributes => { :src => "http://tv.softwarelivre.org/embed/1170", :width => "482", :height => "406", :align => "right", :frameborder => "0", :scrolling => "no"} | ||
89 | - end | ||
90 | - | ||
91 | end | 116 | end |
@@ -0,0 +1,54 @@ | @@ -0,0 +1,54 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class WhiteListFilterTest < Test::Unit::TestCase | ||
4 | + | ||
5 | + include WhiteListFilter | ||
6 | + | ||
7 | + def environment | ||
8 | + @environment ||= Environment.default | ||
9 | + end | ||
10 | + | ||
11 | + should 'remove iframe if it is not from a trusted site' do | ||
12 | + content = "<iframe src='http://anything/videos.ogg'></iframe>" | ||
13 | + assert_equal "", check_iframe_on_content(content, environment.trusted_sites_for_iframe) | ||
14 | + end | ||
15 | + | ||
16 | + should 'not mess with <iframe and </iframe if it is from itheora by default' do | ||
17 | + assert_includes Environment.default.trusted_sites_for_iframe, 'itheora.org' | ||
18 | + content = "<iframe src='http://itheora.org/demo/index.php?v=example.ogv'></iframe>" | ||
19 | + assert_equal "<iframe src='http://itheora.org/demo/index.php?v=example.ogv'></iframe>", check_iframe_on_content(content, environment.trusted_sites_for_iframe) | ||
20 | + end | ||
21 | + | ||
22 | + should 'allow iframe if it is from stream.softwarelivre.org by default' do | ||
23 | + assert_includes Environment.default.trusted_sites_for_iframe, 'stream.softwarelivre.org' | ||
24 | + content = "<iframe src='http://stream.softwarelivre.org/fisl10/sites/default/files/videos.ogg'></iframe>" | ||
25 | + assert_equal "<iframe src='http://stream.softwarelivre.org/fisl10/sites/default/files/videos.ogg'></iframe>", check_iframe_on_content(content, environment.trusted_sites_for_iframe) | ||
26 | + end | ||
27 | + | ||
28 | + should 'allow iframe if it is from tv.softwarelivre.org by default' do | ||
29 | + assert_includes Environment.default.trusted_sites_for_iframe, 'tv.softwarelivre.org' | ||
30 | + content = "<iframe id='player-base' src='http://tv.softwarelivre.org/embed/1170' width='482' height='406' align='right' frameborder='0' scrolling='no'></iframe>" | ||
31 | + assert_equal "<iframe id='player-base' src='http://tv.softwarelivre.org/embed/1170' width='482' height='406' align='right' frameborder='0' scrolling='no'></iframe>", check_iframe_on_content(content, environment.trusted_sites_for_iframe) | ||
32 | + end | ||
33 | + | ||
34 | + should 'allow iframe if it is from a trusted site' do | ||
35 | + env = Environment.default | ||
36 | + env.trusted_sites_for_iframe = ['avideosite.com'] | ||
37 | + env.save | ||
38 | + assert_includes Environment.default.trusted_sites_for_iframe, 'avideosite.com' | ||
39 | + content = "<iframe src='http://avideosite.com/videos.ogg'></iframe>" | ||
40 | + assert_equal "<iframe src='http://avideosite.com/videos.ogg'></iframe>", check_iframe_on_content(content, environment.trusted_sites_for_iframe) | ||
41 | + end | ||
42 | + | ||
43 | + should 'remove only the iframe from untrusted site' do | ||
44 | + content = "<iframe src='http://stream.softwarelivre.org/videos.ogg'></iframe><iframe src='http://untrusted_site.com/videos.ogg'></iframe>" | ||
45 | + assert_equal "<iframe src='http://stream.softwarelivre.org/videos.ogg'></iframe>", check_iframe_on_content(content, environment.trusted_sites_for_iframe) | ||
46 | + end | ||
47 | + | ||
48 | + should 'remove iframe if it has 2 or more src' do | ||
49 | + assert_includes Environment.default.trusted_sites_for_iframe, 'itheora.org' | ||
50 | + | ||
51 | + content = "<iframe src='http://itheora.org/videos.ogg' src='http://untrusted_site.com/videos.ogg'></iframe>" | ||
52 | + assert_equal '', check_iframe_on_content(content, environment.trusted_sites_for_iframe) | ||
53 | + end | ||
54 | +end |
vendor/plugins/white_list_sanitizer_unescape_before_reescape/init.rb
@@ -11,13 +11,6 @@ HTML::WhiteListSanitizer.module_eval do | @@ -11,13 +11,6 @@ HTML::WhiteListSanitizer.module_eval do | ||
11 | final_text = text.gsub(/<!/, '<!') | 11 | final_text = text.gsub(/<!/, '<!') |
12 | final_text = final_text.gsub(/<!--.*\[if IE\]-->(.*)<!--\[endif\]-->/, '<!–-[if IE]>\1<![endif]-–>') #FIX for itheora comments | 12 | final_text = final_text.gsub(/<!--.*\[if IE\]-->(.*)<!--\[endif\]-->/, '<!–-[if IE]>\1<![endif]-–>') #FIX for itheora comments |
13 | 13 | ||
14 | - if final_text =~ /iframe/ | ||
15 | - itheora_video = /<iframe(.*)src=(.*)itheora.org(.*)<\/iframe>/ | ||
16 | - sl_video = /<iframe(.*)src=\"http:\/\/(stream|tv).softwarelivre.org(.*)<\/iframe>/ | ||
17 | - unless (final_text =~ itheora_video || final_text =~ sl_video) | ||
18 | - final_text = final_text.gsub(/<iframe(.*)<\/iframe>/, '') | ||
19 | - end | ||
20 | - end | ||
21 | final_text = final_text.gsub(/&quot;/, '"') #FIX problems with archive.org | 14 | final_text = final_text.gsub(/&quot;/, '"') #FIX problems with archive.org |
22 | final_text | 15 | final_text |
23 | end | 16 | end |