rack-protection 1.2.0 → 1.3.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.

Potentially problematic release.


This version of rack-protection might be problematic. Click here for more details.

data/README.md CHANGED
@@ -43,12 +43,13 @@ Prevented by:
43
43
  * `Rack::Protection::JsonCsrf`
44
44
  * `Rack::Protection::RemoteReferrer` (not included by `use Rack::Protection`)
45
45
  * `Rack::Protection::RemoteToken`
46
+ * `Rack::Protection::HttpOrigin`
46
47
 
47
48
  ## Cross Site Scripting
48
49
 
49
50
  Prevented by:
50
51
 
51
- * `Rack::Protection::EscapedParams`
52
+ * `Rack::Protection::EscapedParams` (not included by `use Rack::Protection`)
52
53
  * `Rack::Protection::XssHeader` (Internet Explorer only)
53
54
 
54
55
  ## Clickjacking
@@ -79,24 +80,3 @@ Prevented by:
79
80
 
80
81
  gem install rack-protection
81
82
 
82
- # History
83
-
84
- ## v0.1.0 (2011/06/20)
85
-
86
- First public release.
87
-
88
- ## v1.0.0 (2011/09/02)
89
-
90
- First stable release.
91
-
92
- Changes:
93
-
94
- * Fix bug in JsonCsrf
95
-
96
- ## v1.1.0 (2011/09/03)
97
-
98
- Second public release.
99
-
100
- Changes:
101
-
102
- * Dependency on `escape_utils` is now optional
@@ -8,6 +8,7 @@ module Rack
8
8
  autoload :EscapedParams, 'rack/protection/escaped_params'
9
9
  autoload :FormToken, 'rack/protection/form_token'
10
10
  autoload :FrameOptions, 'rack/protection/frame_options'
11
+ autoload :HttpOrigin, 'rack/protection/http_origin'
11
12
  autoload :IPSpoofing, 'rack/protection/ip_spoofing'
12
13
  autoload :JsonCsrf, 'rack/protection/json_csrf'
13
14
  autoload :PathTraversal, 'rack/protection/path_traversal'
@@ -21,6 +22,7 @@ module Rack
21
22
  except = Array options[:except]
22
23
  Rack::Builder.new do
23
24
  use ::Rack::Protection::FrameOptions, options unless except.include? :frame_options
25
+ use ::Rack::Protection::HttpOrigin, options unless except.include? :http_origin
24
26
  use ::Rack::Protection::IPSpoofing, options unless except.include? :ip_spoofing
25
27
  use ::Rack::Protection::JsonCsrf, options unless except.include? :json_csrf
26
28
  use ::Rack::Protection::PathTraversal, options unless except.include? :path_traversal
@@ -10,7 +10,8 @@ module Rack
10
10
  :reaction => :default_reaction, :logging => true,
11
11
  :message => 'Forbidden', :encryptor => Digest::SHA1,
12
12
  :session_key => 'rack.session', :status => 403,
13
- :allow_empty_referrer => true
13
+ :allow_empty_referrer => true,
14
+ :html_types => %w[text/html application/xhtml]
14
15
  }
15
16
 
16
17
  attr_reader :app, :options
@@ -81,6 +82,10 @@ module Rack
81
82
  URI.parse(ref).host || Request.new(env).host
82
83
  end
83
84
 
85
+ def origin(env)
86
+ env['HTTP_ORIGIN'] || env['HTTP_X_ORIGIN']
87
+ end
88
+
84
89
  def random_string(secure = defined? SecureRandom)
85
90
  secure ? SecureRandom.hex(32) : "%032x" % rand(2**128-1)
86
91
  rescue NotImplementedError
@@ -92,6 +97,11 @@ module Rack
92
97
  end
93
98
 
94
99
  alias default_reaction deny
100
+
101
+ def html?(headers)
102
+ return false unless header = headers.detect { |k,v| k.downcase == 'content-type' }
103
+ options[:html_types].include? header.last[/^\w+\/\w+/]
104
+ end
95
105
  end
96
106
  end
97
107
  end
@@ -66,7 +66,7 @@ module Rack
66
66
  when Hash then escape_hash(object)
67
67
  when Array then object.map { |o| escape(o) }
68
68
  when String then escape_string(object)
69
- else raise ArgumentError, "cannot escape #{object.inspect}"
69
+ else nil
70
70
  end
71
71
  end
72
72
 
@@ -18,8 +18,13 @@ module Rack
18
18
  # to allow embedding from the same origin (default).
19
19
  class FrameOptions < XSSHeader
