Commit af86ac8d1f15b627c0c9ec68928332916e0a54fd
Exists in
staging
and in
1 other branch
merging with master
Showing
16 changed files
with
151 additions
and
127 deletions
Show diff stats
.travis.yml
... | ... | @@ -5,15 +5,19 @@ notifications: |
5 | 5 | template: |
6 | 6 | - "%{repository_slug} %{branch} %{commit} %{commit_subject} - %{result} %{build_url}" |
7 | 7 | |
8 | -# trusty constainers take more time to start | |
9 | -#dist: trusty | |
8 | +# Ensure Container-based environment, as others can have some random failures | |
9 | +# specially with different Firefox versions and selenium tests. | |
10 | +# E.g. https://travis-ci.org/noosfero/noosfero/jobs/122918772#L1308 | |
11 | +# | |
12 | +# Also container-based environments have the fatest boot times and | |
13 | +# are the only one with cache available for public projects. | |
14 | +# See https://docs.travis-ci.com/user/ci-environment/#Virtualization-environments | |
15 | +sudo: false | |
16 | +cache: bundler | |
10 | 17 | |
11 | 18 | language: ruby |
12 | 19 | rvm: |
13 | - - 2.2 | |
14 | - # ruby 2.3 works but isn't stable on travis | |
15 | - | |
16 | -cache: bundler | |
20 | + - 2.3.0 | |
17 | 21 | |
18 | 22 | addons: |
19 | 23 | apt: | ... | ... |
app/controllers/my_profile/tasks_controller.rb
... | ... | @@ -18,16 +18,16 @@ class TasksController < MyProfileController |
18 | 18 | @task_types = Task.pending_types_for(profile) |
19 | 19 | @task_tags = [OpenStruct.new(:name => _('All'), :id => nil) ] + Task.all_tags |
20 | 20 | |
21 | - @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc') | |
21 | + @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) | |
22 | 22 | @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present? |
23 | 23 | @tasks = @tasks.tagged_with(@filter_tags, any: true) if @filter_tags.present? |
24 | 24 | @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page]) |
25 | - | |
26 | 25 | @failed = params ? params[:failed] : {} |
27 | 26 | |
28 | 27 | @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task') && !r.has_permission?('view_tasks')}) if profile.organization? |
29 | 28 | |
30 | 29 | @view_only = !current_person.has_permission?(:perform_task, profile) |
30 | + | |
31 | 31 | end |
32 | 32 | |
33 | 33 | def processed | ... | ... |
app/helpers/comment_helper.rb
... | ... | @@ -66,7 +66,7 @@ module CommentHelper |
66 | 66 | |
67 | 67 | def link_for_edit(comment) |
68 | 68 | if comment.can_be_updated_by?(user) |
69 | - {:link => expirable_comment_link(comment, :edit, _('Edit'), url_for(:profile => profile.identifier, :controller => :comment, :action => :edit, :id => comment.id),:class => 'modal')} | |
69 | + {:link => expirable_comment_link(comment, :edit, _('Edit'), url_for(:profile => profile.identifier, :controller => :comment, :action => :edit, :id => comment.id), :modal => true)} | |
70 | 70 | end |
71 | 71 | end |
72 | 72 | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +module SanitizeHelper | |
2 | + | |
3 | + def sanitize_html(text, type= :full_sanitize) | |
4 | + sanitizer(type).sanitize(text, scrubber: permit_scrubber) | |
5 | + end | |
6 | + | |
7 | + def sanitize_link(text) | |
8 | + sanitizer(:white_list).sanitize(text, scrubber:permit_scrubber) | |
9 | + end | |
10 | + | |
11 | +protected | |
12 | + | |
13 | + def permit_scrubber | |
14 | + scrubber = Rails::Html::PermitScrubber.new | |
15 | + scrubber.tags = Rails.application.config.action_view.sanitized_allowed_tags | |
16 | + scrubber.attributes = Rails.application.config.action_view.sanitized_allowed_attributes | |
17 | + scrubber | |
18 | + end | |
19 | + | |
20 | + def sanitizer type = :full_sanitize | |
21 | + return HTML::WhiteListSanitizer.new if type == :white_list | |
22 | + HTML::FullSanitizer.new | |
23 | + end | |
24 | + | |
25 | +end | ... | ... |
app/models/article.rb
1 | 1 | |
2 | 2 | class Article < ActiveRecord::Base |
3 | 3 | |
4 | + include SanitizeHelper | |
5 | + | |
4 | 6 | attr_accessible :name, :body, :abstract, :profile, :tag_list, :parent, |
5 | 7 | :allow_members_to_edit, :translation_of_id, :language, |
6 | 8 | :license_id, :parent_id, :display_posts_in_current_language, |
... | ... | @@ -54,6 +56,7 @@ class Article < ActiveRecord::Base |
54 | 56 | track_actions :create_article, :after_create, :keep_params => [:name, :url, :lead, :first_image], :if => Proc.new { |a| a.is_trackable? && !a.image? } |
55 | 57 | |
56 | 58 | # xss_terminate plugin can't sanitize array fields |
59 | + # sanitize_tag_list is used with SanitizeHelper | |
57 | 60 | before_save :sanitize_tag_list |
58 | 61 | |
59 | 62 | before_create do |article| |
... | ... | @@ -875,11 +878,6 @@ class Article < ActiveRecord::Base |
875 | 878 | tag_name.gsub(/[<>]/, '') |
876 | 879 | end |
877 | 880 | |
878 | - def sanitize_html(text) | |
879 | - sanitizer = HTML::FullSanitizer.new | |
880 | - sanitizer.sanitize(text) | |
881 | - end | |
882 | - | |
883 | 881 | def parent_archived? |
884 | 882 | if self.parent_id_changed? && self.parent && self.parent.archived? |
885 | 883 | errors.add(:parent_folder, N_('is archived!!')) | ... | ... |
app/models/link_list_block.rb
1 | 1 | class LinkListBlock < Block |
2 | 2 | |
3 | + include SanitizeHelper | |
4 | + | |
3 | 5 | attr_accessible :links |
4 | 6 | |
5 | 7 | ICONS = [ |
... | ... | @@ -85,9 +87,4 @@ class LinkListBlock < Block |
85 | 87 | end |
86 | 88 | end |
87 | 89 | |
88 | - def sanitize_link(text) | |
89 | - sanitizer = HTML::WhiteListSanitizer.new | |
90 | - sanitizer.sanitize(text) | |
91 | - end | |
92 | - | |
93 | 90 | end | ... | ... |
app/models/scrap.rb
1 | 1 | class Scrap < ActiveRecord::Base |
2 | 2 | |
3 | + include SanitizeHelper | |
4 | + | |
3 | 5 | attr_accessible :content, :sender_id, :receiver_id, :scrap_id |
4 | 6 | |
5 | 7 | SEARCHABLE_FIELDS = { |
... | ... | @@ -41,8 +43,7 @@ class Scrap < ActiveRecord::Base |
41 | 43 | end |
42 | 44 | |
43 | 45 | def strip_all_html_tags |
44 | - sanitizer = HTML::WhiteListSanitizer.new | |
45 | - self.content = sanitizer.sanitize(self.content, :tags => []) | |
46 | + self.content = sanitize_html(self.content) | |
46 | 47 | end |
47 | 48 | |
48 | 49 | def action_tracker_target | ... | ... |
app/models/task.rb
... | ... | @@ -347,6 +347,7 @@ class Task < ActiveRecord::Base |
347 | 347 | where [environment_condition, profile_condition].compact.join(' OR ') |
348 | 348 | } |
349 | 349 | |
350 | + | |
350 | 351 | def self.pending_types_for(profile) |
351 | 352 | Task.to(profile).pending.select('distinct type').map { |t| [t.class.name, t.title] } |
352 | 353 | end | ... | ... |
app/models/textile_article.rb
1 | 1 | class TextileArticle < TextArticle |
2 | + include SanitizeHelper | |
2 | 3 | |
3 | 4 | def self.short_description |
4 | 5 | _('Text article with Textile markup language') |
... | ... | @@ -31,10 +32,9 @@ class TextileArticle < TextArticle |
31 | 32 | protected |
32 | 33 | |
33 | 34 | def convert_to_html(textile) |
34 | - @@sanitizer ||= HTML::WhiteListSanitizer.new | |
35 | 35 | converter = RedCloth.new(textile|| '') |
36 | 36 | converter.hard_breaks = false |
37 | - @@sanitizer.sanitize(converter.to_html) | |
37 | + sanitize_html(converter.to_html, :white_list) | |
38 | 38 | end |
39 | 39 | |
40 | 40 | end | ... | ... |
app/views/tasks/index.html.erb
... | ... | @@ -21,18 +21,18 @@ |
21 | 21 | </div> |
22 | 22 | <% end %> |
23 | 23 | |
24 | -<%= form_tag '#', :method => 'get' do %> | |
25 | - <%= field_set_tag _('Filter'), :class => 'filter_fields' do %> | |
26 | - <p> | |
27 | - <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %> | |
28 | - </p> | |
29 | - <p> | |
30 | - <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text',:value => @filter_text}) %> | |
31 | - </p> | |
32 | - <% if profile.organization? %> | |
33 | - <p> | |
34 | - <%= labelled_select(_('Assigned to')+': ', :filter_responsible, :id, :name, @filter_responsible, [OpenStruct.new(:name => _('All'), :id => nil), OpenStruct.new(:name => _('Unassigned'), :id => -1)] + @responsible_candidates, :class => 'filter_responsible') %> | |
35 | - </p> | |
24 | +<%= form_tag '#', :method => 'post' do %> | |
25 | + | |
26 | + <%= field_set_tag _('Filter'), :class => 'filter_fields' do %> | |
27 | + <p> | |
28 | + <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %> | |
29 | + </p> | |
30 | + <p> | |
31 | + <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text-autocomplete',:value => @filter_text}) %> | |
32 | + </p> | |
33 | + <p> | |
34 | + <%= submit_button(:search, _('Search')) %> | |
35 | + </p> | |
36 | 36 | <% end %> |
37 | 37 | <p> |
38 | 38 | <%= labelled_select(_('Tags')+': ', :filter_tags, :id, :name, @filter_tags, @task_tags, {:id => 'filter-add-tag'}) %> |
... | ... | @@ -44,7 +44,6 @@ |
44 | 44 | </p> |
45 | 45 | <% end %> |
46 | 46 | <% end %> |
47 | - | |
48 | 47 | <% if @tasks.empty? %> |
49 | 48 | <p> |
50 | 49 | <em><%= _('No pending tasks for %s') % profile.name %></em> |
... | ... | @@ -64,7 +63,7 @@ |
64 | 63 | <p> |
65 | 64 | <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %> |
66 | 65 | </p> |
67 | - <% end %> | |
66 | + <% end %> | |
68 | 67 | |
69 | 68 | <div class="task_boxes"> |
70 | 69 | <% @tasks.each do |task| %> |
... | ... | @@ -73,11 +72,11 @@ |
73 | 72 | </div> |
74 | 73 | |
75 | 74 | <% unless @view_only %> |
76 | - <p> | |
77 | - <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %> | |
78 | - </p> | |
75 | + <p> | |
76 | + <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %> | |
77 | + </p> | |
79 | 78 | <% end %> |
80 | - </ul> | |
79 | + </ul> | |
81 | 80 | |
82 | 81 | <script> |
83 | 82 | jQuery('.tag-list').inputosaurus({ | ... | ... |
config/application.rb
... | ... | @@ -15,6 +15,21 @@ module Noosfero |
15 | 15 | |
16 | 16 | require 'noosfero/plugin' |
17 | 17 | |
18 | + # The plugin xss_terminator(located in vendor/plugins/xss_terminator) and the helper | |
19 | + # SanitizeHelper(located in app/helpers/sanitize_helper.rb) use | |
20 | + # ALLOWED_TAGS and ALLOWED_ATTRIBUTES to make a sanitize with html. | |
21 | + | |
22 | + ALLOWED_TAGS = %w(object embed param table tr th td applet comment iframe audio video source | |
23 | + strong em b i p code pre tt samp kbd var sub sup dfn cite big small address hr br div span h1 | |
24 | + h2 h3 h4 h5 h6 ul ol li dl dt dd abbr acronym a img blockquote del ins a) | |
25 | + | |
26 | + ALLOWED_ATTRIBUTES = %w(name href cite class title src xml:lang height datetime alt abbr width | |
27 | + vspace hspace heigth value type data style target codebase archive data-macro align border | |
28 | + classid code flashvars scrolling frameborder controls autoplay colspan id rowspan) | |
29 | + | |
30 | + config.action_view.sanitized_allowed_tags = ALLOWED_TAGS | |
31 | + config.action_view.sanitized_allowed_attributes = ALLOWED_ATTRIBUTES | |
32 | + | |
18 | 33 | require 'noosfero/multi_tenancy' |
19 | 34 | config.middleware.use Noosfero::MultiTenancy::Middleware |
20 | 35 | ... | ... |
config/initializers/sanitizer.rb
... | ... | @@ -1,14 +0,0 @@ |
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 | - |
lib/sanitize_params.rb
... | ... | @@ -2,40 +2,40 @@ module SanitizeParams |
2 | 2 | |
3 | 3 | protected |
4 | 4 | |
5 | - # Check each request parameter for | |
6 | - # improper HTML or Script tags | |
7 | - def sanitize_params | |
8 | - sanitize_params_hash(request.params) | |
9 | - end | |
5 | + # Check each request parameter for | |
6 | + # improper HTML or Script tags | |
7 | + def sanitize_params | |
8 | + sanitize_params_hash(params) | |
9 | + end | |
10 | 10 | |
11 | - # Given a params list sanitize all | |
12 | - def sanitize_params_hash(params) | |
13 | - params.each { |k, v| | |
14 | - if v.is_a?(String) | |
15 | - params[k] = sanitize_param v | |
16 | - elsif v.is_a?(Array) | |
17 | - params[k] = sanitize_array v | |
18 | - elsif v.kind_of?(Hash) | |
19 | - params[k] = sanitize_params_hash(v) | |
20 | - end | |
21 | - } | |
22 | - end | |
11 | + # Given a params list sanitize all | |
12 | + def sanitize_params_hash(params) | |
13 | + params.each { |k, v| | |
14 | + if v.is_a?(String) | |
15 | + params[k] = sanitize_param v | |
16 | + elsif v.is_a?(Array) | |
17 | + params[k] = sanitize_array v | |
18 | + elsif v.kind_of?(Hash) | |
19 | + params[k] = sanitize_params_hash(v) | |
20 | + end | |
21 | + } | |
22 | + end | |
23 | 23 | |
24 | - # If the parameter was an array, | |
25 | - # try to sanitize each element in the array | |
26 | - def sanitize_array(array) | |
27 | - array.map! { |e| | |
28 | - if e.is_a?(String) | |
29 | - sanitize_param e | |
30 | - end | |
31 | - } | |
32 | - return array | |
33 | - end | |
24 | + # If the parameter was an array, | |
25 | + # try to sanitize each element in the array | |
26 | + def sanitize_array(array) | |
27 | + array.map! { |e| | |
28 | + if e.is_a?(String) | |
29 | + sanitize_param e | |
30 | + end | |
31 | + } | |
32 | + return array | |
33 | + end | |
34 | 34 | |
35 | - # Santitize a single value | |
36 | - def sanitize_param(value) | |
37 | - allowed_tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) | |
38 | - ActionController::Base.helpers.sanitize(value, tags: allowed_tags, attributes: %w(href title)) | |
39 | - end | |
35 | + # Santitize a single value | |
36 | + def sanitize_param(value) | |
37 | + allowed_tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) | |
38 | + ActionController::Base.helpers.sanitize(value, tags: allowed_tags, attributes: %w(href title)) | |
39 | + end | |
40 | 40 | |
41 | -end | |
41 | +end | ... | ... |
test/functional/search_controller_test.rb
... | ... | @@ -788,15 +788,18 @@ class SearchControllerTest < ActionController::TestCase |
788 | 788 | injection = '<iMg SrC=x OnErRoR=document.documentElement.innerHTML=1>SearchParam' |
789 | 789 | get :tag, :tag => injection |
790 | 790 | tag = assigns(:tag) |
791 | - assert !tag.upcase.include?('IMG') && tag.include?('SearchParam') | |
791 | + assert !tag.upcase.include?('IMG') | |
792 | + assert tag.include?('SearchParam') | |
792 | 793 | end |
793 | 794 | |
794 | - should 'not allow query injection array' do | |
795 | - injection = ['<iMg SrC=x OnErRoR=document.documentElement.innerHTML=1>', '<script>document.innerHTML = \'x\'</script>'] | |
795 | + should 'not allow query injection in array' do | |
796 | + injection = ['<iMg SrC=x OnErRoR=document.documentElement.innerHTML=1>', | |
797 | + '<script>document.innerHTML = \'x\'</script>'] | |
796 | 798 | get :tag, :tag => injection |
797 | 799 | tag = assigns(:tag) |
798 | - tag.each { |t| | |
799 | - assert !t.upcase.include?('IMG') && !t.upcase.include?('SCRIPT') | |
800 | + tag.each { |t| | |
801 | + assert !t.upcase.include?('IMG') | |
802 | + assert !t.upcase.include?('SCRIPT') | |
800 | 803 | } |
801 | 804 | end |
802 | 805 | ... | ... |
test/functional/tasks_controller_test.rb
... | ... | @@ -4,6 +4,7 @@ require 'tasks_controller' |
4 | 4 | class TasksControllerTest < ActionController::TestCase |
5 | 5 | |
6 | 6 | self.default_params = {profile: 'testuser'} |
7 | + | |
7 | 8 | def setup |
8 | 9 | @controller = TasksController.new |
9 | 10 | @request = ActionController::TestRequest.new |
... | ... | @@ -28,12 +29,12 @@ class TasksControllerTest < ActionController::TestCase |
28 | 29 | end |
29 | 30 | |
30 | 31 | should 'get filtered tasks to autocomplete text field' do |
31 | - | |
32 | + | |
32 | 33 | #Create a admin user and a simple user |
33 | 34 | profile_admin = create_user('admin_tester').person |
34 | 35 | Environment.default.add_admin(profile_admin) |
35 | 36 | user = fast_create(Person,:name => 'FakeUser') |
36 | - | |
37 | + | |
37 | 38 | #Create a task of type 'ModerateUserRegistration' |
38 | 39 | task_data = { |
39 | 40 | :target => Environment.default, |
... | ... | @@ -41,20 +42,20 @@ class TasksControllerTest < ActionController::TestCase |
41 | 42 | :data => {:user_id => user.id,:name => user.name} |
42 | 43 | } |
43 | 44 | ModerateUserRegistration.create!(task_data) |
44 | - | |
45 | + | |
45 | 46 | #Use admin user to your profile with a pending task above |
46 | 47 | @controller.stubs(:profile).returns(profile_admin) |
47 | 48 | login_as profile_admin.identifier |
48 | - | |
49 | + | |
49 | 50 | #Perform a http request to 'search_task' action with params |
50 | 51 | post :search_tasks, :filter_type =>'ModerateUserRegistration', :filter_text => 'Fak' |
51 | - | |
52 | + | |
52 | 53 | assert_response :success |
53 | - | |
54 | + | |
54 | 55 | #Check if json response matches with a 'FakeUser' |
55 | 56 | json_response = ActiveSupport::JSON.decode(@response.body) |
56 | 57 | value = json_response[0]['value'] |
57 | - | |
58 | + | |
58 | 59 | assert_equal value, 'FakeUser' |
59 | 60 | end |
60 | 61 | |
... | ... | @@ -468,13 +469,13 @@ class TasksControllerTest < ActionController::TestCase |
468 | 469 | t2 = CleanHouse.create!(:requestor => requestor, :target => profile) |
469 | 470 | t3 = FeedDog.create!(:requestor => requestor, :target => profile) |
470 | 471 | |
471 | - get :index, :filter_type => t1.type, :filter_text => 'test' | |
472 | + post :index, :filter_type => t1.type, :filter_text => 'test' | |
472 | 473 | |
473 | 474 | assert_includes assigns(:tasks), t1 |
474 | 475 | assert_not_includes assigns(:tasks), t2 |
475 | 476 | assert_not_includes assigns(:tasks), t3 |
476 | 477 | |
477 | - get :index | |
478 | + post :index | |
478 | 479 | |
479 | 480 | assert_includes assigns(:tasks), t1 |
480 | 481 | assert_includes assigns(:tasks), t2 | ... | ... |
vendor/plugins/xss_terminate/lib/xss_terminate.rb
1 | 1 | module XssTerminate |
2 | - ALLOWED_CORE_ATTRIBUTES = %w(name href cite class title src xml:lang height datetime alt abbr width) | |
3 | - ALLOWED_CUSTOM_ATTRIBUTES = %w(data-macro) | |
4 | 2 | |
5 | 3 | def self.sanitize_by_default=(value) |
6 | 4 | @@sanitize_by_default = value |
... | ... | @@ -40,30 +38,33 @@ module XssTerminate |
40 | 38 | |
41 | 39 | module InstanceMethods |
42 | 40 | |
43 | - def sanitize_allowed_attributes | |
44 | - ALLOWED_CORE_ATTRIBUTES | ALLOWED_CUSTOM_ATTRIBUTES | |
45 | - end | |
46 | - | |
47 | 41 | def sanitize_field(sanitizer, field, serialized = false) |
48 | 42 | field = field.to_sym |
49 | 43 | if serialized |
50 | 44 | puts field |
51 | 45 | self[field].each_key { |key| |
52 | 46 | key = key.to_sym |
53 | - self[field][key] = sanitizer.sanitize(self[field][key], scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false, attributes: sanitize_allowed_attributes) | |
47 | + self[field][key] = sanitizer.sanitize(self[field][key], encode_special_chars: false, scrubber: permit_scrubber ) | |
54 | 48 | } |
55 | 49 | else |
56 | 50 | if self[field] |
57 | - self[field] = sanitizer.sanitize(self[field], scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false, attributes: sanitize_allowed_attributes) | |
51 | + self[field] = sanitizer.sanitize(self[field], encode_special_chars: false, scrubber: permit_scrubber ) | |
58 | 52 | else |
59 | 53 | value = self.send("#{field}") |
60 | 54 | return unless value |
61 | - value = sanitizer.sanitize(value, scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false, attributes: sanitize_allowed_attributes) | |
55 | + value = sanitizer.sanitize(value, encode_special_chars: false, scrubber: permit_scrubber) | |
62 | 56 | self.send("#{field}=", value) |
63 | 57 | end |
64 | 58 | end |
65 | 59 | end |
66 | 60 | |
61 | + def permit_scrubber | |
62 | + scrubber = Rails::Html::PermitScrubber.new | |
63 | + scrubber.tags = Rails.application.config.action_view.sanitized_allowed_tags | |
64 | + scrubber.attributes = Rails.application.config.action_view.sanitized_allowed_attributes | |
65 | + scrubber | |
66 | + end | |
67 | + | |
67 | 68 | def sanitize_columns(with = :full) |
68 | 69 | columns_serialized = self.class.serialized_attributes.keys |
69 | 70 | only = eval "xss_terminate_#{with}_options[:only]" |
... | ... | @@ -75,27 +76,20 @@ module XssTerminate |
75 | 76 | end |
76 | 77 | |
77 | 78 | def sanitize_fields_with_full |
78 | - sanitizer = Rails::Html::FullSanitizer.new | |
79 | - columns, columns_serialized = sanitize_columns(:full) | |
80 | - columns.each do |column| | |
81 | - sanitize_field(sanitizer, column.to_sym, columns_serialized.include?(column)) | |
82 | - end | |
79 | + sanitize_fields_with(Rails::Html::FullSanitizer.new,:full) | |
83 | 80 | end |
84 | 81 | |
85 | 82 | def sanitize_fields_with_white_list |
86 | - sanitizer = Rails::Html::WhiteListSanitizer.new | |
87 | - columns, columns_serialized = sanitize_columns(:white_list) | |
88 | - columns.each do |column| | |
89 | - sanitize_field(sanitizer, column.to_sym, columns_serialized.include?(column)) | |
90 | - end | |
91 | - end | |
83 | + sanitize_fields_with(Rails::Html::WhiteListSanitizer.new,:white_list) | |
84 | + end | |
92 | 85 | |
93 | 86 | def sanitize_fields_with_html5lib |
94 | - sanitizer = HTML5libSanitize.new | |
95 | - columns = sanitize_columns(:html5lib) | |
96 | - columns.each do |column| | |
97 | - sanitize_field(sanitizer, column.to_sym, columns_serialized.include?(column)) | |
98 | - end | |
87 | + sanitize_fields_with(HTML5libSanitize.new,:html5lib) | |
88 | + end | |
89 | + | |
90 | + def sanitize_fields_with sanitizer, type | |
91 | + columns, columns_serialized = sanitize_columns(type) | |
92 | + columns.each {|column| sanitize_field(sanitizer, column.to_sym, columns_serialized.include?(column))} | |
99 | 93 | end |
100 | 94 | |
101 | 95 | end | ... | ... |