# =========== lib file =================== class XssScrubber def angular_xss_filter(unknown) case unknown when Hash angular_xss_filter_hash(unknown) when Array angular_xss_filter_array(unknown) when String angular_xss_filter_string(unknown) else unknown end end def angular_xss_filter_hash(hash) clean_hash = {} hash.each do |key, value| clean_hash[key] = angular_xss_filter(value) end ActiveSupport::HashWithIndifferentAccess.new(clean_hash) end def angular_xss_filter_array(arr) clean_arr = [] arr.each do |a| clean_arr << angular_xss_filter(a) end clean_arr end def angular_xss_filter_string(str) # remove {{, }}, encoded versions, and all combos str.gsub(/({{|}}|({){2}|(}){2}|\{{|{\{|}\}|\}})/, '') end end # ========= ApplicationController ============== class ApplicationController < ActionController::Base before_filter :filter_angular_xss def filter_angular_xss params.replace(XssScrubber.new.angular_xss_filter(params)) end end # ========== Spec ============== describe XssScrubber do before :each do @xss_str = "{{XSS}}{{XSS}}{{XSS}}{{XSS}}" @clean_str = "XSSXSSXSSXSS" @xss_hash = { str: @xss_str, arr: [@xss_str, @xss_str], hsh: { str: @xss_str, arr: [@xss_str, @xss_str, 12] } } @clean_hash = { str: @clean_str, arr: [@clean_str, @clean_str], hsh: { str: @clean_str, arr: [@clean_str, @clean_str, 12] } } @scrubber = XssScrubber.new end it "cleans a string" do @scrubber.angular_xss_filter_string(@xss_str).should == @clean_str end it "leaves a number alone" do @scrubber.angular_xss_filter(9).should == 9 end it "leaves a float alone" do @scrubber.angular_xss_filter(6.66).should == 6.66 end it "filters a hash containing other types" do @scrubber.angular_xss_filter(@xss_hash).should == @clean_hash end end