Last active
December 28, 2015 06:49
-
-
Save andrewk/7460371 to your computer and use it in GitHub Desktop.
Rails doesn't expect {{, }}, or encoded versions to be an XSS vulnerability, so doesn't do anything about them in user input. If your page has AngularJS sections (ngApp) which have user input, you need to protect yourself from the attack vector added by AngularJS. This is a VERY basic, alpha implementation. It works as advertised, but has room f…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# =========== 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment