mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
87 lines
2.3 KiB
Ruby
87 lines
2.3 KiB
Ruby
require 'rack/protection'
|
|
require 'rack/utils'
|
|
|
|
begin
|
|
require 'escape_utils'
|
|
rescue LoadError
|
|
end
|
|
|
|
module Rack
|
|
module Protection
|
|
##
|
|
# Prevented attack:: XSS
|
|
# Supported browsers:: all
|
|
# More infos:: http://en.wikipedia.org/wiki/Cross-site_scripting
|
|
#
|
|
# Automatically escapes Rack::Request#params so they can be embedded in HTML
|
|
# or JavaScript without any further issues. Calls +html_safe+ on the escaped
|
|
# strings if defined, to avoid double-escaping in Rails.
|
|
#
|
|
# Options:
|
|
# escape:: What escaping modes to use, should be Symbol or Array of Symbols.
|
|
# Available: :html (default), :javascript, :url
|
|
class EscapedParams < Base
|
|
extend Rack::Utils
|
|
|
|
class << self
|
|
alias escape_url escape
|
|
public :escape_html
|
|
end
|
|
|
|
default_options :escape => :html,
|
|
:escaper => defined?(EscapeUtils) ? EscapeUtils : self
|
|
|
|
def initialize(*)
|
|
super
|
|
|
|
modes = Array options[:escape]
|
|
@escaper = options[:escaper]
|
|
@html = modes.include? :html
|
|
@javascript = modes.include? :javascript
|
|
@url = modes.include? :url
|
|
|
|
if @javascript and not @escaper.respond_to? :escape_javascript
|
|
fail("Use EscapeUtils for JavaScript escaping.")
|
|
end
|
|
end
|
|
|
|
def call(env)
|
|
request = Request.new(env)
|
|
get_was = handle(request.GET)
|
|
post_was = handle(request.POST) rescue nil
|
|
app.call env
|
|
ensure
|
|
request.GET.replace get_was if get_was
|
|
request.POST.replace post_was if post_was
|
|
end
|
|
|
|
def handle(hash)
|
|
was = hash.dup
|
|
hash.replace escape(hash)
|
|
was
|
|
end
|
|
|
|
def escape(object)
|
|
case object
|
|
when Hash then escape_hash(object)
|
|
when Array then object.map { |o| escape(o) }
|
|
when String then escape_string(object)
|
|
else nil
|
|
end
|
|
end
|
|
|
|
def escape_hash(hash)
|
|
hash = hash.dup
|
|
hash.each { |k,v| hash[k] = escape(v) }
|
|
hash
|
|
end
|
|
|
|
def escape_string(str)
|
|
str = @escaper.escape_url(str) if @url
|
|
str = @escaper.escape_html(str) if @html
|
|
str = @escaper.escape_javascript(str) if @javascript
|
|
str
|
|
end
|
|
end
|
|
end
|
|
end
|