# Escaping/stripping all user HTML input

**URL:** <https://www.ruby-forum.com/t/escaping-stripping-all-user-html-input/108074>\
**Category:** Rails\
**Created:** [June 28, 2007, 9:18pm UTC](https://www.ruby-forum.com/t/escaping-stripping-all-user-html-input/108074 "2007-06-28T21:18:31Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![luis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3e96dc/32.png) [@luis](https://www.ruby-forum.com/u/luis)\
**Post date:** [June 28, 2007, 9:18pm UTC](https://www.ruby-forum.com/t/escaping-stripping-all-user-html-input/108074/1 "2007-06-28T21:18:31Z")

</div>

(Some of you may be reading this twice as I accidentally posted this  
to ruby talk)

I am writing an application where I know that I do not need to allow  
any HTML input from a user.

I am considering using before\_filter at the controller level to call a  
method that essentially performs the following on the appropriate  
members of the params hash:

- call strip\_tags()
- escape any remaining characters with h()

The reason why I am doing this is it seems repetitive and error prone  
to have to call the above method every time in a view where user input  
is being displayed. Ultimately, I would prefer to store the data in as  
“non-malicious” format as possible and not have to worry at the  
presentation level of escaping that data at a later time.

Is there a better way to do this? Is there existing code that does  
this already? Some googling yielded nothing specific other than  
postings to the effect of “in your view, make sure to use h()”.

---

<div class="post-metadata">

**Author:** ![luis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3e96dc/32.png) [@luis](https://www.ruby-forum.com/u/luis)\
**Post date:** [July 4, 2007, 4:27pm UTC](https://www.ruby-forum.com/t/escaping-stripping-all-user-html-input/108074/2 "2007-07-04T16:27:18Z")

</div>

Luis wrote:

> I am writing an application where I know that I do not need to allow  
> any HTML input from a user.
> 
> I am considering using before\_filter at the controller level to call a  
> method that essentially performs the following on the appropriate  
> members of the params hash:
> 
> - call strip\_tags()
> - escape any remaining characters with h()

I will answer, but I don’t understand the problem with storing raw HTML  
and  
escaping it. If the user typed into a text area, they should see  
  
in the view, with the angle brackets, and we should not strip the tags.  
You  
can call the equivalent of h() when you save their change, for example.

> The reason why I am doing this is it seems repetitive and error prone  
> to have to call the above method every time in a view where user input  
> is being displayed. Ultimately, I would prefer to store the data in as  
> “non-malicious” format as possible and not have to worry at the  
> presentation level of escaping that data at a later time.
> 
> Is there a better way to do this? Is there existing code that does  
> this already? Some googling yielded nothing specific other than  
> postings to the effect of “in your view, make sure to use h()”.

I can think of a way. It’s sick, excessive, and bullet-proof. Here is  
assert\_tidy:

def assert\_tidy(messy = @response.body, verbosity = :noisy)  
scratch\_html = RAILS\_ROOT + ‘/…/scratch.html’ # TODO tune me!  
File.open(scratch\_html, ‘w’){|f| f.write(messy) }  
gripes = `tidy -eq #{scratch_html} 2>&1`  
gripes.split(“\n”)  
exclude, inclued = gripes.partition do |g|  
g =~ / - Info: / or  
g =~ /Warning: missing \<!DOCTYPE\> declaration/ or  
g =~ /proprietary attribute/ or  
g =~ /lacks “(summary|alt)” attribute/  
end  
puts inclued if verbosity == :noisy  
# inclued.map{|i| puts Regexp.escape(i) }  
assert\_xml `tidy -wrap 1001 -asxhtml #{scratch_html} 2>/dev/null`  
# CONSIDER that should report serious HTML deformities  
end

You can take out the assert\_xml if you don’t have yar\_wiki (whence that  
comes). That code uses the command-line tidy. Don’t worry about the  
Ruby-oriented tidy.so project.

Migrate that test-side code to production code, and you have a function  
that  
turns sloppy HTML into pristine XHTML. Now that your input is XML, you  
can  
strip out all the tags like this:

class REXML::Element  
def inner\_text  
self.each\_element( ‘.//text()’ ){}.join( ‘’ )  
end  
end

This obscenely over-the-top solution will hopefully inspire someone to  
post  
a solution in the usual 4 lines!

–  
Phlip  
[Test Driven Ajax (on Rails) [Book]](http://www.oreilly.com/catalog/9780596510657/)  
“Test Driven Ajax (on Rails)”  
assert\_xpath, assert\_javascript, & assert\_ajax
