/
escaped_params.rb
93 lines (79 loc) · 2.31 KB
/
escaped_params.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# frozen_string_literal: true
require 'rack/protection'
require 'rack/utils'
require 'tempfile'
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.
#
# 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
return unless @javascript && (!@escaper.respond_to? :escape_javascript)
raise('Use EscapeUtils for JavaScript escaping.')
end
def call(env)
request = Request.new(env)
get_was = handle(request.GET)
post_was = begin
handle(request.POST)
rescue StandardError
nil
end
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)
when Tempfile then object
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