Skip to content

Instantly share code, notes, and snippets.

@andrewk
Last active December 28, 2015 06:49
Show Gist options
  • Save andrewk/7460371 to your computer and use it in GitHub Desktop.
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…
# =========== 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(/({{|}}|(&#x7b;){2}|(&#x7d;){2}|\{&#x7b;|&#x7b;\{|&#x7d;\}|\}&#x7d;)/, '')
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 = "&#x7b;&#x7b;XSS&#x7d;&#x7d;{{XSS}}{&#x7b;XSS&#x7d;}&#x7b;{XSS}&#x7d;"
@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