20
20
  default_options :frame_options => :sameorigin
21
+
21
22
  def header
22
- { 'X-Frame-Options' => options[:frame_options].to_s }
23
+ @header ||= begin
24
+ frame_options = options[:frame_options]
25
+ frame_options = options[:frame_options].to_s.upcase unless frame_options.respond_to? :to_str
26
+ { 'X-Frame-Options' => frame_options.to_str }
27
+ end
23
28
  end
24
29
  end
25
30
  end
@@ -0,0 +1,32 @@
1
+ require 'rack/protection'
2
+
3
+ module Rack
4
+ module Protection
5
+ ##
6
+ # Prevented attack:: CSRF
7
+ # Supported browsers:: Google Chrome 2, Safari 4 and later
8
+ # More infos:: http://en.wikipedia.org/wiki/Cross-site_request_forgery
9
+ # http://tools.ietf.org/html/draft-abarth-origin
10
+ #
11
+ # Does not accept unsafe HTTP requests when value of Origin HTTP request header
12
+ # does not match default or whitelisted URIs.
13
+ class HttpOrigin < Base
14
+ default_reaction :deny
15
+
16
+ def accepts?(env)
17
+ # only for unsafe request methods
18
+ safe?(env) and return true
19
+ # ignore if origin is not set
20
+ origin = env['HTTP_ORIGIN'] or return true
21
+
22
+ # check base url
23
+ Request.new(env).base_url == origin and return true
24
+
25
+ # check whitelist
26
+ options[:origin_whitelist] or return false
27
+ options[:origin_whitelist].include?(origin)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -16,7 +16,7 @@ module Rack
16
16
  def call(env)
17
17
  status, headers, body = app.call(env)
18
18
  if headers['Content-Type'].to_s.split(';', 2).first =~ /^\s*application\/json\s*$/
19
- if referrer(env) != Request.new(env).host
19
+ if origin(env).nil? and referrer(env) != Request.new(env).host
20
20
  result = react(env)
21
21
  warn env, "attack prevented by #{self.class}"
22
22
  end
@@ -12,7 +12,7 @@ module Rack
12
12
  class PathTraversal < Base
13
13
  def call(env)
14
14
  path_was = env["PATH_INFO"]
15
- env["PATH_INFO"] = cleanup path_was if path_was
15
+ env["PATH_INFO"] = cleanup path_was if path_was && !path_was.empty?
16
16
  app.call env
17
17
  ensure
18
18
  env["PATH_INFO"] = path_was
@@ -28,7 +28,8 @@ module Rack
28
28
  end
29
29
 
30
30
  def encrypt(value)
31
- options[:encrypt_tracking] ? super(value) : value.to_s
31
+ value = value.to_s.downcase
32
+ options[:encrypt_tracking] ? super(value) : value
32
33
  end
33
34
  end
34
35
  end
@@ -4,7 +4,7 @@ module Rack
4
4
  VERSION
5
5
  end
6
6
 
7
- SIGNATURE = [1, 2, 0]
7
+ SIGNATURE = [1, 3, 1]
8
8
  VERSION = SIGNATURE.join('.')
9
9
 
10
10
  VERSION.extend Comparable
@@ -12,15 +12,21 @@ module Rack
12
12
  # Options:
13
13
  # xss_mode:: How the browser should prevent the attack (default: :block)
14
14
  class XSSHeader < Base
15
- default_options :xss_mode => :block
15
+ default_options :xss_mode => :block, :nosniff => true
16
16
 
17
17
  def header
18
- { 'X-XSS-Protection' => "1; mode=#{options[:xss_mode]}" }
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
19
24
  end
20
25
 
21
26
  def call(env)
22
27
  status, headers, body = @app.call(env)
23
- [status, header.merge(headers), body]
28
+ headers = header.merge(headers) if options[:nosniff] and html?(headers)
29
+ [status, headers, body]
24
30
  end
25
31
  end
26
32
  end
@@ -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.2.0"
5
+ s.version = "1.3.1"
6
6
  s.description = "You should use protection!"
7
7
  s.homepage = "http://github.com/rkh/rack-protection"
8
8
  s.summary = s.description
@@ -10,21 +10,39 @@ Gem::Specification.new do |s|
10
10
  # generated from git shortlog -sn
