rack-protection 2.1.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +8 -8
- data/README.md +8 -1
- data/Rakefile +24 -22
- data/lib/rack/protection/authenticity_token.rb +81 -28
- data/lib/rack/protection/base.rb +37 -16
- data/lib/rack/protection/content_security_policy.rb +8 -7
- data/lib/rack/protection/cookie_tossing.rb +7 -5
- data/lib/rack/protection/escaped_params.rb +14 -10
- data/lib/rack/protection/form_token.rb +3 -1
- data/lib/rack/protection/frame_options.rb +4 -2
- data/lib/rack/protection/host_authorization.rb +110 -0
- data/lib/rack/protection/http_origin.rb +6 -10
- data/lib/rack/protection/ip_spoofing.rb +7 -3
- data/lib/rack/protection/json_csrf.rb +6 -3
- data/lib/rack/protection/path_traversal.rb +8 -5
- data/lib/rack/protection/referrer_policy.rb +4 -2
- data/lib/rack/protection/remote_referrer.rb +2 -0
- data/lib/rack/protection/remote_token.rb +2 -0
- data/lib/rack/protection/session_hijacking.rb +8 -7
- data/lib/rack/protection/strict_transport.rb +5 -3
- data/lib/rack/protection/version.rb +3 -1
- data/lib/rack/protection/xss_header.rb +5 -3
- data/lib/rack/protection.rb +5 -3
- data/lib/rack-protection.rb +1 -1
- data/lib/rack_protection.rb +3 -0
- data/rack-protection.gemspec +30 -25
- metadata +29 -20
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -17,7 +19,7 @@ module Rack
|
|
17
19
|
# frame. Use :deny to forbid any embedding, :sameorigin
|
18
20
|
# to allow embedding from the same origin (default).
|
19
21
|
class FrameOptions < Base
|
20
|
-
default_options :
|
22
|
+
default_options frame_options: :sameorigin
|
21
23
|
|
22
24
|
def frame_options
|
23
25
|
@frame_options ||= begin
|
@@ -29,7 +31,7 @@ module Rack
|
|
29
31
|
|
30
32
|
def call(env)
|
31
33
|
status, headers, body = @app.call(env)
|
32
|
-
headers['
|
34
|
+
headers['x-frame-options'] ||= frame_options if html? headers
|
33
35
|
[status, headers, body]
|
34
36
|
end
|
35
37
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack/protection'
|
4
|
+
require 'ipaddr'
|
5
|
+
|
6
|
+
module Rack
|
7
|
+
module Protection
|
8
|
+
##
|
9
|
+
# Prevented attack:: DNS rebinding and other Host header attacks
|
10
|
+
# Supported browsers:: all
|
11
|
+
# More infos:: https://en.wikipedia.org/wiki/DNS_rebinding
|
12
|
+
# https://portswigger.net/web-security/host-header
|
13
|
+
#
|
14
|
+
# Blocks HTTP requests with an unrecognized hostname in any of the following
|
15
|
+
# HTTP headers: Host, X-Forwarded-Host, Forwarded
|
16
|
+
#
|
17
|
+
# If you want to permit a specific hostname, you can pass in as the `:permitted_hosts` option:
|
18
|
+
#
|
19
|
+
# use Rack::Protection::HostAuthorization, permitted_hosts: ["www.example.org", "sinatrarb.com"]
|
20
|
+
#
|
21
|
+
# The `:allow_if` option can also be set to a proc to use custom allow/deny logic.
|
22
|
+
class HostAuthorization < Base
|
23
|
+
DOT = '.'
|
24
|
+
PORT_REGEXP = /:\d+\z/.freeze
|
25
|
+
SUBDOMAINS = /[a-z0-9\-.]+/.freeze
|
26
|
+
private_constant :DOT,
|
27
|
+
:PORT_REGEXP,
|
28
|
+
:SUBDOMAINS
|
29
|
+
default_reaction :deny
|
30
|
+
default_options allow_if: nil,
|
31
|
+
message: 'Host not permitted'
|
32
|
+
|
33
|
+
def initialize(*)
|
34
|
+
super
|
35
|
+
@permitted_hosts = []
|
36
|
+
@domain_hosts = []
|
37
|
+
@ip_hosts = []
|
38
|
+
@all_permitted_hosts = Array(options[:permitted_hosts])
|
39
|
+
|
40
|
+
@all_permitted_hosts.each do |host|
|
41
|
+
case host
|
42
|
+
when String
|
43
|
+
if host.start_with?(DOT)
|
44
|
+
domain = host[1..-1]
|
45
|
+
@permitted_hosts << domain.downcase
|
46
|
+
@domain_hosts << /\A#{SUBDOMAINS}#{Regexp.escape(domain)}\z/i
|
47
|
+
else
|
48
|
+
@permitted_hosts << host.downcase
|
49
|
+
end
|
50
|
+
when IPAddr then @ip_hosts << host
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def accepts?(env)
|
56
|
+
return true if options[:allow_if]&.call(env)
|
57
|
+
return true if @all_permitted_hosts.empty?
|
58
|
+
|
59
|
+
request = Request.new(env)
|
60
|
+
origin_host = extract_host(request.host_authority)
|
61
|
+
forwarded_host = extract_host(request.forwarded_authority)
|
62
|
+
|
63
|
+
debug env, "#{self.class} " \
|
64
|
+
"@all_permitted_hosts=#{@all_permitted_hosts.inspect} " \
|
65
|
+
"@permitted_hosts=#{@permitted_hosts.inspect} " \
|
66
|
+
"@domain_hosts=#{@domain_hosts.inspect} " \
|
67
|
+
"@ip_hosts=#{@ip_hosts.inspect} " \
|
68
|
+
"origin_host=#{origin_host.inspect} " \
|
69
|
+
"forwarded_host=#{forwarded_host.inspect}"
|
70
|
+
|
71
|
+
if host_permitted?(origin_host)
|
72
|
+
if forwarded_host.nil?
|
73
|
+
true
|
74
|
+
else
|
75
|
+
host_permitted?(forwarded_host)
|
76
|
+
end
|
77
|
+
else
|
78
|
+
false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def extract_host(authority)
|
85
|
+
authority.to_s.split(PORT_REGEXP).first&.downcase
|
86
|
+
end
|
87
|
+
|
88
|
+
def host_permitted?(host)
|
89
|
+
exact_match?(host) || domain_match?(host) || ip_match?(host)
|
90
|
+
end
|
91
|
+
|
92
|
+
def exact_match?(host)
|
93
|
+
@permitted_hosts.include?(host)
|
94
|
+
end
|
95
|
+
|
96
|
+
def domain_match?(host)
|
97
|
+
return false if host.nil?
|
98
|
+
return false if host.start_with?(DOT)
|
99
|
+
|
100
|
+
@domain_hosts.any? { |domain_host| host.match?(domain_host) }
|
101
|
+
end
|
102
|
+
|
103
|
+
def ip_match?(host)
|
104
|
+
@ip_hosts.any? { |ip_host| ip_host.include?(host) }
|
105
|
+
rescue IPAddr::InvalidAddressError
|
106
|
+
false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -19,7 +21,7 @@ module Rack
|
|
19
21
|
class HttpOrigin < Base
|
20
22
|
DEFAULT_PORTS = { 'http' => 80, 'https' => 443, 'coffee' => 80 }
|
21
23
|
default_reaction :deny
|
22
|
-
default_options :
|
24
|
+
default_options allow_if: nil
|
23
25
|
|
24
26
|
def base_url(env)
|
25
27
|
request = Rack::Request.new(env)
|
@@ -29,19 +31,13 @@ module Rack
|
|
29
31
|
|
30
32
|
def accepts?(env)
|
31
33
|
return true if safe? env
|
32
|
-
return true unless origin = env['HTTP_ORIGIN']
|
34
|
+
return true unless (origin = env['HTTP_ORIGIN'])
|
33
35
|
return true if base_url(env) == origin
|
34
|
-
return true if options[:allow_if]
|
35
|
-
|
36
|
-
if options.key? :origin_whitelist
|
37
|
-
warn "Rack::Protection origin_whitelist option is deprecated and will be removed, " \
|
38
|
-
"use permitted_origins instead.\n"
|
39
|
-
end
|
36
|
+
return true if options[:allow_if]&.call(env)
|
40
37
|
|
41
|
-
permitted_origins = options[:permitted_origins]
|
38
|
+
permitted_origins = options[:permitted_origins]
|
42
39
|
Array(permitted_origins).include? origin
|
43
40
|
end
|
44
|
-
|
45
41
|
end
|
46
42
|
end
|
47
43
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -13,9 +15,11 @@ module Rack
|
|
13
15
|
|
14
16
|
def accepts?(env)
|
15
17
|
return true unless env.include? 'HTTP_X_FORWARDED_FOR'
|
16
|
-
|
17
|
-
|
18
|
-
return false if env.include?
|
18
|
+
|
19
|
+
ips = env['HTTP_X_FORWARDED_FOR'].split(',').map(&:strip)
|
20
|
+
return false if env.include?('HTTP_CLIENT_IP') && (!ips.include? env['HTTP_CLIENT_IP'])
|
21
|
+
return false if env.include?('HTTP_X_REAL_IP') && (!ips.include? env['HTTP_X_REAL_IP'])
|
22
|
+
|
19
23
|
true
|
20
24
|
end
|
21
25
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -17,7 +19,7 @@ module Rack
|
|
17
19
|
#
|
18
20
|
# The `:allow_if` option can be set to a proc to use custom allow/deny logic.
|
19
21
|
class JsonCsrf < Base
|
20
|
-
default_options :
|
22
|
+
default_options allow_if: nil
|
21
23
|
|
22
24
|
alias react deny
|
23
25
|
|
@@ -36,8 +38,9 @@ module Rack
|
|
36
38
|
|
37
39
|
def has_vector?(request, headers)
|
38
40
|
return false if request.xhr?
|
39
|
-
return false if options[:allow_if]
|
40
|
-
return false unless headers['
|
41
|
+
return false if options[:allow_if]&.call(request.env)
|
42
|
+
return false unless headers['content-type'].to_s.split(';', 2).first =~ %r{^\s*application/json\s*$}
|
43
|
+
|
41
44
|
origin(request.env).nil? and referrer(request.env) != request.host
|
42
45
|
end
|
43
46
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -11,11 +13,11 @@ module Rack
|
|
11
13
|
# Thus <tt>GET /foo/%2e%2e%2fbar</tt> becomes <tt>GET /bar</tt>.
|
12
14
|
class PathTraversal < Base
|
13
15
|
def call(env)
|
14
|
-
path_was = env[
|
15
|
-
env[
|
16
|
+
path_was = env['PATH_INFO']
|
17
|
+
env['PATH_INFO'] = cleanup path_was if path_was && !path_was.empty?
|
16
18
|
app.call env
|
17
19
|
ensure
|
18
|
-
env[
|
20
|
+
env['PATH_INFO'] = path_was
|
19
21
|
end
|
20
22
|
|
21
23
|
def cleanup(path)
|
@@ -29,12 +31,13 @@ module Rack
|
|
29
31
|
unescaped = unescaped.gsub(backslash, slash)
|
30
32
|
|
31
33
|
unescaped.split(slash).each do |part|
|
32
|
-
next if part.empty?
|
34
|
+
next if part.empty? || (part == dot)
|
35
|
+
|
33
36
|
part == '..' ? parts.pop : parts << part
|
34
37
|
end
|
35
38
|
|
36
39
|
cleaned = slash + parts.join(slash)
|
37
|
-
cleaned << slash if parts.any?
|
40
|
+
cleaned << slash if parts.any? && unescaped =~ (%r{/\.{0,2}$})
|
38
41
|
cleaned
|
39
42
|
end
|
40
43
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -13,11 +15,11 @@ module Rack
|
|
13
15
|
# Options:
|
14
16
|
# referrer_policy:: The policy to use (default: 'strict-origin-when-cross-origin')
|
15
17
|
class ReferrerPolicy < Base
|
16
|
-
default_options :
|
18
|
+
default_options referrer_policy: 'strict-origin-when-cross-origin'
|
17
19
|
|
18
20
|
def call(env)
|
19
21
|
status, headers, body = @app.call(env)
|
20
|
-
headers['
|
22
|
+
headers['referrer-policy'] ||= options[:referrer_policy]
|
21
23
|
[status, headers, body]
|
22
24
|
end
|
23
25
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -13,23 +15,22 @@ module Rack
|
|
13
15
|
# spoofed, too, this will not prevent determined hijacking attempts.
|
14
16
|
class SessionHijacking < Base
|
15
17
|
default_reaction :drop_session
|
16
|
-
default_options :
|
17
|
-
|
18
|
+
default_options tracking_key: :tracking,
|
19
|
+
track: %w[HTTP_USER_AGENT]
|
18
20
|
|
19
21
|
def accepts?(env)
|
20
22
|
session = session env
|
21
23
|
key = options[:tracking_key]
|
22
24
|
if session.include? key
|
23
|
-
session[key].all? { |k,v| v ==
|
25
|
+
session[key].all? { |k, v| v == encode(env[k]) }
|
24
26
|
else
|
25
27
|
session[key] = {}
|
26
|
-
options[:track].each { |k| session[key][k] =
|
28
|
+
options[:track].each { |k| session[key][k] = encode(env[k]) }
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
|
-
def
|
31
|
-
value
|
32
|
-
options[:encrypt_tracking] ? super(value) : value
|
32
|
+
def encode(value)
|
33
|
+
value.to_s.downcase
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -18,11 +20,11 @@ module Rack
|
|
18
20
|
# preload:: Allow this domain to be included in browsers HSTS preload list. See https://hstspreload.appspot.com/
|
19
21
|
|
20
22
|
class StrictTransport < Base
|
21
|
-
default_options :
|
23
|
+
default_options max_age: 31_536_000, include_subdomains: false, preload: false
|
22
24
|
|
23
25
|
def strict_transport
|
24
26
|
@strict_transport ||= begin
|
25
|
-
strict_transport =
|
27
|
+
strict_transport = "max-age=#{options[:max_age]}"
|
26
28
|
strict_transport += '; includeSubDomains' if options[:include_subdomains]
|
27
29
|
strict_transport += '; preload' if options[:preload]
|
28
30
|
strict_transport.to_str
|
@@ -31,7 +33,7 @@ module Rack
|
|
31
33
|
|
32
34
|
def call(env)
|
33
35
|
status, headers, body = @app.call(env)
|
34
|
-
headers['
|
36
|
+
headers['strict-transport-security'] ||= strict_transport
|
35
37
|
[status, headers, body]
|
36
38
|
end
|
37
39
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection'
|
2
4
|
|
3
5
|
module Rack
|
@@ -12,12 +14,12 @@ module Rack
|
|
12
14
|
# Options:
|
13
15
|
# xss_mode:: How the browser should prevent the attack (default: :block)
|
14
16
|
class XSSHeader < Base
|
15
|
-
default_options :
|
17
|
+
default_options xss_mode: :block, nosniff: true
|
16
18
|
|
17
19
|
def call(env)
|
18
20
|
status, headers, body = @app.call(env)
|
19
|
-
headers['
|
20
|
-
headers['
|
21
|
+
headers['x-xss-protection'] ||= "1; mode=#{options[:xss_mode]}" if html? headers
|
22
|
+
headers['x-content-type-options'] ||= 'nosniff' if options[:nosniff]
|
21
23
|
[status, headers, body]
|
22
24
|
end
|
23
25
|
end
|
data/lib/rack/protection.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack/protection/version'
|
2
4
|
require 'rack'
|
3
5
|
|
@@ -10,6 +12,7 @@ module Rack
|
|
10
12
|
autoload :EscapedParams, 'rack/protection/escaped_params'
|
11
13
|
autoload :FormToken, 'rack/protection/form_token'
|
12
14
|
autoload :FrameOptions, 'rack/protection/frame_options'
|
15
|
+
autoload :HostAuthorization, 'rack/protection/host_authorization'
|
13
16
|
autoload :HttpOrigin, 'rack/protection/http_origin'
|
14
17
|
autoload :IPSpoofing, 'rack/protection/ip_spoofing'
|
15
18
|
autoload :JsonCsrf, 'rack/protection/json_csrf'
|
@@ -22,12 +25,11 @@ module Rack
|
|
22
25
|
autoload :XSSHeader, 'rack/protection/xss_header'
|
23
26
|
|
24
27
|
def self.new(app, options = {})
|
25
|
-
# does not include: RemoteReferrer, AuthenticityToken and FormToken
|
26
28
|
except = Array options[:except]
|
27
29
|
use_these = Array options[:use]
|
28
30
|
|
29
31
|
if options.fetch(:without_session, false)
|
30
|
-
except += [
|
32
|
+
except += %i[remote_token]
|
31
33
|
end
|
32
34
|
|
33
35
|
Rack::Builder.new do
|
@@ -39,6 +41,7 @@ module Rack
|
|
39
41
|
use ::Rack::Protection::FormToken, options if use_these.include? :form_token
|
40
42
|
use ::Rack::Protection::ReferrerPolicy, options if use_these.include? :referrer_policy
|
41
43
|
use ::Rack::Protection::RemoteReferrer, options if use_these.include? :remote_referrer
|
44
|
+
use ::Rack::Protection::SessionHijacking, options if use_these.include? :session_hijacking
|
42
45
|
use ::Rack::Protection::StrictTransport, options if use_these.include? :strict_transport
|
43
46
|
|
44
47
|
# On by default, unless skipped
|
@@ -48,7 +51,6 @@ module Rack
|
|
48
51
|
use ::Rack::Protection::JsonCsrf, options unless except.include? :json_csrf
|
49
52
|
use ::Rack::Protection::PathTraversal, options unless except.include? :path_traversal
|
50
53
|
use ::Rack::Protection::RemoteToken, options unless except.include? :remote_token
|
51
|
-
use ::Rack::Protection::SessionHijacking, options unless except.include? :session_hijacking
|
52
54
|
use ::Rack::Protection::XSSHeader, options unless except.include? :xss_header
|
53
55
|
run app
|
54
56
|
end.to_app
|
data/lib/rack-protection.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'rack/protection'
|
data/rack-protection.gemspec
CHANGED
@@ -1,40 +1,45 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
version = File.read(File.expand_path('../VERSION', __dir__)).strip
|
2
4
|
|
3
5
|
Gem::Specification.new do |s|
|
4
6
|
# general infos
|
5
|
-
s.name =
|
7
|
+
s.name = 'rack-protection'
|
6
8
|
s.version = version
|
7
|
-
s.description =
|
8
|
-
s.homepage =
|
9
|
-
s.summary = s.description
|
9
|
+
s.description = 'Protect against typical web attacks, works with all Rack apps, including Rails'
|
10
|
+
s.homepage = 'https://sinatrarb.com/protection/'
|
11
|
+
s.summary = "#{s.description}."
|
10
12
|
s.license = 'MIT'
|
11
|
-
s.authors = [
|
12
|
-
s.email =
|
13
|
-
s.files = Dir[
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
s.authors = ['https://github.com/sinatra/sinatra/graphs/contributors']
|
14
|
+
s.email = 'sinatrarb@googlegroups.com'
|
15
|
+
s.files = Dir['lib/**/*.rb'] + [
|
16
|
+
'License',
|
17
|
+
'README.md',
|
18
|
+
'Rakefile',
|
19
|
+
'Gemfile',
|
20
|
+
'rack-protection.gemspec'
|
19
21
|
]
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
'source_code_uri' => 'https://github.com/sinatra/sinatra/tree/master/rack-protection',
|
24
|
-
'homepage_uri' => 'http://sinatrarb.com/protection/',
|
25
|
-
'documentation_uri' => 'https://www.rubydoc.info/gems/rack-protection'
|
26
|
-
}
|
27
|
-
else
|
28
|
-
raise <<-EOF
|
23
|
+
unless s.respond_to?(:metadata)
|
24
|
+
raise <<-WARN
|
29
25
|
RubyGems 2.0 or newer is required to protect against public gem pushes. You can update your rubygems version by running:
|
30
26
|
gem install rubygems-update
|
31
27
|
update_rubygems:
|
32
28
|
gem update --system
|
33
|
-
|
29
|
+
WARN
|
34
30
|
end
|
35
31
|
|
32
|
+
s.metadata = {
|
33
|
+
'source_code_uri' => 'https://github.com/sinatra/sinatra/tree/main/rack-protection',
|
34
|
+
'homepage_uri' => 'http://sinatrarb.com/protection/',
|
35
|
+
'documentation_uri' => 'https://www.rubydoc.info/gems/rack-protection',
|
36
|
+
'rubygems_mfa_required' => 'true'
|
37
|
+
}
|
38
|
+
|
39
|
+
s.required_ruby_version = '>= 2.7.8'
|
40
|
+
|
36
41
|
# dependencies
|
37
|
-
s.add_dependency
|
38
|
-
s.
|
39
|
-
s.
|
42
|
+
s.add_dependency 'base64', '>= 0.1.0'
|
43
|
+
s.add_dependency 'logger', '>= 1.6.0'
|
44
|
+
s.add_dependency 'rack', '>= 3.0.0', '< 4'
|
40
45
|
end
|
metadata
CHANGED
@@ -1,59 +1,65 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-protection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/sinatra/sinatra/graphs/contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: base64
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: logger
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
34
|
-
type: :
|
33
|
+
version: 1.6.0
|
34
|
+
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 1.6.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rack
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.0.0
|
48
|
+
- - "<"
|
46
49
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
-
type: :
|
50
|
+
version: '4'
|
51
|
+
type: :runtime
|
49
52
|
prerelease: false
|
50
53
|
version_requirements: !ruby/object:Gem::Requirement
|
51
54
|
requirements:
|
52
|
-
- - "
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 3.0.0
|
58
|
+
- - "<"
|
53
59
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
60
|
+
version: '4'
|
55
61
|
description: Protect against typical web attacks, works with all Rack apps, including
|
56
|
-
Rails
|
62
|
+
Rails
|
57
63
|
email: sinatrarb@googlegroups.com
|
58
64
|
executables: []
|
59
65
|
extensions: []
|
@@ -72,6 +78,7 @@ files:
|
|
72
78
|
- lib/rack/protection/escaped_params.rb
|
73
79
|
- lib/rack/protection/form_token.rb
|
74
80
|
- lib/rack/protection/frame_options.rb
|
81
|
+
- lib/rack/protection/host_authorization.rb
|
75
82
|
- lib/rack/protection/http_origin.rb
|
76
83
|
- lib/rack/protection/ip_spoofing.rb
|
77
84
|
- lib/rack/protection/json_csrf.rb
|
@@ -83,14 +90,16 @@ files:
|
|
83
90
|
- lib/rack/protection/strict_transport.rb
|
84
91
|
- lib/rack/protection/version.rb
|
85
92
|
- lib/rack/protection/xss_header.rb
|
93
|
+
- lib/rack_protection.rb
|
86
94
|
- rack-protection.gemspec
|
87
|
-
homepage:
|
95
|
+
homepage: https://sinatrarb.com/protection/
|
88
96
|
licenses:
|
89
97
|
- MIT
|
90
98
|
metadata:
|
91
|
-
source_code_uri: https://github.com/sinatra/sinatra/tree/
|
99
|
+
source_code_uri: https://github.com/sinatra/sinatra/tree/main/rack-protection
|
92
100
|
homepage_uri: http://sinatrarb.com/protection/
|
93
101
|
documentation_uri: https://www.rubydoc.info/gems/rack-protection
|
102
|
+
rubygems_mfa_required: 'true'
|
94
103
|
post_install_message:
|
95
104
|
rdoc_options: []
|
96
105
|
require_paths:
|
@@ -99,14 +108,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
108
|
requirements:
|
100
109
|
- - ">="
|
101
110
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
111
|
+
version: 2.7.8
|
103
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
113
|
requirements:
|
105
114
|
- - ">="
|
106
115
|
- !ruby/object:Gem::Version
|
107
116
|
version: '0'
|
108
117
|
requirements: []
|
109
|
-
rubygems_version: 3.
|
118
|
+
rubygems_version: 3.5.22
|
110
119
|
signing_key:
|
111
120
|
specification_version: 4
|
112
121
|
summary: Protect against typical web attacks, works with all Rack apps, including
|