da99_rack_protect 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b2e6ef07cf45beee6e0e040c99df3c5f63a6c6f1
4
+ data.tar.gz: 551bfa85f643a26860b241a386e1ed752b6426a5
5
+ SHA512:
6
+ metadata.gz: 50fbd480139dcc53acd2b97106be75f9a823702c8926e9861f5b581facc4490488ae89cfae7012b3df76eb6bd4beeedeefcd07fc8543323c286c1ddaddd98de5
7
+ data.tar.gz: dca52f395017f3b6312d0064c8dd2520e01fd2d8964dbcb8a2473ab7dfb8209bed60ad45d509ad72272044e8da1eca4dbaf6194886f3b5ca6d1b6dd80ea57559
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ tmp/*
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,23 @@
1
+
2
+ Copyright (c) 2014 da99
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,10 @@
1
+ rack\_protect
2
+ ===============
3
+
4
+ My favorite rack middleware in one package.
5
+
6
+ Notes:
7
+ ================
8
+
9
+ 1) `HTTP\_HOST`: Unreliable because it is sent by client.
10
+ Use `SERVER\_NAME`
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.0.2
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "da99_rack_protect"
7
+ spec.version = `cat VERSION`
8
+ spec.authors = ["da99"]
9
+ spec.email = ["i-hate-spam-1234567@mailinator.com"]
10
+ spec.summary = %q{My personal list of rack middlewares for web apps.}
11
+ spec.description = %q{
12
+ Various rack middlewares I use for projects.
13
+ I got tired of copying/pasting the same ones for
14
+ different apps.
15
+ }
16
+ spec.homepage = "https://github.com/da99/da99_rack_protect"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject { |file|
20
+ file.index('bin/') == 0 && file != "bin/#{File.basename Dir.pwd}"
21
+ }
22
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
23
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_runtime_dependency "rack-protection" , "> 1.5"
27
+
28
+ spec.add_development_dependency "pry" , "> 0.9"
29
+ spec.add_development_dependency "bundler" , "> 1.5"
30
+ spec.add_development_dependency "bacon" , "> 1.0"
31
+ spec.add_development_dependency "Bacon_Colored" , "> 0.1"
32
+ spec.add_development_dependency "cuba" , "> 3.2"
33
+ spec.add_development_dependency "thin" , "> 1.6"
34
+ end
@@ -0,0 +1,24 @@
1
+
2
+ class Da99_Rack_Protect
3
+ class Allow_Only_Roman_Uri
4
+
5
+ INVALID = /[^a-zA-Z0-9\_\-\/\.\?\@\*\=]+/
6
+ INVALID_QUERY = /[^a-zA-Z0-9\_\-\/\.\?\@\*\=\(\)\%\&]+/
7
+
8
+ def initialize new_app
9
+ @app = new_app
10
+ end
11
+
12
+ def call new_env
13
+ path_invalid = new_env['PATH_INFO'][INVALID]
14
+ qs_invalid = new_env['QUERY_STRING'][INVALID_QUERY]
15
+ if path_invalid || qs_invalid
16
+ content = "Page not found. \nReason: Invalid chars in page address: #{[path_invalid, qs_invalid].compact.join}"
17
+ DA99.response 400, :text, content
18
+ else
19
+ @app.call new_env
20
+ end
21
+ end
22
+
23
+ end # === Allow_Only_Roman_Uri
24
+ end # === Da99_Rack_Protect
@@ -0,0 +1,23 @@
1
+ class Da99_Rack_Protect
2
+ class Squeeze_Uri_Dots
3
+
4
+ DOTS_AND_SLASHES = /(\.+\/)|(\/\.+)/
5
+ DOTS = /\.\.+/
6
+
7
+ def initialize new_app
8
+ @app = new_app
9
+ end
10
+
11
+ # Using :REQUEST_URI includes query string
12
+ def call new_env
13
+ old = new_env['REQUEST_URI']
14
+ new = new_env['REQUEST_URI'].gsub(DOTS_AND_SLASHES, '/'.freeze).gsub(DOTS, '.'.freeze)
15
+ if new != old
16
+ DA99.redirect new, 301
17
+ else
18
+ @app.call new_env
19
+ end
20
+ end
21
+
22
+ end # === Squeeze_Uri_Dots
23
+ end # === Da99_Rack_Protect
@@ -0,0 +1,35 @@
1
+ class Da99_Rack_Protect
2
+ class No_Slash_Path_Ending
3
+
4
+ METHODS = ['HEAD', 'GET']
5
+ SLASH = '/'
6
+ LAST_SLASH = /\/\z/
7
+
8
+ def initialize new_app
9
+ @app = new_app
10
+ end
11
+
12
+ def call new_env
13
+
14
+ remove_slash = begin
15
+ new_env['PATH_INFO'] != SLASH &&
16
+ METHODS.include?(new_env['REQUEST_METHOD']) &&
17
+ new_env['PATH_INFO'][-1,1] == SLASH &&
18
+ File.extname(new_env['PATH_INFO']) === ''
19
+ end
20
+
21
+ return(@app.call( new_env )) unless remove_slash
22
+
23
+ req = Rack::Request.new(new_env)
24
+ response = Rack::Response.new
25
+
26
+ qs = req.query_string.strip.empty? ? nil : req.query_string
27
+ new = [ req.path_info.sub(LAST_SLASH, ''), qs ].compact.join('?')
28
+
29
+ response.redirect( new, 301 ) # permanent
30
+ response.finish
31
+
32
+ end
33
+
34
+ end # === Slashify_Path_Ending
35
+ end # === Da99_Rack_Protect
@@ -0,0 +1,18 @@
1
+ class Da99_Rack_Protect
2
+ class Root_Favicon_If_Not_Found
3
+
4
+ NON_ROOT_ICO = /.+\/favicon\.ico\z/
5
+ ROOT_ICO = '/favicon.ico'
6
+
7
+ def initialize new_app
8
+ @app = new_app
9
+ end
10
+
11
+ def call e
12
+ status, headers, body = @app.call( e )
13
+ return [status, headers, body] unless status == 404 && e['PATH_INFO'][NON_ROOT_ICO]
14
+ DA99.redirect ROOT_ICO, 302 # Permanent
15
+ end
16
+
17
+ end # === Root_Favicon_If_Not_Found
18
+ end # === Da99_Rack_Protect
@@ -0,0 +1,35 @@
1
+
2
+ class Da99_Rack_Protect
3
+
4
+ class Ensure_Host
5
+
6
+ SERVER_NAME = 'SERVER_NAME'
7
+ LOCALHOST = /\A(localhost|127\.0\.0\.1)\z/
8
+ HTT_HOST = 'HTTP_HOST'
9
+
10
+ def initialize new_app
11
+ @app = new_app
12
+ end
13
+
14
+ def call e
15
+ hosts = Da99_Rack_Protect::HOSTS
16
+ name = e[SERVER_NAME]
17
+ host = e[HTT_HOST]
18
+
19
+ is_valid = hosts.include?(name)
20
+
21
+ if !is_valid
22
+ is_local = hosts.include?(:localhost) && name[LOCALHOST]
23
+ is_valid = is_local
24
+ end
25
+
26
+ is_match = host[/\A#{name}(:\d+)?\z/]
27
+
28
+ return @app.call(e) if is_valid && is_match
29
+ Da99_Rack_Protect.response 444, :text, 'Unknown error.'
30
+ end
31
+
32
+ end # === class Ensure_Host
33
+
34
+
35
+ end # === class Da99_Rack_Protect
@@ -0,0 +1,21 @@
1
+
2
+ class Da99_Rack_Protect
3
+
4
+ class No_Old_MSIE
5
+
6
+ UA = /; MSIE (\d)\.\d/
7
+ def initialize new_app
8
+ @app = new_app
9
+ end
10
+
11
+ def call e
12
+ if e['HTTP_USER_AGENT'].to_s[UA] && $1.to_i < 9
13
+ return DA99.response 400, :text, "Page inaccessible because you are using an old browser: MSIE #{$1}"
14
+ end
15
+ @app.call e
16
+ end
17
+
18
+ end # === class No_Old_MSIE
19
+
20
+
21
+ end # === class Da99_Rack_Protect
@@ -0,0 +1,139 @@
1
+
2
+ require 'rack/protection'
3
+
4
+ class Da99_Rack_Protect
5
+
6
+ HOSTS = []
7
+ DA99 = self
8
+
9
+ # =================================================================
10
+ #
11
+ # I need to know if new middleware has been added
12
+ # to `rack-protection` so it can be properly
13
+ # used (or ignored) by Da99_Rack_Protect.
14
+ #
15
+ # =================================================================
16
+ RACK_PROTECTS_DIR = File.join File.dirname(`gem which rack-protection`.strip), '/rack/protection'
17
+ RACK_PROTECTS = Dir.glob(RACK_PROTECTS_DIR + '/*').map { |f|
18
+ File.basename(f).sub('.rb', '')
19
+ }.sort
20
+
21
+ Ignore_Rack_Protects = %w{ base version escaped_params remote_referrer }
22
+ Known_Rack_Protects = %w{
23
+ authenticity_token
24
+ form_token
25
+ frame_options
26
+ http_origin
27
+ ip_spoofing
28
+ json_csrf
29
+ path_traversal
30
+ remote_token
31
+ session_hijacking
32
+ xss_header
33
+ }
34
+
35
+ Rack_Protection_Names = {'ip_spoofing' => :IPSpoofing, 'xss_header'=>:XSSHeader}
36
+
37
+ Unknown_Rack_Protects = RACK_PROTECTS - Known_Rack_Protects - Ignore_Rack_Protects
38
+
39
+ if !Unknown_Rack_Protects.empty?
40
+ fail "Unknown rack-protection middleware: #{Unknown_Rack_Protects.inspect}"
41
+ end
42
+
43
+ require 'rack/protection/base'
44
+ Known_Rack_Protects.each { |name|
45
+ require "rack/protection/#{name}"
46
+ official_name = begin
47
+ Rack_Protection_Names[name] ||= name.split('_').map(&:capitalize).join.to_sym
48
+ end
49
+
50
+ Rack::Protection.const_get(official_name)
51
+ }
52
+ # =================================================================
53
+
54
+ dir = File.expand_path(File.dirname(__FILE__) + '/da99_rack_protect')
55
+ files = Dir.glob(dir + '/*.rb').sort
56
+ Names = files.map { |file|
57
+ base = File.basename(file).sub('.rb', '')
58
+ require "da99_rack_protect/#{base}"
59
+ pieces = base.split('_')
60
+ pieces.shift
61
+ pieces.join('_').to_sym
62
+ }
63
+
64
+ class << self
65
+
66
+ def config *args
67
+ yield(self) if block_given?
68
+ case args.length
69
+ when 0
70
+ # do nothing
71
+
72
+ when 2
73
+
74
+ case args.first
75
+
76
+ when :host
77
+ HOSTS.concat args.last
78
+
79
+ else
80
+ fail "Unknown args: #{args.inspect}"
81
+
82
+ end # === case
83
+
84
+ else
85
+ fail "Unknown args: #{args.inspect}"
86
+ end # === case
87
+
88
+ self
89
+ end # === def config
90
+
91
+ def redirect new, code = 301
92
+ res = Rack::Response.new
93
+ res.redirect new, code
94
+ res.finish
95
+ end
96
+
97
+ def response code, type, raw_content
98
+ content = raw_content.to_s
99
+ res = Rack::Response.new
100
+ res.status = code.to_i
101
+ res.headers['Content-Length'] = content.bytesize.to_s
102
+ res.headers['Content-Type'] = 'text/plain'.freeze
103
+ res.body = [content]
104
+ res.finish
105
+ end
106
+
107
+ end # === class self
108
+
109
+ def initialize main_app
110
+ @app = Rack::Builder.new do
111
+
112
+ use Rack::Lint
113
+ use Rack::ContentLength
114
+ use Rack::ContentType, "text/plain"
115
+ use Rack::MethodOverride
116
+ use Rack::Session::Cookie, secret: SecureRandom.urlsafe_base64(nil, true)
117
+
118
+ Known_Rack_Protects.each { |name|
119
+ use Rack::Protection.const_get(Rack_Protection_Names[name])
120
+ }
121
+
122
+ Names.each { |name|
123
+ use Da99_Rack_Protect.const_get(name)
124
+ }
125
+
126
+ if ENV['IS_DEV']
127
+ use Rack::CommonLogger
128
+ use Rack::ShowExceptions
129
+ end
130
+
131
+ run main_app
132
+ end
133
+ end
134
+
135
+ def call env
136
+ @app.call env
137
+ end
138
+
139
+ end # === class Da99_Rack_Protect ===
@@ -0,0 +1,129 @@
1
+
2
+ RACK_PROTECTS_DIR = File.join File.dirname(`gem which rack-protection`.strip), '/rack/protection'
3
+ RACK_PROTECTS = Dir.glob(RACK_PROTECTS_DIR + '/*').map { |f|
4
+ File.basename(f).sub('.rb', '')
5
+ }.sort
6
+
7
+
8
+ describe Da99_Rack_Protect do
9
+
10
+ it "runs" do
11
+ get(:http_code, '/').should == 200
12
+ end
13
+
14
+ it "does not have duplicates in Ignore_Rack_Protects, Known_Rack_Protects" do
15
+ (Da99_Rack_Protect::Ignore_Rack_Protects & Da99_Rack_Protect::Known_Rack_Protects).
16
+ should.be.empty
17
+ end
18
+
19
+ it "sets X-Frame-Options header to: SAMEORIGIN" do
20
+ get(:x_frame_options, '/').should == 'SAMEORIGIN'
21
+ end
22
+
23
+ it "returns 400 if browser is MSIE 6" do
24
+ get(:http_code, '/', '--header "User-Agent: Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)"').
25
+ should == 400
26
+ end
27
+
28
+ it "returns 400 if browser is MSIE 7" do
29
+ get(:http_code, '/', '--header "User-Agent: Mozilla/4.0(compatible; MSIE 7.0b; Windows NT 6.0)"').
30
+ should == 400
31
+ end
32
+
33
+ it "returns 400 if browser is MSIE 8" do
34
+ get(:http_code, '/', '--header "User-Agent: Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.2; SV1; .NET CLR 3.3.69573; WOW64; en-US)"').
35
+ should == 400
36
+ end
37
+
38
+ describe 'unknown rack protect' do
39
+
40
+ before { @random_file = RACK_PROTECTS_DIR + '/random_rack_file.rb' }
41
+
42
+ after { `rm -f #{@random_file}` }
43
+
44
+ it "fails if unknown rack-protection middleware is found" do
45
+ `touch #{@random_file}`
46
+ `ruby -e "require 'da99_rack_protect'" 2>&1`.
47
+ should.match /Unknown rack-protection middleware: ..random_rack_file.. \(/
48
+ end
49
+
50
+ end # === describe
51
+
52
+ end # === describe da99_rack_protect ===
53
+
54
+ describe Da99_Rack_Protect::Allow_Only_Roman_Uri do
55
+
56
+ it "returns 400 if uri has non-roman chars" do
57
+ get(:http_code, '/()').should == 400
58
+ end
59
+
60
+ it "returns 400 if query string has invalid chars: @+" do
61
+ get(:http_code, '/?@+').should == 400
62
+ end
63
+
64
+ it "output 'Invalid chars' in content" do
65
+ get(:output, '/()').should.match /Invalid chars/
66
+ end
67
+
68
+ it "allows special chars in query string: /?module=allow%20(event)&testNum=48" do
69
+ get(:http_code, '/?module=allow%20(event)').should == 200
70
+ end
71
+
72
+ end # === describe Allow_Only_Roman_Uri
73
+
74
+ describe Da99_Rack_Protect::Squeeze_Uri_Dots do
75
+
76
+ it "squeezes multiple dots into one" do
77
+ code, url = get(:redirect, '/hello.....rb')
78
+ code.should == 301
79
+ url.should.match /\/hello\.rb/
80
+ end
81
+
82
+ it "replaces .../ with /" do
83
+ code, url = get(:redirect, '/hello.../abc')
84
+ code.should == 301
85
+ url.should.match /\/hello\/abc/
86
+ end
87
+
88
+ it "replaces /... with /" do
89
+ code, url = get(:redirect, '/hello/...h')
90
+ code.should == 301
91
+ url.should.match /\/hello\/h/
92
+ end
93
+
94
+ end # === describe Squeeze_Uri_Dots
95
+
96
+ describe Da99_Rack_Protect::No_Slash_Path_Ending do
97
+
98
+ it "redirects to path with no ending slash" do
99
+ code, url = get(:redirect, '/slash/')
100
+ code.should == 301
101
+ url.should.match /\/slash\z/
102
+ end
103
+
104
+ end # === describe No_Slash_Path_Ending
105
+
106
+ describe Da99_Rack_Protect::Root_Favicon_If_Not_Found do
107
+
108
+ it "redirects to /favicon.ico if deeper ico file not found." do
109
+ code, url = get(:redirect, '/something/favicon.ico')
110
+ code.should == 302
111
+ url.should.match /\:4567\/favicon.ico/
112
+ end
113
+
114
+ it "does not redirect /favicon.ico" do
115
+ get(:http_code, '/favicon.ico').should == 404
116
+ end
117
+
118
+ end # === describe Root_Favicon_If_Not_Found
119
+
120
+ describe Da99_Rack_Protect::Ensure_Host do
121
+
122
+ it "returns a 444 error if host does not match allowed hosts" do
123
+ get(:http_code, '/', '--header "Host: MEGA"').should == 444
124
+ end
125
+
126
+ end # === describe Da99_Rack_Protect::Ensure_Host ===
127
+
128
+
129
+
@@ -0,0 +1,23 @@
1
+
2
+ require 'cuba'
3
+ require 'da99_rack_protect'
4
+
5
+ Cuba.use Da99_Rack_Protect.config { |c|
6
+ c.config :host, [:localhost, 'da99_sample.com']
7
+ }
8
+
9
+ if ENV['IS_DEV']
10
+ Cuba.use Rack::ShowExceptions
11
+ end
12
+
13
+ Cuba.define do
14
+
15
+ on get do
16
+ on(root) { res.write "Root" }
17
+ on('hello') { res.write 'Hello' }
18
+ on('hello/s') { res.write 'Hello/' }
19
+ end
20
+
21
+ end
22
+
23
+ run Cuba
@@ -0,0 +1,33 @@
1
+
2
+ require 'Bacon_Colored'
3
+ require 'pry'
4
+ require 'da99_rack_protect'
5
+
6
+ def get var, path, append = ''
7
+ url = "http://localhost:#{ENV['PORT']}#{path}"
8
+
9
+ case var
10
+
11
+ when :x_frame_options
12
+ `bin/get -D - -o /dev/null "#{url}" #{append}`.strip[/X-Frame-Options: (.+)$/] && ($1 || '').strip
13
+
14
+ when :http_code
15
+ `bin/get -w "%{#{var}}" "#{url}" #{append}`.strip.to_i
16
+
17
+ when :redirect_url
18
+ `bin/get -w "%{#{var}}" "#{url}" #{append}`.strip
19
+
20
+ when :redirect
21
+ raw = `bin/get -w '%{http_code} %{redirect_url}' "#{url}" #{append}`
22
+ pieces = raw.strip.split
23
+ pieces[0] = pieces[0].to_i
24
+ pieces
25
+
26
+ when :output
27
+ `bin/get "#{url}" #{append}`
28
+
29
+ else
30
+ fail "Unknown option: #{var.inspect}"
31
+
32
+ end # === case var
33
+ end # === def get
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: da99_rack_protect
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.2
5
+ platform: ruby
6
+ authors:
7
+ - da99
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack-protection
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bacon
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: Bacon_Colored
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: cuba
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: thin
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.6'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.6'
111
+ description: "\n Various rack middlewares I use for projects.\n I got tired
112
+ of copying/pasting the same ones for\n different apps.\n "
113
+ email:
114
+ - i-hate-spam-1234567@mailinator.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - Gemfile
121
+ - LICENSE.txt
122
+ - README.md
123
+ - VERSION
124
+ - da99_rack_protect.gemspec
125
+ - lib/da99_rack_protect.rb
126
+ - lib/da99_rack_protect/0010_Allow_Only_Roman_Uri.rb
127
+ - lib/da99_rack_protect/0020_Squeeze_Uri_Dots.rb
128
+ - lib/da99_rack_protect/0030_No_Slash_Path_Ending.rb
129
+ - lib/da99_rack_protect/0040_Root_Favicon_If_Not_Found.rb
130
+ - lib/da99_rack_protect/0050_Ensure_Host.rb
131
+ - lib/da99_rack_protect/0050_No_Old_MSIE.rb
132
+ - specs/da99_rack_protect.rb
133
+ - specs/helpers/config.ru
134
+ - specs/helpers/helpers.rb
135
+ homepage: https://github.com/da99/da99_rack_protect
136
+ licenses:
137
+ - MIT
138
+ metadata: {}
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 2.4.5
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: My personal list of rack middlewares for web apps.
159
+ test_files: []