11
11
  s.authors = [
12
12
  "Konstantin Haase",
13
- "Akzhan Abdulin",
13
+ "Alex Rodionov",
14
+ "Chris Heald",
15
+ "Chris Mytton",
14
16
  "Corey Ward",
15
17
  "David Kellum",
16
18
  "Fojas",
17
- "Martin Mauch"
19
+ "Mael Clerambault",
20
+ "Martin Mauch",
21
+ "SAKAI, Kazuaki",
22
+ "Stanislav Savulchik",
23
+ "Steve Agalloco",
24
+ "Akzhan Abdulin",
25
+ "TOBY",
26
+ "Bjørge Næss"
18
27
  ]
19
28
 
20
29
  # generated from git shortlog -sne
21
30
  s.email = [
22
31
  "konstantin.mailinglists@googlemail.com",
23
- "akzhan.abdulin@gmail.com",
32
+ "p0deje@gmail.com",
33
+ "cheald@gmail.com",
34
+ "self@hecticjeff.net",
24
35
  "coreyward@me.com",
25
36
  "dek-oss@gravitext.com",
26
37
  "developer@fojasaur.us",
27
- "martin.mauch@gmail.com"
38
+ "mael@clerambault.fr",
39
+ "martin.mauch@gmail.com",
40
+ "kaz.july.7@gmail.com",
41
+ "s.savulchik@gmail.com",
42
+ "steve.agalloco@gmail.com",
43
+ "akzhan.abdulin@gmail.com",
44
+ "toby.net.info.mail+git@gmail.com",
45
+ "bjoerge@bengler.no"
28
46
  ]
29
47
 
30
48
  # generated from git ls-files
@@ -39,6 +57,7 @@ Gem::Specification.new do |s|
39
57
  "lib/rack/protection/escaped_params.rb",
40
58
  "lib/rack/protection/form_token.rb",
41
59
  "lib/rack/protection/frame_options.rb",
60
+ "lib/rack/protection/http_origin.rb",
42
61
  "lib/rack/protection/ip_spoofing.rb",
43
62
  "lib/rack/protection/json_csrf.rb",
44
63
  "lib/rack/protection/path_traversal.rb",
@@ -52,6 +71,7 @@ Gem::Specification.new do |s|
52
71
  "spec/escaped_params_spec.rb",
53
72
  "spec/form_token_spec.rb",
54
73
  "spec/frame_options_spec.rb",
74
+ "spec/http_origin_spec.rb",
55
75
  "spec/ip_spoofing_spec.rb",
56
76
  "spec/json_csrf_spec.rb",
57
77
  "spec/path_traversal_spec.rb",
@@ -30,5 +30,15 @@ describe Rack::Protection::EscapedParams do
30
30
  get '/', :foo => {:bar => "<bar>"}
31
31
  body.should == '&lt;bar&gt;'
32
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
33
43
  end
34
44
  end
@@ -3,8 +3,12 @@ require File.expand_path('../spec_helper.rb', __FILE__)
3
3
  describe Rack::Protection::FrameOptions do
4
4
  it_behaves_like "any rack application"
5
5
 
6
- it 'should set the X-XSS-Protection' do
7
- get('/').headers["X-Frame-Options"].should == "sameorigin"
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
8
12
  end
9
13
 
10
14
  it 'should allow changing the protection mode' do
@@ -14,11 +18,22 @@ describe Rack::Protection::FrameOptions do
14
18
  run DummyApp
15
19
  end
16
20
 
17
- get('/').headers["X-Frame-Options"].should == "deny"
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"
18
33
  end
19
34
 
20
35
  it 'should not override the header if already set' do
21
36
  mock_app with_headers("X-Frame-Options" => "allow")
22
- get('/').headers["X-Frame-Options"].should == "allow"
37
+ get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "allow"
23
38
  end
24
39
  end
@@ -0,0 +1,38 @@
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
@@ -12,6 +12,14 @@ describe Rack::Protection::JsonCsrf do
12
12
  get('/', {}, 'HTTP_REFERER' => 'http://evil.com').should_not be_ok
13
13
  end
14
14
 
15
+ it "accepts requests with json responses with a remote referrer when there's an origin header set" do
16
+ get('/', {}, 'HTTP_REFERER' => 'http://good.com', 'HTTP_ORIGIN' => 'http://good.com').should be_ok
17
+ end
18
+
19
+ it "accepts requests with json responses with a remote referrer when there's an x-origin header set" do
20
+ get('/', {}, 'HTTP_REFERER' => 'http://good.com', 'HTTP_X_ORIGIN' => 'http://good.com').should be_ok
21
+ end
22
+
15
23
  it "accepts get requests with json responses with a local referrer" do
16
24
  get('/', {}, 'HTTP_REFERER' => '/').should be_ok
