Browse files

add method_missing magic to temporarily turn off html_escaping on non…

…-column methods.
  • Loading branch information...
1 parent 565183c commit aa20687633b612d6f09009210889b1d122cc7006 @jsgarvin jsgarvin committed Mar 5, 2008
Showing with 31 additions and 1 deletion.
  1. +3 −0 README
  2. +16 −0 lib/cross_site_sniper.rb
  3. +12 −1 test/cross_site_sniper_test.rb
View
3 README
@@ -35,6 +35,9 @@ By not escaping data accessed via the hash method (eg. @quiz[:question]), forms
prepopulate with the *unescaped* data, allowing user friendly legitimate uses of
usually escaped characters.
+Cross Site Sniper also supports calling <method_name>_without_html_escaping on
+non-column methods to temporarily disable html escaping for that method call.
+(eg. @person.some_computed_value_without_html_escaping)
== Installation
script/plugin install -x http://xss.rubyforge.org/svn/cross_site_sniper/trunk
View
16 lib/cross_site_sniper.rb
@@ -35,6 +35,9 @@ def define_attribute_methods_with_html_escaping
# Retrieve the raw data.
val = send("#{column.name}_without_html_escaping")
+ #if htmlescaping is disabled, just send it as is.
+ return val if @html_escaping_disabled
+
# Only escape strings. Other data types, such
# as 'nil', should be returned uncorrupted.
val.is_a?(String) ? ERB::Util::h(val) : val
@@ -51,6 +54,19 @@ def define_attribute_methods_with_html_escaping
end
alias_method_chain :define_attribute_methods, :html_escaping
+
+ def method_missing(method_sym,*args,&blk)
+ #catch without_html_escaping for non-column methods and simulate it
+ if method_sym.to_s[/(.+)_without_html_escaping/]
+ original_method = $1
+ @html_escaping_disabled = true
+ val = self.send(original_method)
+ @html_escaping_disabled = false
+ return val
+ else
+ super
+ end
+ end
end
end
View
13 test/cross_site_sniper_test.rb
@@ -32,6 +32,9 @@ def test_basics
assert_equal(false,hunter.respond_to?('title_with_html_escaping'))
assert_equal(false,hunter.respond_to?('title_without_html_escaping'))
+ assert_equal('&lt;b&gt;One&lt;/b&gt;(42)',hunter.name_and_age)
+ assert_equal('<b>One</b>(42)',hunter.name_and_age_without_html_escaping)
+
assert_equal('<b>Overriden</b>',hunter.description)
assert_equal(false,hunter.respond_to?('description_with_html_escaping'))
assert_equal(false,hunter.respond_to?('description_without_html_escaping'))
@@ -55,7 +58,8 @@ class SnipeHunter < ActiveRecord::Base
#make description unescaped
def description; '<b>Overriden</b>'; end
-
+
+ def name_and_age; "#{name}(#{age})"; end
end
class Snipe < ActiveRecord::Base
@@ -69,6 +73,10 @@ class Leprechaun < ActiveRecord::Base
end
def setup_db
+ #Supress annoying Schema creation output when tests run
+ old_stdout = $stdout
+ $stdout = StringIO.new
+
ActiveRecord::Schema.define(:version => 1) do
create_table :snipe_hunters do |t|
t.column :name, :string
@@ -87,6 +95,9 @@ def setup_db
t.column :name, :string
end
end
+
+ #Re-enable stdout
+ $stdout = old_stdout
end
def teardown_db

0 comments on commit aa20687

Please sign in to comment.