I am trying to include a section wherein my users can input HAML and
view the resulting HTML page.
I would like to make this as un-exploitable as possible.
This is what I have in place now:
= Haml::Engine.new(current_user.userinput).render(self)
This is obviously no good.
Previously, I was using standard HTML, and used sanitize to allow only
a certain array of tags, e.g.
= sanitize current_user.userinput, :tags => %w(div br span a h1 h2
h3 ul li hr b em img), :attributes => %w(style href id class title
src)
Is there anyway to combine the two? I'd like to only allow specific
tags in both html or haml to be processed, and everything else,
including ruby code, to be ignored/escaped.
My solution:
users_controller.rb:
def self
@users = User.all
@user = User.find_by_name(params[:name])
@name = User.all(params[:name])
if @user
@haml = User.find_by_name(params[:name]).userinput
end
end
self.html.haml:
= sanitize Haml::Engine.new(@haml).render(self), :tags => %w(div a
br span h1 h2 h3 b em img ul li ol hr), :attributes => %w(style href
id class title src)
For whatever reason, I couldnt run sanitize without moving userinput
into an instance variable.
Additionally, since this does not sanitize against embedded ruby code,
in my user model:
before_save :remove_script, :only => [ :userinput ]
def remove_script
self.userinput = userinput.gsub(/=(?!>)/, '═')
self.userinput = userinput.gsub(/-(?!>)/, '‒')
end
The replacement characters simply resemble = and -, but will cause
embedding code to fail, while still allowing the => syntax