rack-protection 1.3.2 → 1.4.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.
Potentially problematic release.
This version of rack-protection might be problematic. Click here for more details.
- data/README.md +1 -1
- data/Rakefile +7 -4
- data/lib/rack/protection.rb +4 -0
- data/lib/rack/protection/frame_options.rb +10 -4
- data/lib/rack/protection/json_csrf.rb +13 -6
- data/lib/rack/protection/remote_referrer.rb +0 -3
- data/lib/rack/protection/version.rb +1 -1
- data/lib/rack/protection/xss_header.rb +2 -10
- data/rack-protection.gemspec +4 -2
- data/spec/json_csrf_spec.rb +4 -0
- data/spec/xss_header_spec.rb +6 -0
- metadata +77 -60
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -14,15 +14,18 @@ task(:spec) { ruby '-S rspec spec' }
|
|
14
14
|
desc "generate gemspec"
|
15
15
|
task 'rack-protection.gemspec' do
|
16
16
|
require 'rack/protection/version'
|
17
|
-
content = File.
|
17
|
+
content = File.binread 'rack-protection.gemspec'
|
18
18
|
|
19
19
|
# fetch data
|
20
20
|
fields = {
|
21
|
-
:authors => `git shortlog -sn`.scan(/[^\d\s].*/),
|
22
|
-
:email => `git shortlog -sne`.scan(/[^<]+@[^>]+/),
|
23
|
-
:files => `git ls-files`.split("\n").reject { |f| f =~ /^(\.|Gemfile)/ }
|
21
|
+
:authors => `git shortlog -sn`.force_encoding('utf-8').scan(/[^\d\s].*/),
|
22
|
+
:email => `git shortlog -sne`.force_encoding('utf-8').scan(/[^<]+@[^>]+/),
|
23
|
+
:files => `git ls-files`.force_encoding('utf-8').split("\n").reject { |f| f =~ /^(\.|Gemfile)/ }
|
24
24
|
}
|
25
25
|
|
26
|
+
# double email :(
|
27
|
+
fields[:email].delete("konstantin.haase@gmail.com")
|
28
|
+
|
26
29
|
# insert data
|
27
30
|
fields.each do |field, values|
|
28
31
|
updated = " s.#{field} = ["
|
data/lib/rack/protection.rb
CHANGED
@@ -20,7 +20,11 @@ module Rack
|
|
20
20
|
def self.new(app, options = {})
|
21
21
|
# does not include: RemoteReferrer, AuthenticityToken and FormToken
|
22
22
|
except = Array options[:except]
|
23
|
+
use_these = Array options[:use]
|
23
24
|
Rack::Builder.new do
|
25
|
+
use ::Rack::Protection::RemoteReferrer, options if use_these.include? :remote_referrer
|
26
|
+
use ::Rack::Protection::AuthenticityToken,options if use_these.include? :authenticity_token
|
27
|
+
use ::Rack::Protection::FormToken, options if use_these.include? :form_token
|
24
28
|
use ::Rack::Protection::FrameOptions, options unless except.include? :frame_options
|
25
29
|
use ::Rack::Protection::HttpOrigin, options unless except.include? :http_origin
|
26
30
|
use ::Rack::Protection::IPSpoofing, options unless except.include? :ip_spoofing
|
@@ -16,16 +16,22 @@ module Rack
|
|
16
16
|
# frame_options:: Defines who should be allowed to embed the page in a
|
17
17
|
# frame. Use :deny to forbid any embedding, :sameorigin
|
18
18
|
# to allow embedding from the same origin (default).
|
19
|
-
class FrameOptions <
|
19
|
+
class FrameOptions < Base
|
20
20
|
default_options :frame_options => :sameorigin
|
21
21
|
|
22
|
-
def
|
23
|
-
@
|
22
|
+
def frame_options
|
23
|
+
@frame_options ||= begin
|
24
24
|
frame_options = options[:frame_options]
|
25
25
|
frame_options = options[:frame_options].to_s.upcase unless frame_options.respond_to? :to_str
|
26
|
-
|
26
|
+
frame_options.to_str
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
def call(env)
|
31
|
+
status, headers, body = @app.call(env)
|
32
|
+
headers['X-Frame-Options'] ||= frame_options if html? headers
|
33
|
+
[status, headers, body]
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
@@ -14,14 +14,21 @@ module Rack
|
|
14
14
|
default_reaction :deny
|
15
15
|
|
16
16
|
def call(env)
|
17
|
+
request = Request.new(env)
|
17
18
|
status, headers, body = app.call(env)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
|
20
|
+
if has_vector? request, headers
|
21
|
+
warn env, "attack prevented by #{self.class}"
|
22
|
+
react(env)
|
23
|
+
else
|
24
|
+
[status, headers, body]
|
23
25
|
end
|
24
|
-
|
26
|
+
end
|
27
|
+
|
28
|
+
def has_vector?(request, headers)
|
29
|
+
return false if request.xhr?
|
30
|
+
return false unless headers['Content-Type'].to_s.split(';', 2).first =~ /^\s*application\/json\s*$/
|
31
|
+
origin(request.env).nil? and referrer(request.env) != request.host
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
@@ -9,9 +9,6 @@ module Rack
|
|
9
9
|
#
|
10
10
|
# Does not accept unsafe HTTP requests if the Referer [sic] header is set to
|
11
11
|
# a different host.
|
12
|
-
#
|
13
|
-
# Combine with NoReferrer to also block remote requests from non-HTTP pages
|
14
|
-
# (FTP/HTTPS/...).
|
15
12
|
class RemoteReferrer < Base
|
16
13
|
default_reaction :deny
|
17
14
|
|
@@ -14,18 +14,10 @@ module Rack
|
|
14
14
|
class XSSHeader < Base
|
15
15
|
default_options :xss_mode => :block, :nosniff => true
|
16
16
|
|
17
|
-
def header
|
18
|
-
headers = {
|
19
|
-
'X-XSS-Protection' => "1; mode=#{options[:xss_mode]}",
|
20
|
-
'X-Content-Type-Options' => "nosniff"
|
21
|
-
}
|
22
|
-
headers.delete("X-Content-Type-Options") unless options[:nosniff]
|
23
|
-
headers
|
24
|
-
end
|
25
|
-
|
26
17
|
def call(env)
|
27
18
|
status, headers, body = @app.call(env)
|
28
|
-
headers
|
19
|
+
headers['X-XSS-Protection'] ||= "1; mode=#{options[:xss_mode]}" if html? headers
|
20
|
+
headers['X-Content-Type-Options'] ||= 'nosniff' if options[:nosniff]
|
29
21
|
[status, headers, body]
|
30
22
|
end
|
31
23
|
end
|
data/rack-protection.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
# general infos
|
4
4
|
s.name = "rack-protection"
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.4.0"
|
6
6
|
s.description = "You should use protection!"
|
7
7
|
s.homepage = "http://github.com/rkh/rack-protection"
|
8
8
|
s.summary = s.description
|
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
"Chris Mytton",
|
16
16
|
"Corey Ward",
|
17
17
|
"David Kellum",
|
18
|
+
"Egor Homakov",
|
18
19
|
"Fojas",
|
19
20
|
"Mael Clerambault",
|
20
21
|
"Martin Mauch",
|
@@ -23,7 +24,7 @@ Gem::Specification.new do |s|
|
|
23
24
|
"Steve Agalloco",
|
24
25
|
"Akzhan Abdulin",
|
25
26
|
"TOBY",
|
26
|
-
"Bj\
|
27
|
+
"Bj\u00F8rge N\u00E6ss"
|
27
28
|
]
|
28
29
|
|
29
30
|
# generated from git shortlog -sne
|
@@ -34,6 +35,7 @@ Gem::Specification.new do |s|
|
|
34
35
|
"self@hecticjeff.net",
|
35
36
|
"coreyward@me.com",
|
36
37
|
"dek-oss@gravitext.com",
|
38
|
+
"homakov@gmail.com",
|
37
39
|
"developer@fojasaur.us",
|
38
40
|
"mael@clerambault.fr",
|
39
41
|
"martin.mauch@gmail.com",
|
data/spec/json_csrf_spec.rb
CHANGED
@@ -27,6 +27,10 @@ describe Rack::Protection::JsonCsrf do
|
|
27
27
|
it "accepts get requests with json responses with no referrer" do
|
28
28
|
get('/', {}).should be_ok
|
29
29
|
end
|
30
|
+
|
31
|
+
it "accepts XHR requests" do
|
32
|
+
get('/', {}, 'HTTP_REFERER' => 'http://evil.com', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest').should be_ok
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
describe 'not json response' do
|
data/spec/xss_header_spec.rb
CHANGED
@@ -34,6 +34,12 @@ describe Rack::Protection::XSSHeader do
|
|
34
34
|
get('/', {}, 'wants' => 'text/html').header["X-Content-Type-Options"].should == "nosniff"
|
35
35
|
end
|
36
36
|
|
37
|
+
|
38
|
+
it 'should set the X-Content-Type-Options for other content types' do
|
39
|
+
get('/', {}, 'wants' => 'application/foo').header["X-Content-Type-Options"].should == "nosniff"
|
40
|
+
end
|
41
|
+
|
42
|
+
|
37
43
|
it 'should allow changing the nosniff-mode off' do
|
38
44
|
mock_app do
|
39
45
|
use Rack::Protection::XSSHeader, :nosniff => false
|
metadata
CHANGED
@@ -1,16 +1,22 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-protection
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 1.4.0
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Konstantin Haase
|
9
14
|
- Alex Rodionov
|
10
15
|
- Chris Heald
|
11
16
|
- Chris Mytton
|
12
17
|
- Corey Ward
|
13
18
|
- David Kellum
|
19
|
+
- Egor Homakov
|
14
20
|
- Fojas
|
15
21
|
- Mael Clerambault
|
16
22
|
- Martin Mauch
|
@@ -19,68 +25,66 @@ authors:
|
|
19
25
|
- Steve Agalloco
|
20
26
|
- Akzhan Abdulin
|
21
27
|
- TOBY
|
22
|
-
-
|
28
|
+
- Bju00F8rge Nu00E6ss
|
23
29
|
autorequire:
|
24
30
|
bindir: bin
|
25
31
|
cert_chain: []
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
|
33
|
+
date: 2013-03-01 00:00:00 +11:00
|
34
|
+
default_executable:
|
35
|
+
dependencies:
|
36
|
+
- !ruby/object:Gem::Dependency
|
29
37
|
name: rack
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
31
|
-
none: false
|
32
|
-
requirements:
|
33
|
-
- - ! '>='
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version: '0'
|
36
|
-
type: :runtime
|
37
38
|
prerelease: false
|
38
|
-
|
39
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
39
40
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id001
|
50
|
+
- !ruby/object:Gem::Dependency
|
45
51
|
name: rack-test
|
46
|
-
requirement: !ruby/object:Gem::Requirement
|
47
|
-
none: false
|
48
|
-
requirements:
|
49
|
-
- - ! '>='
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
version: '0'
|
52
|
-
type: :development
|
53
52
|
prerelease: false
|
54
|
-
|
53
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
55
54
|
none: false
|
56
|
-
requirements:
|
57
|
-
- -
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
none: false
|
64
|
-
requirements:
|
65
|
-
- - ~>
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: '2.0'
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
68
62
|
type: :development
|
63
|
+
version_requirements: *id002
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: rspec
|
69
66
|
prerelease: false
|
70
|
-
|
67
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
71
68
|
none: false
|
72
|
-
requirements:
|
69
|
+
requirements:
|
73
70
|
- - ~>
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 2
|
75
|
+
- 0
|
76
|
+
version: "2.0"
|
77
|
+
type: :development
|
78
|
+
version_requirements: *id003
|
76
79
|
description: You should use protection!
|
77
|
-
email:
|
80
|
+
email:
|
78
81
|
- konstantin.mailinglists@googlemail.com
|
79
82
|
- p0deje@gmail.com
|
80
83
|
- cheald@gmail.com
|
81
84
|
- self@hecticjeff.net
|
82
85
|
- coreyward@me.com
|
83
86
|
- dek-oss@gravitext.com
|
87
|
+
- homakov@gmail.com
|
84
88
|
- developer@fojasaur.us
|
85
89
|
- mael@clerambault.fr
|
86
90
|
- martin.mauch@gmail.com
|
@@ -91,9 +95,12 @@ email:
|
|
91
95
|
- toby.net.info.mail+git@gmail.com
|
92
96
|
- bjoerge@bengler.no
|
93
97
|
executables: []
|
98
|
+
|
94
99
|
extensions: []
|
100
|
+
|
95
101
|
extra_rdoc_files: []
|
96
|
-
|
102
|
+
|
103
|
+
files:
|
97
104
|
- License
|
98
105
|
- README.md
|
99
106
|
- Rakefile
|
@@ -128,29 +135,39 @@ files:
|
|
128
135
|
- spec/session_hijacking_spec.rb
|
129
136
|
- spec/spec_helper.rb
|
130
137
|
- spec/xss_header_spec.rb
|
138
|
+
has_rdoc: true
|
131
139
|
homepage: http://github.com/rkh/rack-protection
|
132
140
|
licenses: []
|
141
|
+
|
133
142
|
post_install_message:
|
134
143
|
rdoc_options: []
|
135
|
-
|
144
|
+
|
145
|
+
require_paths:
|
136
146
|
- lib
|
137
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
148
|
none: false
|
139
|
-
requirements:
|
140
|
-
- -
|
141
|
-
- !ruby/object:Gem::Version
|
142
|
-
|
143
|
-
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
hash: 3
|
153
|
+
segments:
|
154
|
+
- 0
|
155
|
+
version: "0"
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
157
|
none: false
|
145
|
-
requirements:
|
146
|
-
- -
|
147
|
-
- !ruby/object:Gem::Version
|
148
|
-
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
hash: 3
|
162
|
+
segments:
|
163
|
+
- 0
|
164
|
+
version: "0"
|
149
165
|
requirements: []
|
166
|
+
|
150
167
|
rubyforge_project:
|
151
|
-
rubygems_version: 1.
|
168
|
+
rubygems_version: 1.6.2
|
152
169
|
signing_key:
|
153
170
|
specification_version: 3
|
154
171
|
summary: You should use protection!
|
155
172
|
test_files: []
|
156
|
-
|
173
|
+
|