This post originated from an RSS feed registered with Ruby Buzz
by Jan Lelis.
Original Post: Rack::NoTags
Feed Title: rbJ*_*L.net
Feed URL: http://feeds.feedburner.com/rbJL
Feed Description: Hi, I am a fan of Ruby and like to explore it and the world around ;).
So I started this blog, where I am publishing code snippets, tutorials for beginners as well as general thoughts about Ruby, the web or programming in general.
A middleware that removes < and > from all incoming requests.
About
Lots of XSS attacks try to inject some kinds of javascript. But almost every attack requires some html tags to be inserted (in which they can start javascript in some way).
This Rack middleware approaches this by radically removing all < and > in all incoming get/post paramaters.
Note: This means, if your site needs to send < and > in post or get requests, it probably will not work, anymore – you have to change your application design to use this middleware.
There are three modes available:
:brackets_only (default)
substitutes < with < and > with >
:valid_html
substitutes < > & " ’ similar to Rack::Utils#escape_html (also known as h)
:paranoid
deletes < > < > %3C %3E < > < &x3e; and similar variations
It is important to keep in mind: By using Rack::NoTags, your website is not suddenly 100% save from XSS attacks. Look at it as just another security-layer.
# # # ## Rack::NoTags removes < and > from all incoming requests# This software is licensed under the CC-GNU GPL version 2.0 or later.# # # #module Rackclass NoTagsPatterns={# replacement => [ array, of, patterns ]:brackets_only=>{'<'=>['<'],'>'=>['>']},:valid_xml=>{# similar to Rack::Utils#escape_html'<'=>['<'],'>'=>['>'],'&'=>['&'],'''=>["'"],'"'=>['"']},:paranoid=>{# encodings which might be interpreted as < or > in some situations''=>%w[ < > %3C %3E ]+[/&[lg]t;?/i,/�{0,5}6[02];?/,/�{0,5}3[ce];?/i]}}def initialize(app,mode=:brackets_only)@app=app@patterns=Patterns[mode.to_sym]enddef call(env)# get form params in a nice formatparams=Rack::Utils.parse_query(env['rack.input'].read,"&")# remove @patternsparams=strip_all(params)# update envirionmentenv["rack.input"]=StringIO.new(Rack::Utils.build_query(params))@app.call(env)endprivate# applies each 'to-substitute'-pattern to the stringdef strip(string)@patterns.each{|replacement,patterns|patterns.each{|pattern|string=string.gsub(pattern,replacement)}}stringend# looks at every param-element an sends it to the strip methoddef strip_all(params)ret={}params.each{|param,value|ret[strip(param)]=value.is_a?(Array)?value.map{|v|strip(v)}:strip(value)}retendendend
(c) 2009 Jan Lelis. Please contact me, if you want to use this content.