17
25
  end
@@ -17,4 +17,21 @@ describe Rack::Protection do
17
17
  get '/', {}, 'rack.session' => session, 'HTTP_FOO' => 'BAR'
18
18
  session.should be_empty
19
19
  end
20
+
21
+ describe "#html?" do
22
+ context "given an appropriate content-type header" do
23
+ subject { Rack::Protection::Base.new(nil).html? 'content-type' => "text/html" }
24
+ it { should be_true }
25
+ end
26
+
27
+ context "given an inappropriate content-type header" do
28
+ subject { Rack::Protection::Base.new(nil).html? 'content-type' => "image/gif" }
29
+ it { should be_false }
30
+ end
31
+
32
+ context "given no content-type header" do
33
+ subject { Rack::Protection::Base.new(nil).html?({}) }
34
+ it { should be_false }
35
+ end
36
+ end
20
37
  end
@@ -31,6 +31,20 @@ describe Rack::Protection::SessionHijacking do
31
31
  session.should be_empty
32
32
  end
33
33
 
34
+ it "accepts requests with the same Accept-Language header" do
35
+ session = {:foo => :bar}
36
+ get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
37
+ get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
38
+ session.should_not be_empty
39
+ end
40
+
41
+ it "comparison of Accept-Language header is not case sensitive" do
42
+ session = {:foo => :bar}
43
+ get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
44
+ get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'A'
45
+ session.should_not be_empty
46
+ end
47
+
34
48
  it "accepts requests with a changing Version header"do
35
49
  session = {:foo => :bar}
36
50
  get '/', {}, 'rack.session' => session, 'HTTP_VERSION' => '1.0'
@@ -24,7 +24,8 @@ end
24
24
  module DummyApp
25
25
  def self.call(env)
26
26
  Thread.current[:last_env] = env
27
- [200, {'Content-Type' => 'text/plain'}, ['ok']]
27
+ body = (env['REQUEST_METHOD'] == 'HEAD' ? '' : 'ok')
28
+ [200, {'Content-Type' => env['wants'] || 'text/plain'}, [body]]
28
29
  end
29
30
  end
30
31
 
@@ -4,7 +4,15 @@ describe Rack::Protection::XSSHeader do
4
4
  it_behaves_like "any rack application"
5
5
 
6
6
  it 'should set the X-XSS-Protection' do
7
- get('/').headers["X-XSS-Protection"].should == "1; mode=block"
7
+ get('/', {}, 'wants' => 'text/html;charset=utf-8').headers["X-XSS-Protection"].should == "1; mode=block"
8
+ end
9
+
10
+ it 'should set the X-XSS-Protection for XHTML' do
11
+ get('/', {}, 'wants' => 'application/xhtml+xml').headers["X-XSS-Protection"].should == "1; mode=block"
12
+ end
13
+
14
+ it 'should not set the X-XSS-Protection for other content types' do
15
+ get('/', {}, 'wants' => 'application/foo').headers["X-XSS-Protection"].should be_nil
8
16
  end
9
17
 
10
18
  it 'should allow changing the protection mode' do
@@ -14,11 +22,29 @@ describe Rack::Protection::XSSHeader do
14
22
  run DummyApp
15
23
  end
16
24
 
17
- get('/').headers["X-XSS-Protection"].should == "1; mode=foo"
25
+ get('/', {}, 'wants' => 'application/xhtml').headers["X-XSS-Protection"].should == "1; mode=foo"
18
26
  end
19
27
 
20
28
  it 'should not override the header if already set' do
21
29
  mock_app with_headers("X-XSS-Protection" => "0")
22
- get('/').headers["X-XSS-Protection"].should == "0"
30
+ get('/', {}, 'wants' => 'text/html').headers["X-XSS-Protection"].should == "0"
31
+ end
32
+
33
+ it 'should set the X-Content-Type-Options' do
34
+ get('/', {}, 'wants' => 'text/html').header["X-Content-Type-Options"].should == "nosniff"
35
+ end
36
+
37
+ it 'should allow changing the nosniff-mode off' do
38
+ mock_app do
39
+ use Rack::Protection::XSSHeader, :nosniff => false
40
+ run DummyApp
41
+ end
42
+
43
+ get('/').headers["X-Content-Type-Options"].should be_nil
44
+ end
45
+
46
+ it 'should not override the header if already set X-Content-Type-Options' do
47
+ mock_app with_headers("X-Content-Type-Options" => "sniff")
48
+ get('/', {}, 'wants' => 'text/html').headers["X-Content-Type-Options"].should == "sniff"
23
49
  end
