Commit 08165b714366b8db3bb1f387efa1dadf01863c98

Authored by Francisco Júnior
Committed by Rodrigo Souto
1 parent f9687c15

Removing search controller vulnabilities

Signed-off-by: Lucas Kanashiro <kanashiro.duarte@gmail.com>
Signed-off-by: Macartur Sousa <macartur.sc@gmail.com>
app/controllers/public/search_controller.rb
@@ -3,7 +3,10 @@ class SearchController &lt; PublicController @@ -3,7 +3,10 @@ class SearchController &lt; PublicController
3 helper TagsHelper 3 helper TagsHelper
4 include SearchHelper 4 include SearchHelper
5 include ActionView::Helpers::NumberHelper 5 include ActionView::Helpers::NumberHelper
  6 + include SanitizeParams
6 7
  8 +
  9 + before_filter :sanitize_params
7 before_filter :redirect_asset_param, :except => [:assets, :suggestions] 10 before_filter :redirect_asset_param, :except => [:assets, :suggestions]
8 before_filter :load_category, :except => :suggestions 11 before_filter :load_category, :except => :suggestions
9 before_filter :load_search_assets, :except => :suggestions 12 before_filter :load_search_assets, :except => :suggestions
@@ -134,7 +137,8 @@ class SearchController &lt; PublicController @@ -134,7 +137,8 @@ class SearchController &lt; PublicController
134 137
135 def tag 138 def tag
136 @tag = params[:tag] 139 @tag = params[:tag]
137 - @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}" 140 + tag_str = @tag.kind_of?(Array) ? @tag.join(" ") : @tag.to_str
  141 + @tag_cache_key = "tag_#{CGI.escape(tag_str)}_env_#{environment.id.to_s}_page_#{params[:npage]}"
138 if is_cache_expired?(@tag_cache_key) 142 if is_cache_expired?(@tag_cache_key)
139 @searches[@asset] = {:results => environment.articles.tagged_with(@tag).paginate(paginate_options)} 143 @searches[@asset] = {:results => environment.articles.tagged_with(@tag).paginate(paginate_options)}
140 end 144 end
config/application.rb
@@ -15,6 +15,12 @@ module Noosfero @@ -15,6 +15,12 @@ module Noosfero
15 15
16 require 'noosfero/plugin' 16 require 'noosfero/plugin'
17 17
  18 + config.action_view.sanitized_allowed_tags |= %w(object embed param table
  19 + tr th td applet comment iframe audio video source)
  20 + config.action_view.sanitized_allowed_attributes |= %w(align border alt
  21 + vspace hspace width heigth value type data style target codebase archive
  22 + classid code flashvars scrolling frameborder controls autoplay colspan)
  23 +
18 require 'noosfero/multi_tenancy' 24 require 'noosfero/multi_tenancy'
19 config.middleware.use Noosfero::MultiTenancy::Middleware 25 config.middleware.use Noosfero::MultiTenancy::Middleware
20 26
config/initializers/sanitizer.rb
@@ -1,14 +0,0 @@ @@ -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,40 +2,40 @@ module SanitizeParams
2 2
3 protected 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
@@ -779,6 +779,30 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -779,6 +779,30 @@ class SearchControllerTest &lt; ActionController::TestCase
779 assert_equivalent [t1,t2,c1,c2,c3,c4] , assigns(:searches)[:communities][:results] 779 assert_equivalent [t1,t2,c1,c2,c3,c4] , assigns(:searches)[:communities][:results]
780 end 780 end
781 781
  782 + should 'not raise an exception if tag query contains accented latin characters' do
  783 + tag_query = 'àáâãäå'
  784 + assert_nothing_raised(NoMethodError) { get :tag, :tag => tag_query }
  785 + end
  786 +
  787 + should 'not allow query injection' do
  788 + injection = '<iMg SrC=x OnErRoR=document.documentElement.innerHTML=1>SearchParam'
  789 + get :tag, :tag => injection
  790 + tag = assigns(:tag)
  791 + assert !tag.upcase.include?('IMG')
  792 + assert tag.include?('SearchParam')
  793 + end
  794 +
  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>']
  798 + get :tag, :tag => injection
  799 + tag = assigns(:tag)
  800 + tag.each { |t|
  801 + assert !t.upcase.include?('IMG')
  802 + assert !t.upcase.include?('SCRIPT')
  803 + }
  804 + end
  805 +
782 protected 806 protected
783 807
784 def create_event(profile, options) 808 def create_event(profile, options)