rack-protection 1.5.0 → 2.0.0
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 +7 -0
- data/Gemfile +13 -0
- data/License +4 -1
- data/README.md +24 -2
- data/Rakefile +21 -5
- data/lib/rack/protection/authenticity_token.rb +113 -5
- data/lib/rack/protection/base.rb +16 -2
- data/lib/rack/protection/content_security_policy.rb +80 -0
- data/lib/rack/protection/cookie_tossing.rb +75 -0
- data/lib/rack/protection/escaped_params.rb +2 -0
- data/lib/rack/protection/form_token.rb +1 -1
- data/lib/rack/protection/http_origin.rb +8 -0
- data/lib/rack/protection/json_csrf.rb +27 -5
- data/lib/rack/protection/path_traversal.rb +16 -5
- data/lib/rack/protection/remote_token.rb +1 -1
- data/lib/rack/protection/session_hijacking.rb +3 -3
- data/lib/rack/protection/strict_transport.rb +39 -0
- data/lib/rack/protection/version.rb +1 -12
- data/lib/rack/protection/xss_header.rb +1 -1
- data/lib/rack/protection.rb +38 -24
- data/rack-protection.gemspec +12 -81
- metadata +28 -77
- data/spec/authenticity_token_spec.rb +0 -33
- data/spec/escaped_params_spec.rb +0 -44
- data/spec/form_token_spec.rb +0 -33
- data/spec/frame_options_spec.rb +0 -39
- data/spec/http_origin_spec.rb +0 -38
- data/spec/ip_spoofing_spec.rb +0 -35
- data/spec/json_csrf_spec.rb +0 -44
- data/spec/path_traversal_spec.rb +0 -28
- data/spec/protection_spec.rb +0 -49
- data/spec/remote_referrer_spec.rb +0 -31
- data/spec/remote_token_spec.rb +0 -42
- data/spec/session_hijacking_spec.rb +0 -54
- data/spec/spec_helper.rb +0 -163
- data/spec/xss_header_spec.rb +0 -56
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'rack/protection'
|
|
2
|
+
|
|
3
|
+
module Rack
|
|
4
|
+
module Protection
|
|
5
|
+
##
|
|
6
|
+
# Prevented attack:: Protects against against protocol downgrade attacks and cookie hijacking.
|
|
7
|
+
# Supported browsers:: all
|
|
8
|
+
# More infos:: https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
|
|
9
|
+
#
|
|
10
|
+
# browser will prevent any communications from being sent over HTTP
|
|
11
|
+
# to the specified domain and will instead send all communications over HTTPS.
|
|
12
|
+
# It also prevents HTTPS click through prompts on browsers.
|
|
13
|
+
#
|
|
14
|
+
# Options:
|
|
15
|
+
#
|
|
16
|
+
# max_age:: How long future requests to the domain should go over HTTPS; specified in seconds
|
|
17
|
+
# include_subdomains:: If all present and future subdomains will be HTTPS
|
|
18
|
+
# preload:: Allow this domain to be included in browsers HSTS preload list. See https://hstspreload.appspot.com/
|
|
19
|
+
|
|
20
|
+
class StrictTransport < Base
|
|
21
|
+
default_options :max_age => 31_536_000, :include_subdomains => false, :preload => false
|
|
22
|
+
|
|
23
|
+
def strict_transport
|
|
24
|
+
@strict_transport ||= begin
|
|
25
|
+
strict_transport = 'max-age=' + options[:max_age].to_s
|
|
26
|
+
strict_transport += '; includeSubDomains' if options[:include_subdomains]
|
|
27
|
+
strict_transport += '; preload' if options[:preload]
|
|
28
|
+
strict_transport.to_str
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def call(env)
|
|
33
|
+
status, headers, body = @app.call(env)
|
|
34
|
+
headers['Strict-Transport-Security'] ||= strict_transport
|
|
35
|
+
[status, headers, body]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
module Rack
|
|
2
2
|
module Protection
|
|
3
|
-
|
|
4
|
-
VERSION
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
SIGNATURE = [1, 5, 0]
|
|
8
|
-
VERSION = SIGNATURE.join('.')
|
|
9
|
-
|
|
10
|
-
VERSION.extend Comparable
|
|
11
|
-
def VERSION.<=>(other)
|
|
12
|
-
other = other.split('.').map { |i| i.to_i } if other.respond_to? :split
|
|
13
|
-
SIGNATURE <=> Array(other)
|
|
14
|
-
end
|
|
3
|
+
VERSION = '2.0.0'
|
|
15
4
|
end
|
|
16
5
|
end
|
|
@@ -4,7 +4,7 @@ module Rack
|
|
|
4
4
|
module Protection
|
|
5
5
|
##
|
|
6
6
|
# Prevented attack:: Non-permanent XSS
|
|
7
|
-
# Supported browsers:: Internet Explorer 8 and
|
|
7
|
+
# Supported browsers:: Internet Explorer 8+ and Chrome
|
|
8
8
|
# More infos:: http://blogs.msdn.com/b/ie/archive/2008/07/01/ie8-security-part-iv-the-xss-filter.aspx
|
|
9
9
|
#
|
|
10
10
|
# Sets X-XSS-Protection header to tell the browser to block attacks.
|
data/lib/rack/protection.rb
CHANGED
|
@@ -3,36 +3,50 @@ require 'rack'
|
|
|
3
3
|
|
|
4
4
|
module Rack
|
|
5
5
|
module Protection
|
|
6
|
-
autoload :AuthenticityToken,
|
|
7
|
-
autoload :Base,
|
|
8
|
-
autoload :
|
|
9
|
-
autoload :
|
|
10
|
-
autoload :
|
|
11
|
-
autoload :
|
|
12
|
-
autoload :
|
|
13
|
-
autoload :
|
|
14
|
-
autoload :
|
|
15
|
-
autoload :
|
|
16
|
-
autoload :
|
|
17
|
-
autoload :
|
|
18
|
-
autoload :
|
|
6
|
+
autoload :AuthenticityToken, 'rack/protection/authenticity_token'
|
|
7
|
+
autoload :Base, 'rack/protection/base'
|
|
8
|
+
autoload :CookieTossing, 'rack/protection/cookie_tossing'
|
|
9
|
+
autoload :ContentSecurityPolicy, 'rack/protection/content_security_policy'
|
|
10
|
+
autoload :EscapedParams, 'rack/protection/escaped_params'
|
|
11
|
+
autoload :FormToken, 'rack/protection/form_token'
|
|
12
|
+
autoload :FrameOptions, 'rack/protection/frame_options'
|
|
13
|
+
autoload :HttpOrigin, 'rack/protection/http_origin'
|
|
14
|
+
autoload :IPSpoofing, 'rack/protection/ip_spoofing'
|
|
15
|
+
autoload :JsonCsrf, 'rack/protection/json_csrf'
|
|
16
|
+
autoload :PathTraversal, 'rack/protection/path_traversal'
|
|
17
|
+
autoload :RemoteReferrer, 'rack/protection/remote_referrer'
|
|
18
|
+
autoload :RemoteToken, 'rack/protection/remote_token'
|
|
19
|
+
autoload :SessionHijacking, 'rack/protection/session_hijacking'
|
|
20
|
+
autoload :StrictTransport, 'rack/protection/strict_transport'
|
|
21
|
+
autoload :XSSHeader, 'rack/protection/xss_header'
|
|
19
22
|
|
|
20
23
|
def self.new(app, options = {})
|
|
21
24
|
# does not include: RemoteReferrer, AuthenticityToken and FormToken
|
|
22
25
|
except = Array options[:except]
|
|
23
26
|
use_these = Array options[:use]
|
|
27
|
+
|
|
28
|
+
if options.fetch(:without_session, false)
|
|
29
|
+
except += [:session_hijacking, :remote_token]
|
|
30
|
+
end
|
|
31
|
+
|
|
24
32
|
Rack::Builder.new do
|
|
25
|
-
|
|
26
|
-
use ::Rack::Protection::AuthenticityToken,options if use_these.include? :authenticity_token
|
|
27
|
-
use ::Rack::Protection::
|
|
28
|
-
use ::Rack::Protection::
|
|
29
|
-
use ::Rack::Protection::
|
|
30
|
-
use ::Rack::Protection::
|
|
31
|
-
use ::Rack::Protection::
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
use ::Rack::Protection::
|
|
35
|
-
use ::Rack::Protection::
|
|
33
|
+
# Off by default, unless added
|
|
34
|
+
use ::Rack::Protection::AuthenticityToken, options if use_these.include? :authenticity_token
|
|
35
|
+
use ::Rack::Protection::CookieTossing, options if use_these.include? :cookie_tossing
|
|
36
|
+
use ::Rack::Protection::ContentSecurityPolicy, options if use_these.include? :content_security_policy
|
|
37
|
+
use ::Rack::Protection::FormToken, options if use_these.include? :form_token
|
|
38
|
+
use ::Rack::Protection::RemoteReferrer, options if use_these.include? :remote_referrer
|
|
39
|
+
use ::Rack::Protection::StrictTransport, options if use_these.include? :strict_transport
|
|
40
|
+
|
|
41
|
+
# On by default, unless skipped
|
|
42
|
+
use ::Rack::Protection::FrameOptions, options unless except.include? :frame_options
|
|
43
|
+
use ::Rack::Protection::HttpOrigin, options unless except.include? :http_origin
|
|
44
|
+
use ::Rack::Protection::IPSpoofing, options unless except.include? :ip_spoofing
|
|
45
|
+
use ::Rack::Protection::JsonCsrf, options unless except.include? :json_csrf
|
|
46
|
+
use ::Rack::Protection::PathTraversal, options unless except.include? :path_traversal
|
|
47
|
+
use ::Rack::Protection::RemoteToken, options unless except.include? :remote_token
|
|
48
|
+
use ::Rack::Protection::SessionHijacking, options unless except.include? :session_hijacking
|
|
49
|
+
use ::Rack::Protection::XSSHeader, options unless except.include? :xss_header
|
|
36
50
|
run app
|
|
37
51
|
end.to_app
|
|
38
52
|
end
|
data/rack-protection.gemspec
CHANGED
|
@@ -1,94 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
version = File.read(File.expand_path("../../VERSION", __FILE__)).strip
|
|
2
|
+
|
|
2
3
|
Gem::Specification.new do |s|
|
|
3
4
|
# general infos
|
|
4
5
|
s.name = "rack-protection"
|
|
5
|
-
s.version =
|
|
6
|
-
s.description = "
|
|
7
|
-
s.homepage = "http://github.com/
|
|
6
|
+
s.version = version
|
|
7
|
+
s.description = "Protect against typical web attacks, works with all Rack apps, including Rails."
|
|
8
|
+
s.homepage = "http://github.com/sinatra/sinatra/tree/master/rack-protection"
|
|
8
9
|
s.summary = s.description
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
s.
|
|
12
|
-
|
|
13
|
-
"Alex Rodionov",
|
|
14
|
-
"Chris Heald",
|
|
15
|
-
"Chris Mytton",
|
|
16
|
-
"Corey Ward",
|
|
17
|
-
"David Kellum",
|
|
18
|
-
"Egor Homakov",
|
|
19
|
-
"Florian Gilcher",
|
|
20
|
-
"Fojas",
|
|
21
|
-
"Mael Clerambault",
|
|
22
|
-
"Martin Mauch",
|
|
23
|
-
"SAKAI, Kazuaki",
|
|
24
|
-
"Stanislav Savulchik",
|
|
25
|
-
"Steve Agalloco",
|
|
26
|
-
"Akzhan Abdulin",
|
|
27
|
-
"TOBY",
|
|
28
|
-
"Bj\u00F8rge N\u00E6ss"
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
# generated from git shortlog -sne
|
|
32
|
-
s.email = [
|
|
33
|
-
"konstantin.mailinglists@googlemail.com",
|
|
34
|
-
"p0deje@gmail.com",
|
|
35
|
-
"self@hecticjeff.net",
|
|
36
|
-
"coreyward@me.com",
|
|
37
|
-
"dek-oss@gravitext.com",
|
|
38
|
-
"homakov@gmail.com",
|
|
39
|
-
"florian.gilcher@asquera.de",
|
|
40
|
-
"developer@fojasaur.us",
|
|
41
|
-
"mael@clerambault.fr",
|
|
42
|
-
"martin.mauch@gmail.com",
|
|
43
|
-
"kaz.july.7@gmail.com",
|
|
44
|
-
"s.savulchik@gmail.com",
|
|
45
|
-
"steve.agalloco@gmail.com",
|
|
46
|
-
"akzhan.abdulin@gmail.com",
|
|
47
|
-
"toby.net.info.mail+git@gmail.com",
|
|
48
|
-
"bjoerge@bengler.no",
|
|
49
|
-
"cheald@gmail.com"
|
|
50
|
-
]
|
|
51
|
-
|
|
52
|
-
# generated from git ls-files
|
|
53
|
-
s.files = [
|
|
10
|
+
s.license = 'MIT'
|
|
11
|
+
s.authors = ["https://github.com/sinatra/sinatra/graphs/contributors"]
|
|
12
|
+
s.email = "sinatrarb@googlegroups.com"
|
|
13
|
+
s.files = Dir["lib/**/*.rb"] + [
|
|
54
14
|
"License",
|
|
55
15
|
"README.md",
|
|
56
16
|
"Rakefile",
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"lib/rack/protection/authenticity_token.rb",
|
|
60
|
-
"lib/rack/protection/base.rb",
|
|
61
|
-
"lib/rack/protection/escaped_params.rb",
|
|
62
|
-
"lib/rack/protection/form_token.rb",
|
|
63
|
-
"lib/rack/protection/frame_options.rb",
|
|
64
|
-
"lib/rack/protection/http_origin.rb",
|
|
65
|
-
"lib/rack/protection/ip_spoofing.rb",
|
|
66
|
-
"lib/rack/protection/json_csrf.rb",
|
|
67
|
-
"lib/rack/protection/path_traversal.rb",
|
|
68
|
-
"lib/rack/protection/remote_referrer.rb",
|
|
69
|
-
"lib/rack/protection/remote_token.rb",
|
|
70
|
-
"lib/rack/protection/session_hijacking.rb",
|
|
71
|
-
"lib/rack/protection/version.rb",
|
|
72
|
-
"lib/rack/protection/xss_header.rb",
|
|
73
|
-
"rack-protection.gemspec",
|
|
74
|
-
"spec/authenticity_token_spec.rb",
|
|
75
|
-
"spec/escaped_params_spec.rb",
|
|
76
|
-
"spec/form_token_spec.rb",
|
|
77
|
-
"spec/frame_options_spec.rb",
|
|
78
|
-
"spec/http_origin_spec.rb",
|
|
79
|
-
"spec/ip_spoofing_spec.rb",
|
|
80
|
-
"spec/json_csrf_spec.rb",
|
|
81
|
-
"spec/path_traversal_spec.rb",
|
|
82
|
-
"spec/protection_spec.rb",
|
|
83
|
-
"spec/remote_referrer_spec.rb",
|
|
84
|
-
"spec/remote_token_spec.rb",
|
|
85
|
-
"spec/session_hijacking_spec.rb",
|
|
86
|
-
"spec/spec_helper.rb",
|
|
87
|
-
"spec/xss_header_spec.rb"
|
|
17
|
+
"Gemfile",
|
|
18
|
+
"rack-protection.gemspec"
|
|
88
19
|
]
|
|
89
20
|
|
|
90
21
|
# dependencies
|
|
91
22
|
s.add_dependency "rack"
|
|
92
23
|
s.add_development_dependency "rack-test"
|
|
93
|
-
s.add_development_dependency "rspec", "~>
|
|
24
|
+
s.add_development_dependency "rspec", "~> 3.0.0"
|
|
94
25
|
end
|
metadata
CHANGED
|
@@ -1,103 +1,65 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-protection
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 2.0.0
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
|
-
-
|
|
9
|
-
- Alex Rodionov
|
|
10
|
-
- Chris Heald
|
|
11
|
-
- Chris Mytton
|
|
12
|
-
- Corey Ward
|
|
13
|
-
- David Kellum
|
|
14
|
-
- Egor Homakov
|
|
15
|
-
- Florian Gilcher
|
|
16
|
-
- Fojas
|
|
17
|
-
- Mael Clerambault
|
|
18
|
-
- Martin Mauch
|
|
19
|
-
- SAKAI, Kazuaki
|
|
20
|
-
- Stanislav Savulchik
|
|
21
|
-
- Steve Agalloco
|
|
22
|
-
- Akzhan Abdulin
|
|
23
|
-
- TOBY
|
|
24
|
-
- Bjørge Næss
|
|
7
|
+
- https://github.com/sinatra/sinatra/graphs/contributors
|
|
25
8
|
autorequire:
|
|
26
9
|
bindir: bin
|
|
27
10
|
cert_chain: []
|
|
28
|
-
date:
|
|
11
|
+
date: 2017-05-07 00:00:00.000000000 Z
|
|
29
12
|
dependencies:
|
|
30
13
|
- !ruby/object:Gem::Dependency
|
|
31
14
|
name: rack
|
|
32
15
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
-
none: false
|
|
34
16
|
requirements:
|
|
35
|
-
- -
|
|
17
|
+
- - ">="
|
|
36
18
|
- !ruby/object:Gem::Version
|
|
37
19
|
version: '0'
|
|
38
20
|
type: :runtime
|
|
39
21
|
prerelease: false
|
|
40
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
none: false
|
|
42
23
|
requirements:
|
|
43
|
-
- -
|
|
24
|
+
- - ">="
|
|
44
25
|
- !ruby/object:Gem::Version
|
|
45
26
|
version: '0'
|
|
46
27
|
- !ruby/object:Gem::Dependency
|
|
47
28
|
name: rack-test
|
|
48
29
|
requirement: !ruby/object:Gem::Requirement
|
|
49
|
-
none: false
|
|
50
30
|
requirements:
|
|
51
|
-
- -
|
|
31
|
+
- - ">="
|
|
52
32
|
- !ruby/object:Gem::Version
|
|
53
33
|
version: '0'
|
|
54
34
|
type: :development
|
|
55
35
|
prerelease: false
|
|
56
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
none: false
|
|
58
37
|
requirements:
|
|
59
|
-
- -
|
|
38
|
+
- - ">="
|
|
60
39
|
- !ruby/object:Gem::Version
|
|
61
40
|
version: '0'
|
|
62
41
|
- !ruby/object:Gem::Dependency
|
|
63
42
|
name: rspec
|
|
64
43
|
requirement: !ruby/object:Gem::Requirement
|
|
65
|
-
none: false
|
|
66
44
|
requirements:
|
|
67
|
-
- - ~>
|
|
45
|
+
- - "~>"
|
|
68
46
|
- !ruby/object:Gem::Version
|
|
69
|
-
version:
|
|
47
|
+
version: 3.0.0
|
|
70
48
|
type: :development
|
|
71
49
|
prerelease: false
|
|
72
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
-
none: false
|
|
74
51
|
requirements:
|
|
75
|
-
- - ~>
|
|
52
|
+
- - "~>"
|
|
76
53
|
- !ruby/object:Gem::Version
|
|
77
|
-
version:
|
|
78
|
-
description:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
- p0deje@gmail.com
|
|
82
|
-
- self@hecticjeff.net
|
|
83
|
-
- coreyward@me.com
|
|
84
|
-
- dek-oss@gravitext.com
|
|
85
|
-
- homakov@gmail.com
|
|
86
|
-
- florian.gilcher@asquera.de
|
|
87
|
-
- developer@fojasaur.us
|
|
88
|
-
- mael@clerambault.fr
|
|
89
|
-
- martin.mauch@gmail.com
|
|
90
|
-
- kaz.july.7@gmail.com
|
|
91
|
-
- s.savulchik@gmail.com
|
|
92
|
-
- steve.agalloco@gmail.com
|
|
93
|
-
- akzhan.abdulin@gmail.com
|
|
94
|
-
- toby.net.info.mail+git@gmail.com
|
|
95
|
-
- bjoerge@bengler.no
|
|
96
|
-
- cheald@gmail.com
|
|
54
|
+
version: 3.0.0
|
|
55
|
+
description: Protect against typical web attacks, works with all Rack apps, including
|
|
56
|
+
Rails.
|
|
57
|
+
email: sinatrarb@googlegroups.com
|
|
97
58
|
executables: []
|
|
98
59
|
extensions: []
|
|
99
60
|
extra_rdoc_files: []
|
|
100
61
|
files:
|
|
62
|
+
- Gemfile
|
|
101
63
|
- License
|
|
102
64
|
- README.md
|
|
103
65
|
- Rakefile
|
|
@@ -105,6 +67,8 @@ files:
|
|
|
105
67
|
- lib/rack/protection.rb
|
|
106
68
|
- lib/rack/protection/authenticity_token.rb
|
|
107
69
|
- lib/rack/protection/base.rb
|
|
70
|
+
- lib/rack/protection/content_security_policy.rb
|
|
71
|
+
- lib/rack/protection/cookie_tossing.rb
|
|
108
72
|
- lib/rack/protection/escaped_params.rb
|
|
109
73
|
- lib/rack/protection/form_token.rb
|
|
110
74
|
- lib/rack/protection/frame_options.rb
|
|
@@ -115,46 +79,33 @@ files:
|
|
|
115
79
|
- lib/rack/protection/remote_referrer.rb
|
|
116
80
|
- lib/rack/protection/remote_token.rb
|
|
117
81
|
- lib/rack/protection/session_hijacking.rb
|
|
82
|
+
- lib/rack/protection/strict_transport.rb
|
|
118
83
|
- lib/rack/protection/version.rb
|
|
119
84
|
- lib/rack/protection/xss_header.rb
|
|
120
85
|
- rack-protection.gemspec
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
|
|
125
|
-
- spec/http_origin_spec.rb
|
|
126
|
-
- spec/ip_spoofing_spec.rb
|
|
127
|
-
- spec/json_csrf_spec.rb
|
|
128
|
-
- spec/path_traversal_spec.rb
|
|
129
|
-
- spec/protection_spec.rb
|
|
130
|
-
- spec/remote_referrer_spec.rb
|
|
131
|
-
- spec/remote_token_spec.rb
|
|
132
|
-
- spec/session_hijacking_spec.rb
|
|
133
|
-
- spec/spec_helper.rb
|
|
134
|
-
- spec/xss_header_spec.rb
|
|
135
|
-
homepage: http://github.com/rkh/rack-protection
|
|
136
|
-
licenses: []
|
|
86
|
+
homepage: http://github.com/sinatra/sinatra/tree/master/rack-protection
|
|
87
|
+
licenses:
|
|
88
|
+
- MIT
|
|
89
|
+
metadata: {}
|
|
137
90
|
post_install_message:
|
|
138
91
|
rdoc_options: []
|
|
139
92
|
require_paths:
|
|
140
93
|
- lib
|
|
141
94
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
|
-
none: false
|
|
143
95
|
requirements:
|
|
144
|
-
- -
|
|
96
|
+
- - ">="
|
|
145
97
|
- !ruby/object:Gem::Version
|
|
146
98
|
version: '0'
|
|
147
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
|
-
none: false
|
|
149
100
|
requirements:
|
|
150
|
-
- -
|
|
101
|
+
- - ">="
|
|
151
102
|
- !ruby/object:Gem::Version
|
|
152
103
|
version: '0'
|
|
153
104
|
requirements: []
|
|
154
105
|
rubyforge_project:
|
|
155
|
-
rubygems_version:
|
|
106
|
+
rubygems_version: 2.6.11
|
|
156
107
|
signing_key:
|
|
157
|
-
specification_version:
|
|
158
|
-
summary:
|
|
108
|
+
specification_version: 4
|
|
109
|
+
summary: Protect against typical web attacks, works with all Rack apps, including
|
|
110
|
+
Rails.
|
|
159
111
|
test_files: []
|
|
160
|
-
has_rdoc:
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
2
|
-
|
|
3
|
-
describe Rack::Protection::AuthenticityToken do
|
|
4
|
-
it_behaves_like "any rack application"
|
|
5
|
-
|
|
6
|
-
it "denies post requests without any token" do
|
|
7
|
-
post('/').should_not be_ok
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "accepts post requests with correct X-CSRF-Token header" do
|
|
11
|
-
post('/', {}, 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "a")
|
|
12
|
-
last_response.should be_ok
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "denies post requests with wrong X-CSRF-Token header" do
|
|
16
|
-
post('/', {}, 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "b")
|
|
17
|
-
last_response.should_not be_ok
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "accepts post form requests with correct authenticity_token field" do
|
|
21
|
-
post('/', {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "a"})
|
|
22
|
-
last_response.should be_ok
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "denies post form requests with wrong authenticity_token field" do
|
|
26
|
-
post('/', {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "b"})
|
|
27
|
-
last_response.should_not be_ok
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "prevents ajax requests without a valid token" do
|
|
31
|
-
post('/', {}, "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest").should_not be_ok
|
|
32
|
-
end
|
|
33
|
-
end
|
data/spec/escaped_params_spec.rb
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
2
|
-
|
|
3
|
-
describe Rack::Protection::EscapedParams do
|
|
4
|
-
it_behaves_like "any rack application"
|
|
5
|
-
|
|
6
|
-
context 'escaping' do
|
|
7
|
-
it 'escapes html entities' do
|
|
8
|
-
mock_app do |env|
|
|
9
|
-
request = Rack::Request.new(env)
|
|
10
|
-
[200, {'Content-Type' => 'text/plain'}, [request.params['foo']]]
|
|
11
|
-
end
|
|
12
|
-
get '/', :foo => "<bar>"
|
|
13
|
-
body.should == '<bar>'
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'leaves normal params untouched' do
|
|
17
|
-
mock_app do |env|
|
|
18
|
-
request = Rack::Request.new(env)
|
|
19
|
-
[200, {'Content-Type' => 'text/plain'}, [request.params['foo']]]
|
|
20
|
-
end
|
|
21
|
-
get '/', :foo => "bar"
|
|
22
|
-
body.should == 'bar'
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it 'copes with nested arrays' do
|
|
26
|
-
mock_app do |env|
|
|
27
|
-
request = Rack::Request.new(env)
|
|
28
|
-
[200, {'Content-Type' => 'text/plain'}, [request.params['foo']['bar']]]
|
|
29
|
-
end
|
|
30
|
-
get '/', :foo => {:bar => "<bar>"}
|
|
31
|
-
body.should == '<bar>'
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it 'leaves cache-breaker params untouched' do
|
|
35
|
-
mock_app do |env|
|
|
36
|
-
request = Rack::Request.new(env)
|
|
37
|
-
[200, {'Content-Type' => 'text/plain'}, ['hi']]
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
get '/?95df8d9bf5237ad08df3115ee74dcb10'
|
|
41
|
-
body.should == 'hi'
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
data/spec/form_token_spec.rb
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
2
|
-
|
|
3
|
-
describe Rack::Protection::FormToken do
|
|
4
|
-
it_behaves_like "any rack application"
|
|
5
|
-
|
|
6
|
-
it "denies post requests without any token" do
|
|
7
|
-
post('/').should_not be_ok
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "accepts post requests with correct X-CSRF-Token header" do
|
|
11
|
-
post('/', {}, 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "a")
|
|
12
|
-
last_response.should be_ok
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "denies post requests with wrong X-CSRF-Token header" do
|
|
16
|
-
post('/', {}, 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "b")
|
|
17
|
-
last_response.should_not be_ok
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "accepts post form requests with correct authenticity_token field" do
|
|
21
|
-
post('/', {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "a"})
|
|
22
|
-
last_response.should be_ok
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "denies post form requests with wrong authenticity_token field" do
|
|
26
|
-
post('/', {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "b"})
|
|
27
|
-
last_response.should_not be_ok
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "accepts ajax requests without a valid token" do
|
|
31
|
-
post('/', {}, "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest").should be_ok
|
|
32
|
-
end
|
|
33
|
-
end
|
data/spec/frame_options_spec.rb
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
2
|
-
|
|
3
|
-
describe Rack::Protection::FrameOptions do
|
|
4
|
-
it_behaves_like "any rack application"
|
|
5
|
-
|
|
6
|
-
it 'should set the X-Frame-Options' do
|
|
7
|
-
get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "SAMEORIGIN"
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it 'should not set the X-Frame-Options for other content types' do
|
|
11
|
-
get('/', {}, 'wants' => 'text/foo').headers["X-Frame-Options"].should be_nil
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it 'should allow changing the protection mode' do
|
|
15
|
-
# I have no clue what other modes are available
|
|
16
|
-
mock_app do
|
|
17
|
-
use Rack::Protection::FrameOptions, :frame_options => :deny
|
|
18
|
-
run DummyApp
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "DENY"
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
it 'should allow changing the protection mode to a string' do
|
|
26
|
-
# I have no clue what other modes are available
|
|
27
|
-
mock_app do
|
|
28
|
-
use Rack::Protection::FrameOptions, :frame_options => "ALLOW-FROM foo"
|
|
29
|
-
run DummyApp
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "ALLOW-FROM foo"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it 'should not override the header if already set' do
|
|
36
|
-
mock_app with_headers("X-Frame-Options" => "allow")
|
|
37
|
-
get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "allow"
|
|
38
|
-
end
|
|
39
|
-
end
|
data/spec/http_origin_spec.rb
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
2
|
-
|
|
3
|
-
describe Rack::Protection::HttpOrigin do
|
|
4
|
-
it_behaves_like "any rack application"
|
|
5
|
-
|
|
6
|
-
before(:each) do
|
|
7
|
-
mock_app do
|
|
8
|
-
use Rack::Protection::HttpOrigin
|
|
9
|
-
run DummyApp
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
%w(GET HEAD POST PUT DELETE).each do |method|
|
|
14
|
-
it "accepts #{method} requests with no Origin" do
|
|
15
|
-
send(method.downcase, '/').should be_ok
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
%w(GET HEAD).each do |method|
|
|
20
|
-
it "accepts #{method} requests with non-whitelisted Origin" do
|
|
21
|
-
send(method.downcase, '/', {}, 'HTTP_ORIGIN' => 'http://malicious.com').should be_ok
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
%w(POST PUT DELETE).each do |method|
|
|
26
|
-
it "denies #{method} requests with non-whitelisted Origin" do
|
|
27
|
-
send(method.downcase, '/', {}, 'HTTP_ORIGIN' => 'http://malicious.com').should_not be_ok
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "accepts #{method} requests with whitelisted Origin" do
|
|
31
|
-
mock_app do
|
|
32
|
-
use Rack::Protection::HttpOrigin, :origin_whitelist => ['http://www.friend.com']
|
|
33
|
-
run DummyApp
|
|
34
|
-
end
|
|
35
|
-
send(method.downcase, '/', {}, 'HTTP_ORIGIN' => 'http://www.friend.com').should be_ok
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
data/spec/ip_spoofing_spec.rb
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
2
|
-
|
|
3
|
-
describe Rack::Protection::IPSpoofing do
|
|
4
|
-
it_behaves_like "any rack application"
|
|
5
|
-
|
|
6
|
-
it 'accepts requests without X-Forward-For header' do
|
|
7
|
-
get('/', {}, 'HTTP_CLIENT_IP' => '1.2.3.4', 'HTTP_X_REAL_IP' => '4.3.2.1')
|
|
8
|
-
last_response.should be_ok
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it 'accepts requests with proper X-Forward-For header' do
|
|
12
|
-
get('/', {}, 'HTTP_CLIENT_IP' => '1.2.3.4',
|
|
13
|
-
'HTTP_X_FORWARDED_FOR' => '192.168.1.20, 1.2.3.4, 127.0.0.1')
|
|
14
|
-
last_response.should be_ok
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'denies requests where the client spoofs X-Forward-For but not the IP' do
|
|
18
|
-
get('/', {}, 'HTTP_CLIENT_IP' => '1.2.3.4', 'HTTP_X_FORWARDED_FOR' => '1.2.3.5')
|
|
19
|
-
last_response.should_not be_ok
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it 'denies requests where the client spoofs the IP but not X-Forward-For' do
|
|
23
|
-
get('/', {}, 'HTTP_CLIENT_IP' => '1.2.3.5',
|
|
24
|
-
'HTTP_X_FORWARDED_FOR' => '192.168.1.20, 1.2.3.4, 127.0.0.1')
|
|
25
|
-
last_response.should_not be_ok
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'denies requests where IP and X-Forward-For are spoofed but not X-Real-IP' do
|
|
29
|
-
get('/', {},
|
|
30
|
-
'HTTP_CLIENT_IP' => '1.2.3.5',
|
|
31
|
-
'HTTP_X_FORWARDED_FOR' => '1.2.3.5',
|
|
32
|
-
'HTTP_X_REAL_IP' => '1.2.3.4')
|
|
33
|
-
last_response.should_not be_ok
|
|
34
|
-
end
|
|
35
|
-
end
|