24
50
  end
metadata CHANGED
@@ -1,24 +1,33 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-protection
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Konstantin Haase
9
- - Akzhan Abdulin
9
+ - Alex Rodionov
10
+ - Chris Heald
11
+ - Chris Mytton
10
12
  - Corey Ward
11
13
  - David Kellum
12
14
  - Fojas
15
+ - Mael Clerambault
13
16
  - Martin Mauch
17
+ - SAKAI, Kazuaki
18
+ - Stanislav Savulchik
19
+ - Steve Agalloco
20
+ - Akzhan Abdulin
21
+ - TOBY
22
+ - Bjørge Næss
14
23
  autorequire:
15
24
  bindir: bin
16
25
  cert_chain: []
17
- date: 2011-12-30 00:00:00.000000000 Z
26
+ date: 2012-12-10 00:00:00.000000000 Z
18
27
  dependencies:
19
28
  - !ruby/object:Gem::Dependency
20
29
  name: rack
21
- requirement: &2153091280 !ruby/object:Gem::Requirement
30
+ requirement: !ruby/object:Gem::Requirement
22
31
  none: false
23
32
  requirements:
24
33
  - - ! '>='
@@ -26,10 +35,15 @@ dependencies:
26
35
  version: '0'
27
36
  type: :runtime
28
37
  prerelease: false
29
- version_requirements: *2153091280
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
30
44
  - !ruby/object:Gem::Dependency
31
45
  name: rack-test
32
- requirement: &2153090800 !ruby/object:Gem::Requirement
46
+ requirement: !ruby/object:Gem::Requirement
33
47
  none: false
34
48
  requirements:
35
49
  - - ! '>='
@@ -37,10 +51,15 @@ dependencies:
37
51
  version: '0'
38
52
  type: :development
39
53
  prerelease: false
40
- version_requirements: *2153090800
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
41
60
  - !ruby/object:Gem::Dependency
42
61
  name: rspec
43
- requirement: &2153090140 !ruby/object:Gem::Requirement
62
+ requirement: !ruby/object:Gem::Requirement
44
63
  none: false
45
64
  requirements:
46
65
  - - ~>
@@ -48,15 +67,29 @@ dependencies:
48
67
  version: '2.0'
49
68
  type: :development
50
69
  prerelease: false
51
- version_requirements: *2153090140
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
52
76
  description: You should use protection!
53
77
  email:
54
78
  - konstantin.mailinglists@googlemail.com
55
- - akzhan.abdulin@gmail.com
79
+ - p0deje@gmail.com
80
+ - cheald@gmail.com
81
+ - self@hecticjeff.net
56
82
  - coreyward@me.com
57
83
  - dek-oss@gravitext.com
58
84
  - developer@fojasaur.us
85
+ - mael@clerambault.fr
59
86
  - martin.mauch@gmail.com
87
+ - kaz.july.7@gmail.com
88
+ - s.savulchik@gmail.com
89
+ - steve.agalloco@gmail.com
90
+ - akzhan.abdulin@gmail.com
91
+ - toby.net.info.mail+git@gmail.com
92
+ - bjoerge@bengler.no
60
93
  executables: []
61
94
  extensions: []
62
95
  extra_rdoc_files: []
@@ -71,6 +104,7 @@ files:
71
104
  - lib/rack/protection/escaped_params.rb
72
105
  - lib/rack/protection/form_token.rb
73
106
  - lib/rack/protection/frame_options.rb
107
+ - lib/rack/protection/http_origin.rb
74
108
  - lib/rack/protection/ip_spoofing.rb
75
109
  - lib/rack/protection/json_csrf.rb
76
110
  - lib/rack/protection/path_traversal.rb
@@ -84,6 +118,7 @@ files:
84
118
  - spec/escaped_params_spec.rb
85
119
  - spec/form_token_spec.rb
86
120
  - spec/frame_options_spec.rb
121
+ - spec/http_origin_spec.rb
87
122
  - spec/ip_spoofing_spec.rb
88
123
  - spec/json_csrf_spec.rb
89
124
  - spec/path_traversal_spec.rb
@@ -113,8 +148,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
148
  version: '0'
114
149
  requirements: []
115
150
  rubyforge_project:
116
- rubygems_version: 1.8.10
151
+ rubygems_version: 1.8.23
117
152
  signing_key:
118
153
  specification_version: 3
119
154
  summary: You should use protection!
120
155
  test_files: []
156
+ has_rdoc: