rack-protection 1.2.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.

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: