helper and partial whitelisting functionality

Oleg committed Feb 14, 2012
commit dd3b5313d64262f702e7ec2bfa6707616979ebd3
Showing 9 changed files with 82 additions and 22 deletions
config/initializers/comfortable_mexican_sofa.rb +14 -5
@@ @@ -26,11 +26,6 @@ ComfortableMexicanSofa.configure do |config|
# If you want to include the routes manually set this to false
# config.use_default_routes = true
- # By default you cannot have irb code inside your layouts/pages/snippets.
- # Generally this is to prevent putting something like this:
- # <% User.delete_all %> but if you really want to allow it...
- # config.allow_irb = false
-
# File uploads use Paperclip and can support filesystem or s3 uploads. Override
# the upload method and appropriate settings based on Paperclip. For S3 see:
# http://rdoc.info/gems/paperclip/2.3.8/Paperclip/Storage/S3, and for
@@ @@ -78,6 +73,20 @@ ComfortableMexicanSofa.configure do |config|
# A class that is included as a sweeper to admin base controller if it's set
# config.admin_cache_sweeper = nil
+ # By default you cannot have irb code inside your layouts/pages/snippets.
+ # Generally this is to prevent putting something like this:
+ # <% User.delete_all %> but if you really want to allow it...
+ # config.allow_irb = false
+
+ # Whitelist of all helper methods that can be used via {{cms:helper}} tag. By default
+ # all helpers are allowed except `eval`, `send`, `call` and few others. Empty array
+ # will prevent rendering of all helpers.
+ # config.allowed_helpers = nil
+
+ # Whitelist of partials paths that can be used via {{cms:partial}} tag. All partials
+ # are accessible by default. Empty array will prevent rendering of all partials.
+ # config.allowed_partials = nil
+
end
# Default credentials for ComfortableMexicanSofa::HttpAuth
comfortable_mexican_sofa/configuration.rb b/lib/comfortable_mexican_sofa/configuration.rb +16 -5
@@ @@ -2,7 +2,7 @@
class ComfortableMexicanSofa::Configuration
- # Don't like Comfortable Mexican Sofa? Set it to whatever you like. :(
+ # Don't like ComfortableMexicanSofa? Set it to whatever you like. :(
attr_accessor :cms_title
# Module that will handle authentication to access cms-admin area
@@ @@ -22,9 +22,6 @@ class ComfortableMexicanSofa::Configuration
# Normally we include default routes from https://github.com/comfy/comfortable-mexican-sofa/blob/master/config/routes.rb
# If you want to include the routes manually set this to false
attr_accessor :use_default_routes
-
- # Not allowing irb code to be run inside page content. False by default.
- attr_accessor :allow_irb
# Upload settings
attr_accessor :upload_file_options
@@ @@ -56,6 +53,18 @@ class ComfortableMexicanSofa::Configuration
# A class that is included as a sweeper to admin base controller if it's set
attr_accessor :admin_cache_sweeper
+ # Not allowing irb code to be run inside page content. False by default.
+ attr_accessor :allow_irb
+
+ # Whitelist of all helper methods that can be used via {{cms:helper}} tag. By default
+ # all helpers are allowed except `eval`, `send`, `call` and few others. Empty array
+ # will prevent rendering of all helpers.
+ attr_accessor :allowed_helpers
+
+ # Whitelist of partials paths that can be used via {{cms:partial}} tag. All partials
+ # are accessible by default. Empty array will prevent rendering of all partials.
+ attr_accessor :allowed_partials
+
# Configuration defaults
def initialize
@cms_title = 'ComfortableMexicanSofa CMS Engine'
@@ @@ -65,7 +74,6 @@ class ComfortableMexicanSofa::Configuration
@admin_route_prefix = 'cms-admin'
@admin_route_redirect = ''
@use_default_routes = true
- @allow_irb = false
@upload_file_options = { :url => '/system/:class/:id/:attachment/:style/:filename' }
@enable_fixtures = false
@fixtures_path = File.expand_path('db/cms_fixtures', Rails.root)
@@ @@ -79,6 +87,9 @@ class ComfortableMexicanSofa::Configuration
@admin_locale = nil
@database_config = nil
@admin_cache_sweeper = nil
+ @allow_irb = false
+ @allowed_helpers = nil
+ @allowed_partials = nil
end
end
comfortable_mexican_sofa/render_methods.rb b/lib/comfortable_mexican_sofa/render_methods.rb +0 -1
@@ @@ -36,7 +36,6 @@ module ComfortableMexicanSofa::RenderMethods
#
def render(options = {}, locals = {}, &block)
- # TODO: add slug to Cms::Site as well
if options.is_a?(Hash) && identifier = options.delete(:cms_site)
unless @cms_site = Cms::Site.find_by_identifier(identifier)
raise ComfortableMexicanSofa::MissingSite.new(identifier)
comfortable_mexican_sofa/tags/helper.rb b/lib/comfortable_mexican_sofa/tags/helper.rb +7 -2
@@ @@ -1,7 +1,7 @@
class ComfortableMexicanSofa::Tag::Helper
include ComfortableMexicanSofa::Tag
- PROTECTED_METHODS = %w(eval class_eval instance_eval)
+ BLACKLIST = %w(eval class_eval instance_eval)
def self.regex_tag_signature(identifier = nil)
identifier ||= /[\w\-]+/
@@ @@ -13,7 +13,12 @@ class ComfortableMexicanSofa::Tag::Helper
end
def render
- content if !PROTECTED_METHODS.member?(identifier) || ComfortableMexicanSofa.config.allow_irb
+ whitelist = ComfortableMexicanSofa.config.allowed_helpers
+ if whitelist.is_a?(Array)
+ content if whitelist.map!(&:to_s).member?(identifier)
+ else
+ content unless BLACKLIST.member?(identifier)
+ end
end
end
\ No newline at end of file
comfortable_mexican_sofa/tags/partial.rb b/lib/comfortable_mexican_sofa/tags/partial.rb +9 -0
@@ @@ -11,4 +11,13 @@ class ComfortableMexicanSofa::Tag::Partial
"<%= render :partial => '#{identifier}'#{ps.blank?? nil : ", :locals => {#{ps}}"} %>"
end
+ def render
+ whitelist = ComfortableMexicanSofa.config.allowed_partials
+ if whitelist.is_a?(Array)
+ content if whitelist.member?(identifier)
+ else
+ content
+ end
+ end
+
end
\ No newline at end of file
test/test_helper.rb +3 -1
@@ @@ -24,7 +24,6 @@ class ActiveSupport::TestCase
config.admin_route_prefix = 'cms-admin'
config.admin_route_redirect = ''
config.use_default_routes = true
- config.allow_irb = false
config.enable_fixtures = false
config.fixtures_path = File.expand_path('db/cms_fixtures', Rails.root)
config.revisions_limit = 25
@@ @@ -37,6 +36,9 @@ class ActiveSupport::TestCase
config.admin_locale = nil
config.upload_file_options = { :url => '/system/:class/:id/:attachment/:style/:filename' }
config.admin_cache_sweeper = nil
+ config.allow_irb = false
+ config.allowed_helpers = nil
+ config.allowed_partials = nil
end
ComfortableMexicanSofa::HttpAuth.username = 'username'
ComfortableMexicanSofa::HttpAuth.password = 'password'
test/unit/configuration_test.rb +4 -1
@@ @@ -12,7 +12,7 @@ class ConfigurationTest < ActiveSupport::TestCase
assert_equal 'cms-admin', config.admin_route_prefix
assert_equal true, config.use_default_routes
assert_equal '', config.admin_route_redirect
- assert_equal false, config.allow_irb
+
assert_equal false, config.enable_fixtures
assert_equal File.expand_path('db/cms_fixtures', Rails.root), config.fixtures_path
assert_equal 25, config.revisions_limit
@@ @@ -28,6 +28,9 @@ class ConfigurationTest < ActiveSupport::TestCase
:url => '/system/:class/:id/:attachment/:style/:filename'
}), config.upload_file_options
assert_equal nil, config.admin_cache_sweeper
+ assert_equal false, config.allow_irb
+ assert_equal nil, config.allowed_helpers
+ assert_equal nil, config.allowed_partials
end
def test_initialization_overrides
test/unit/tags/helper_test.rb +13 -7
@@ @@ -56,25 +56,31 @@ class HelperTagTest < ActiveSupport::TestCase
assert_equal "<%= method_name('param1', 'param2') %>", tag.render
end
- def test_protected_methods_with_irb_enabled
- ComfortableMexicanSofa.config.allow_irb = true
- ComfortableMexicanSofa::Tag::Helper::PROTECTED_METHODS.each do |method|
+ def test_blacklisted_methods
+ ComfortableMexicanSofa::Tag::Helper::BLACKLIST.each do |method|
tag = ComfortableMexicanSofa::Tag::Helper.initialize_tag(
cms_pages(:default), "{{ cms:helper:#{method}:Rails.env }}"
)
assert_equal "<%= #{method}('Rails.env') %>", tag.content
- assert_equal "<%= #{method}('Rails.env') %>", tag.render
+ assert_equal nil, tag.render
end
end
- def test_protected_methods_with_irb_disabled
- ComfortableMexicanSofa::Tag::Helper::PROTECTED_METHODS.each do |method|
+ def test_whitelisted_methods
+ ComfortableMexicanSofa.config.allowed_helpers = [:tester, :eval]
+ ComfortableMexicanSofa.config.allowed_helpers.each do |method|
tag = ComfortableMexicanSofa::Tag::Helper.initialize_tag(
cms_pages(:default), "{{ cms:helper:#{method}:Rails.env }}"
)
assert_equal "<%= #{method}('Rails.env') %>", tag.content
- assert_equal nil, tag.render
+ assert_equal "<%= #{method}('Rails.env') %>", tag.render
end
+
+ tag = ComfortableMexicanSofa::Tag::Helper.initialize_tag(
+ cms_pages(:default), "{{ cms:helper:invalid:Rails.env }}"
+ )
+ assert_equal "<%= invalid('Rails.env') %>", tag.content
+ assert_equal nil, tag.render
end
end
test/unit/tags/partial_test.rb +16 -0
@@ @@ -57,4 +57,20 @@ class PartialTagTest < ActiveSupport::TestCase
assert_equal "<%= render :partial => 'path/to/partial', :locals => {:param_1 => 'param1', :param_2 => 'param2'} %>", tag.render
end
+ def test_whitelisted_paths
+ ComfortableMexicanSofa.config.allowed_partials = ['safe/path']
+
+ tag = ComfortableMexicanSofa::Tag::Partial.initialize_tag(
+ cms_pages(:default), '{{cms:partial:safe/path}}'
+ )
+ assert_equal "<%= render :partial => 'safe/path' %>", tag.content
+ assert_equal "<%= render :partial => 'safe/path' %>", tag.render
+
+ tag = ComfortableMexicanSofa::Tag::Partial.initialize_tag(
+ cms_pages(:default), '{{cms:partial:unsafe/path}}'
+ )
+ assert_equal "<%= render :partial => 'unsafe/path' %>", tag.content
+ assert_equal nil, tag.render
+ end
+
end
\ No newline at end of file