rack-ssl-enforcer 0.2.4 → 0.2.5

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.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Tobias Matthies
1
+ Copyright (c) 2009-2012 Tobias Matthies
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -0,0 +1,220 @@
1
+ # Rack::SslEnforcer [![Build Status](https://secure.travis-ci.org/tobmatth/rack-ssl-enforcer.png?branch=master)](http://travis-ci.org/tobmatth/rack-ssl-enforcer)
2
+
3
+ Rack::SslEnforcer is a simple Rack middleware to enforce SSL connections. As of Version 0.2.0, Rack::SslEnforcer marks
4
+ Cookies as secure by default (HSTS must be set manually).
5
+
6
+ Tested against Ruby 1.8.7, 1.9.2, 1.9.3, ruby-head, REE and the latest versions of Rubinius & JRuby.
7
+
8
+ ## Installation
9
+
10
+ The simplest way to install Rack::SslEnforcer is to use [Bundler](http://gembundler.com/).
11
+
12
+ Add Rack::SslEnforcer to your `Gemfile`:
13
+
14
+ ```ruby
15
+ gem 'rack-ssl-enforcer'
16
+ ```
17
+
18
+ ### Installing on Sinatra / Padrino application
19
+
20
+ In order for Rack::SslEnforcer to properly work it has to be at the top
21
+ of the Rack Middleware.
22
+
23
+ Using `enable :session` will place Rack::Session::Cookie before Rack::Ssl::Enforcer
24
+ and will prevent Rack::Ssl::Enforcer from marking cookies as secure.
25
+
26
+ To fix this issue do not use `enable :sessions` instead add the
27
+ Rack::Session::Cookie middleware after Rack::Ssl::Enforcer.
28
+
29
+ Eg:
30
+
31
+ use Rack::SslEnforcer
32
+ set :session_secret, 'asdfa2342923422f1adc05c837fa234230e3594b93824b00e930ab0fb94b'
33
+
34
+ #Enable sinatra sessions
35
+ use Rack::Session::Cookie, :key => '_rack_session',
36
+ :path => '/',
37
+ :expire_after => 2592000, # In seconds
38
+ :secret => session_secret
39
+
40
+
41
+ ## Basic Usage
42
+
43
+ If you don't use Bundler, be sure to require Rack::SslEnforcer manually before actually using the middleware:
44
+
45
+ ```ruby
46
+ require 'rack/ssl-enforcer'
47
+ use Rack::SslEnforcer
48
+ ```
49
+
50
+ To use Rack::SslEnforcer in your Rails application, add the following line to your application config file (`config/application.rb` for Rails 3, `config/environment.rb` for Rails 2):
51
+
52
+ ```ruby
53
+ config.middleware.use Rack::SslEnforcer
54
+ ```
55
+
56
+ If all you want is SSL for your whole application, you are done! Otherwise, you can specify some options described below.
57
+
58
+ ## Options
59
+
60
+ ### Host constraints
61
+
62
+ You can enforce SSL connections only for certain hosts with `:only_hosts`, or prevent certain hosts from being forced to SSL with `:except_hosts`. Constraints can be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
63
+
64
+ ```ruby
65
+ config.middleware.use Rack::SslEnforcer, :only_hosts => 'api.example.com'
66
+ # Please note that, for instance, both http://help.example.com/demo and https://help.example.com/demo would be accessible here
67
+
68
+ config.middleware.use Rack::SslEnforcer, :except_hosts => /[help|blog]\.example\.com$/
69
+
70
+ config.middleware.use Rack::SslEnforcer, :only_hosts => [/[secure|admin]\.example\.org$/, 'api.example.com']
71
+ ```
72
+
73
+ ### Path constraints
74
+
75
+ You can enforce SSL connections only for certain paths with `:only`, or prevent certain paths from being forced to SSL with `:except`. Constraints can be a `String`, a `Regex` or an array of `String` or `Regex` (possibly mixed), as shown in the following examples:
76
+
77
+ ```ruby
78
+ config.middleware.use Rack::SslEnforcer, :only => '/login'
79
+ # Please note that, for instance, both http://example.com/demo and https://example.com/demo would be accessible here
80
+
81
+ config.middleware.use Rack::SslEnforcer, :only => %r{^/admin/}
82
+
83
+ config.middleware.use Rack::SslEnforcer, :except => ['/demo', %r{^/public/}]
84
+ ```
85
+
86
+ ### Method constraints
87
+
88
+ You can enforce SSL connections only for certain HTTP methods with `:only_methods`, or prevent certain HTTP methods from being forced to SSL with `:except_methods`. Constraints can be a `String` or an array of `String`, as shown in the following examples:
89
+
90
+ ```ruby
91
+ # constraint as a String
92
+ config.middleware.use Rack::SslEnforcer, :only_methods => 'POST'
93
+ # Please note that, for instance, GET requests would be accessible via SSL and non-SSL connection here
94
+
95
+ config.middleware.use Rack::SslEnforcer, :except_methods => ['GET', 'HEAD']
96
+ ```
97
+
98
+ Note: The `:hosts` constraint takes precedence over the `:path` constraint. Please see the tests for examples.
99
+
100
+ ### Force-redirection to non-SSL connection if constraint is not matched
101
+
102
+ Use the `:strict` option to force non-SSL connection for all requests not matching the constraints you set. Examples:
103
+
104
+ ```ruby
105
+ config.middleware.use Rack::SslEnforcer, :only => ["/login", /\.xml$/], :strict => true
106
+ # https://example.com/demo would be redirected to http://example.com/demo
107
+
108
+ config.middleware.use Rack::SslEnforcer, :except_hosts => 'demo.example.com', :strict => true
109
+ # https://demo.example.com would be redirected to http://demo.example.com
110
+ ```
111
+
112
+ ### Automatic method constraints
113
+
114
+ In the case where you have matching URLs with different HTTP methods – for instance Rails RESTful routes: `GET /users`, `POST /users`, `GET /user/:id` and `PUT /user/:id` – you may need to force POST and PUT requests to SSL connection but redirect to non-SSL connection on GET.
115
+
116
+ ```ruby
117
+ config.middleware.use Rack::SslEnforcer, :only => [%r{^/users/}], :mixed => true
118
+ ```
119
+
120
+ The above will allow you to POST/PUT from the secure/non-secure URLs keeping the original schema.
121
+
122
+ ### HTTP Strict Transport Security (HSTS)
123
+
124
+ To set HSTS expiry and subdomain inclusion (defaults respectively to `one year` and `true`).
125
+
126
+ ```ruby
127
+ config.middleware.use Rack::SslEnforcer, :hsts => { :expires => 500, :subdomains => false }
128
+ config.middleware.use Rack::SslEnforcer, :hsts => true # equivalent to { :expires => 31536000, :subdomains => true }
129
+ ```
130
+ Please note that the strict option disables HSTS.
131
+
132
+ ### Redirect to specific URL (e.g. if you're using a proxy)
133
+
134
+ You might need the `:redirect_to` option if the requested URL can't be determined.
135
+
136
+ ```ruby
137
+ config.middleware.use Rack::SslEnforcer, :redirect_to => 'https://example.org'
138
+ ```
139
+
140
+ ### Custom HTTP port
141
+
142
+ If you're using a different port than the default (80) for HTTP, you can specify it with the `:http_port` option:
143
+
144
+ ```ruby
145
+ config.middleware.use Rack::SslEnforcer, :http_port => 8080
146
+ ```
147
+
148
+ ### Custom HTTPS port
149
+
150
+ If you're using a different port than the default (443) for HTTPS, you can specify it with the `:https_port` option:
151
+
152
+ ```ruby
153
+ config.middleware.use Rack::SslEnforcer, :https_port => 444
154
+ ```
155
+
156
+ ### Secure cookies disabling
157
+
158
+ Finally you might want to share a cookie based session between HTTP and HTTPS.
159
+ This is not possible by default with Rack::SslEnforcer for [security reasons](http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking).
160
+
161
+ Nevertheless, you can set the `:force_secure_cookies` option to `false` in order to be able to share a cookie based session between HTTP and HTTPS:
162
+
163
+ ```ruby
164
+ config.middleware.use Rack::SslEnforcer, :only => "/login", :force_secure_cookies => false
165
+ ```
166
+
167
+ But be aware that if you do so, you have to make sure that the content of you cookie is encoded.
168
+ This can be done using a coder with [Rack::Session::Cookie](https://github.com/rack/rack/blob/master/lib/rack/session/cookie.rb#L28-42).
169
+
170
+ ## Deployment
171
+
172
+ If you run your application behind a proxy (e.g. Nginx) you may need to do some configuration on that side. If you don't you may experience an infinite redirect loop.
173
+
174
+ The reason this happens is that Rack::SslEnforcer can't detect if you are running SSL or not. The solution is to have your front-end server send extra headers for Rack::SslEnforcer to identify the request protocol.
175
+
176
+ ### Nginx
177
+
178
+ In the `location` block for your app's SSL configuration, include the following proxy header configuration:
179
+
180
+ `proxy_set_header X-Forwarded-Proto https;`
181
+
182
+ ### Passenger
183
+
184
+ Or, if you're using mod_rails/passenger (which will ignore the proxy_xxx directives):
185
+
186
+ `passenger_set_cgi_param HTTP_X_FORWARDED_PROTO https;`
187
+
188
+ If you're sharing a single `server` block for http AND https access you can add:
189
+
190
+ `passenger_set_cgi_param HTTP_X_FORWARDED_PROTO $scheme;`
191
+
192
+ This makes sure that Rack::SslEnforcer knows it's being accessed over SSL. Just restart Nginx for these changes to take effect.
193
+
194
+ ## TODO
195
+
196
+ * Cleanup tests
197
+
198
+ ## Contributors
199
+
200
+ * [Dan Mayer](http://github.com/danmayer)
201
+ * [Rémy Coutable](http://github.com/rymai)
202
+ * [Thibaud Guillaume-Gentil](http://github.com/thibaudgg)
203
+ * [Paul Annesley](https://github.com/pda)
204
+ * [Saimon Moore](https://github.com/saimonmoore)
205
+
206
+ ## Credits
207
+
208
+ Flagging cookies as secure functionality and HSTS support is greatly inspired by [Joshua Peek's Rack::SSL](https://github.com/josh/rack-ssl).
209
+
210
+ ## Note on Patches / Pull Requests
211
+
212
+ * Fork the project.
213
+ * Code your feature addition or bug fix.
214
+ * **Add tests for it.** This is important so we don't break it in a future version unintentionally.
215
+ * Commit, do not mess with Rakefile or version number. If you want to have your own version, that's fine but bump version in a commit by itself so we can ignore it when merging.
216
+ * Send a pull request. Bonus points for topic branches.
217
+
218
+ ## Copyright
219
+
220
+ Copyright (c) 2010-2012 Tobias Matthies. See LICENSE for details.
@@ -1,38 +1,46 @@
1
+ require 'rack/ssl-enforcer/constraint'
2
+
1
3
  module Rack
4
+
2
5
  class SslEnforcer
3
6
 
7
+ CONSTRAINTS_BY_TYPE = {
8
+ :hosts => [:only_hosts, :except_hosts],
9
+ :path => [:only, :except],
10
+ :methods => [:only_methods, :except_methods]
11
+ }
12
+
4
13
  # Warning: If you set the option force_secure_cookies to false, make sure that your cookies
5
- # are encoded and that you understand the consequences (see documentation)
14
+ # are encoded and that you understand the consequences (see documentation)
6
15
  def initialize(app, options={})
7
16
  default_options = {
8
- :redirect_to => nil,
9
- :only => nil,
10
- :only_hosts => nil,
11
- :except => nil,
12
- :except_hosts => nil,
13
- :strict => false,
14
- :mixed => false,
15
- :hsts => nil,
16
- :http_port => nil,
17
- :https_port => nil,
17
+ :redirect_to => nil,
18
+ :strict => false,
19
+ :mixed => false,
20
+ :hsts => nil,
21
+ :http_port => nil,
22
+ :https_port => nil,
18
23
  :force_secure_cookies => true
19
24
  }
25
+ CONSTRAINTS_BY_TYPE.values.each { |constraint| default_options[constraint] = nil }
26
+
20
27
  @app, @options = app, default_options.merge(options)
21
28
  end
22
29
 
23
30
  def call(env)
24
- @req = Rack::Request.new(env)
25
- if enforce_ssl?(@req)
26
- scheme = 'https' unless ssl_request?(env)
27
- elsif ssl_request?(env) && enforcement_non_ssl?(env)
28
- scheme = 'http'
31
+ @request = Rack::Request.new(env)
32
+
33
+ return @app.call(env) if ignore?
34
+
35
+ @scheme = if enforce_ssl?
36
+ 'https'
37
+ elsif enforce_non_ssl?
38
+ 'http'
29
39
  end
30
40
 
31
- if scheme
32
- location = replace_scheme(@req, scheme)
33
- body = "<html><body>You are being <a href=\"#{location}\">redirected</a>.</body></html>"
34
- [301, { 'Content-Type' => 'text/html', 'Location' => location }, [body]]
35
- elsif ssl_request?(env)
41
+ if redirect_required?
42
+ modify_location_and_redirect
43
+ elsif ssl_request?
36
44
  status, headers, body = @app.call(env)
37
45
  flag_cookies_as_secure!(headers) if @options[:force_secure_cookies]
38
46
  set_hsts_headers!(headers) if @options[:hsts] && !@options[:strict]
@@ -43,105 +51,113 @@ module Rack
43
51
  end
44
52
 
45
53
  private
54
+
55
+ def redirect_required?
56
+ scheme_mismatch? || host_mismatch?
57
+ end
46
58
 
47
- def enforcement_non_ssl?(env)
48
- true if @options[:strict] || @options[:mixed] && !(env['REQUEST_METHOD'] == 'PUT' || env['REQUEST_METHOD'] == 'POST')
59
+ def ignore?
60
+ if @options[:ignore]
61
+ rules = [@options[:ignore]].flatten.compact
62
+ rules.any? do |rule|
63
+ SslEnforcerConstraint.new(:ignore, rule, @request).matches?
64
+ end
65
+ else
66
+ false
67
+ end
68
+ end
69
+
70
+ def scheme_mismatch?
71
+ @scheme && @scheme != current_scheme
72
+ end
73
+
74
+ def host_mismatch?
75
+ destination_host && destination_host != @request.host
76
+ end
77
+
78
+ def modify_location_and_redirect
79
+ location = "#{current_scheme}://#{@request.host}#{@request.fullpath}"
80
+ location = replace_scheme(location, @scheme)
81
+ location = replace_host(location, @options[:redirect_to])
82
+ redirect_to(location)
83
+ end
84
+
85
+ def redirect_to(location)
86
+ body = "<html><body>You are being <a href=\"#{location}\">redirected</a>.</body></html>"
87
+ [301, { 'Content-Type' => 'text/html', 'Location' => location }, [body]]
49
88
  end
50
89
 
51
- def ssl_request?(env)
52
- scheme(env) == 'https'
90
+ def ssl_request?
91
+ current_scheme == 'https'
92
+ end
93
+
94
+ def destination_host
95
+ if @options[:redirect_to]
96
+ host_parts = URI.split(@options[:redirect_to])
97
+ host_parts[2] || host_parts[5]
98
+ end
53
99
  end
54
100
 
55
101
  # Fixed in rack >= 1.3
56
- def scheme(env)
57
- if env['HTTPS'] == 'on'
102
+ def current_scheme
103
+ if @request.env['HTTPS'] == 'on'
58
104
  'https'
59
- elsif env['HTTP_X_FORWARDED_PROTO']
60
- env['HTTP_X_FORWARDED_PROTO'].split(',')[0]
105
+ elsif @request.env['HTTP_X_FORWARDED_PROTO']
106
+ @request.env['HTTP_X_FORWARDED_PROTO'].split(',')[0]
61
107
  else
62
- env['rack.url_scheme']
108
+ @request.scheme
63
109
  end
64
110
  end
65
111
 
66
- def matches?(key, pattern, req)
67
- if pattern.is_a?(Regexp)
68
- case key
69
- when :only
70
- req.path =~ pattern
71
- when :except
72
- req.path !~ pattern
73
- when :only_hosts
74
- req.host =~ pattern
75
- when :except_hosts
76
- req.host !~ pattern
77
- end
112
+ def enforce_ssl_for?(keys)
113
+ provided_keys = keys.select { |key| @options[key] }
114
+ if provided_keys.empty?
115
+ true
78
116
  else
79
- case key
80
- when :only
81
- req.path[0,pattern.length] == pattern
82
- when :except
83
- req.path[0,pattern.length] != pattern
84
- when :only_hosts
85
- req.host == pattern
86
- when :except_hosts
87
- req.host != pattern
88
- end
89
- end
90
- end
91
-
92
- def enforce_ssl_for?(keys, req)
93
- if keys.any? { |option| @options[option] }
94
- keys.any? do |key|
117
+ provided_keys.all? do |key|
95
118
  rules = [@options[key]].flatten.compact
96
- unless rules.empty?
97
- rules.send(key == :except_hosts || key == :except ? "all?" : "any?") do |pattern|
98
- matches?(key, pattern, req)
99
- end
119
+ rules.send([:except_hosts, :except].include?(key) ? :all? : :any?) do |rule|
120
+ SslEnforcerConstraint.new(key, rule, @request).matches?
100
121
  end
101
122
  end
102
- else
103
- false
104
123
  end
105
124
  end
106
125
 
107
- def enforce_ssl?(req)
108
- path_keys = [:only, :except]
109
- hosts_keys = [:only_hosts, :except_hosts]
110
- if hosts_keys.any? { |option| @options[option] }
111
- if enforce_ssl_for?(hosts_keys, req)
112
- if path_keys.any? { |option| @options[option] }
113
- enforce_ssl_for?(path_keys, req)
114
- else
115
- true
116
- end
117
- else
118
- false
119
- end
120
- elsif path_keys.any? { |option| @options[option] }
121
- enforce_ssl_for?(path_keys, req)
122
- else
123
- true
124
- end
126
+ def enforce_non_ssl?
127
+ @options[:strict] || @options[:mixed] && !(@request.request_method == 'PUT' || @request.request_method == 'POST')
125
128
  end
126
129
 
127
- def replace_scheme(req, scheme)
128
- if @options[:redirect_to]
129
- uri = URI.split(@options[:redirect_to])
130
- uri = uri[2] || uri[5]
131
- else
132
- uri = nil
130
+ def enforce_ssl?
131
+ CONSTRAINTS_BY_TYPE.inject(true) do |memo, (type, keys)|
132
+ memo && enforce_ssl_for?(keys)
133
133
  end
134
- host = uri || req.host
135
- port = port_for(scheme).to_s
136
-
137
- URI.parse("#{scheme}://#{host}:#{port}#{req.fullpath}").to_s
138
134
  end
139
135
 
140
- def port_for(scheme)
136
+ def replace_scheme(uri, scheme)
137
+ return uri if not scheme_mismatch?
138
+
139
+ port = adjust_port_to(scheme)
140
+ uri_parts = URI.split(uri)
141
+ uri_parts[3] = port unless port.nil?
142
+ uri_parts[0] = scheme
143
+ URI::HTTP.new(*uri_parts).to_s
144
+ end
145
+
146
+ def replace_host(uri, host)
147
+ return uri unless host_mismatch?
148
+
149
+ host_parts = URI.split(host)
150
+ new_host = host_parts[2] || host_parts[5]
151
+ uri_parts = URI.split(uri)
152
+ uri_parts[2] = new_host
153
+ URI::HTTPS.new(*uri_parts).to_s
154
+ end
155
+
156
+ def adjust_port_to(scheme)
141
157
  if scheme == 'https'
142
- @options[:https_port] || 443
143
- else
144
- @options[:http_port] || 80
158
+ @options[:https_port] if @options[:https_port] && @options[:https_port] != URI::HTTPS.default_port
159
+ elsif scheme == 'http'
160
+ @options[:http_port] if @options[:http_port] && @options[:http_port] != URI::HTTP.default_port
145
161
  end
146
162
  end
147
163
 
@@ -0,0 +1,38 @@
1
+ class SslEnforcerConstraint
2
+ def initialize(name, rule, request)
3
+ @name = name
4
+ @rule = rule
5
+ @request = request
6
+ end
7
+
8
+ def matches?
9
+ if @rule.is_a?(String) && [:only, :except].include?(@name)
10
+ result = tested_string[0, @rule.size].send(operator, @rule)
11
+ else
12
+ result = tested_string.send(operator, @rule)
13
+ end
14
+
15
+ negate_result? ? !result : result
16
+ end
17
+
18
+ private
19
+
20
+ def negate_result?
21
+ @name.to_s =~ /except/
22
+ end
23
+
24
+ def operator
25
+ @rule.is_a?(Regexp) ? "=~" : "=="
26
+ end
27
+
28
+ def tested_string
29
+ case @name.to_s
30
+ when /hosts/
31
+ @request.host
32
+ when /methods/
33
+ @request.request_method
34
+ else
35
+ @request.path
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class SslEnforcer
3
- VERSION = "0.2.4"
3
+ VERSION = "0.2.5"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-ssl-enforcer
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 29
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 2
8
- - 4
9
- version: 0.2.4
9
+ - 5
10
+ version: 0.2.5
10
11
  platform: ruby
11
12
  authors:
12
13
  - Tobias Matthies
@@ -15,8 +16,7 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-09-05 00:00:00 +02:00
19
- default_executable:
19
+ date: 2012-11-14 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: bundler
@@ -26,6 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
+ hash: 15
29
30
  segments:
30
31
  - 1
31
32
  - 0
@@ -40,6 +41,7 @@ dependencies:
40
41
  requirements:
41
42
  - - ~>
42
43
  - !ruby/object:Gem::Version
44
+ hash: 5
43
45
  segments:
44
46
  - 2
45
47
  - 3
@@ -54,6 +56,7 @@ dependencies:
54
56
  requirements:
55
57
  - - ~>
56
58
  - !ruby/object:Gem::Version
59
+ hash: 37
57
60
  segments:
58
61
  - 2
59
62
  - 11
@@ -69,6 +72,7 @@ dependencies:
69
72
  requirements:
70
73
  - - ~>
71
74
  - !ruby/object:Gem::Version
75
+ hash: 31
72
76
  segments:
73
77
  - 1
74
78
  - 2
@@ -84,6 +88,7 @@ dependencies:
84
88
  requirements:
85
89
  - - ~>
86
90
  - !ruby/object:Gem::Version
91
+ hash: 3
87
92
  segments:
88
93
  - 0
89
94
  - 5
@@ -102,12 +107,12 @@ extensions: []
102
107
  extra_rdoc_files: []
103
108
 
104
109
  files:
110
+ - lib/rack/ssl-enforcer/constraint.rb
105
111
  - lib/rack/ssl-enforcer/version.rb
106
112
  - lib/rack/ssl-enforcer.rb
107
113
  - lib/rack-ssl-enforcer.rb
108
114
  - LICENSE
109
- - README.rdoc
110
- has_rdoc: true
115
+ - README.md
111
116
  homepage: http://github.com/tobmatth/rack-ssl-enforcer
112
117
  licenses: []
113
118
 
@@ -121,6 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
126
  requirements:
122
127
  - - ">="
123
128
  - !ruby/object:Gem::Version
129
+ hash: 3
124
130
  segments:
125
131
  - 0
126
132
  version: "0"
@@ -129,6 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
135
  requirements:
130
136
  - - ">="
131
137
  - !ruby/object:Gem::Version
138
+ hash: 23
132
139
  segments:
133
140
  - 1
134
141
  - 3
@@ -137,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
144
  requirements: []
138
145
 
139
146
  rubyforge_project: rack-ssl-enforcer
140
- rubygems_version: 1.3.7
147
+ rubygems_version: 1.8.24
141
148
  signing_key:
142
149
  specification_version: 3
143
150
  summary: A simple Rack middleware to enforce SSL
@@ -1,111 +0,0 @@
1
- = Rack::SslEnforcer
2
-
3
- Rack::SslEnforcer is a simple Rack middleware to enforce SSL connections. As of Version 0.2.0, Rack::SslEnforcer marks
4
- Cookies as secure by default (HSTS must be set manually).
5
-
6
- Tested on Ruby 1.8.7, 1.9.2, REE, JRuby and Rubinius.
7
-
8
- == Installation
9
-
10
- gem install rack-ssl-enforcer
11
-
12
-
13
- == Basic Usage
14
-
15
- require 'rack/ssl-enforcer'
16
- use Rack::SslEnforcer
17
-
18
- Or, if you are using Bundler, just add this to your Gemfile:
19
-
20
- gem 'rack-ssl-enforcer'
21
-
22
- To use Rack::SslEnforcer in your Rails application, add the following line to your application
23
- config file (<tt>config/application.rb</tt> for Rails 3, <tt>config/environment.rb</tt> for Rails 2):
24
-
25
- config.middleware.use Rack::SslEnforcer
26
-
27
- If all you want is SSL for your whole application, you are done! However, you can specify some
28
-
29
-
30
- == Options
31
-
32
- You might need the :redirect_to option if the requested URL can't be determined (e.g. if using a proxy).
33
-
34
- config.middleware.use Rack::SslEnforcer, :redirect_to => 'https://example.org'
35
-
36
- You can also define specific regex patterns or paths or hosts to redirect.
37
-
38
- config.middleware.use Rack::SslEnforcer, :only => /^\/admin\//
39
- config.middleware.use Rack::SslEnforcer, :only => "/login"
40
- config.middleware.use Rack::SslEnforcer, :only => ["/login", /\.xml$/]
41
- config.middleware.use Rack::SslEnforcer, :only_hosts => 'api.example.com'
42
- config.middleware.use Rack::SslEnforcer, :only_hosts => [/[www|api]\.example\.org$/, 'example.com']
43
- config.middleware.use Rack::SslEnforcer, :except_hosts => 'help.example.com'
44
- config.middleware.use Rack::SslEnforcer, :except_hosts => /[help|blog]\.example\.com$/
45
-
46
- Note: hosts options take precedence over the path options. See tests for examples.
47
-
48
- Use the :strict option to force http for all requests not matching your :only specification
49
-
50
- config.middleware.use Rack::SslEnforcer, :only => ["/login", /\.xml$/], :strict => true
51
- config.middleware.use Rack::SslEnforcer, :only_hosts => 'api.example.com', :strict => true
52
-
53
- Or in the case where you have matching urls with different methods (Rails RESTful routes: get#users post#users || get#user/:id put#user/:id) you may need to post and put to secure but redirect to http on get.
54
-
55
- config.middleware.use Rack::SslEnforcer, :only => [%r{^/users/}], :mixed => true
56
-
57
- The above will allow you to post/put from the secure/non-secure urls keeping the original schema.
58
-
59
- To set HSTS expiry and subdomain inclusion (defaults: one year, true). Strict option disables HSTS.
60
-
61
- config.middleware.use Rack::SslEnforcer, :hsts => { :expires => 500, :subdomains => false }
62
- config.middleware.use Rack::SslEnforcer, :hsts => true # equivalent to { :expires => 31536000, :subdomains => true }
63
-
64
- Finally you might want to share a cookie based session between http and https.
65
- This is not possible by default with Rack::SslEnforcer for security reasons.
66
- See: [http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking]
67
-
68
- Nevertheless, you can set the option :force_secure_cookies to false in order to be able to share a cookie based session between http and https:
69
-
70
- config.middleware.use Rack::SslEnforcer, :only => "/login", :force_secure_cookies => false
71
-
72
- But be aware that if you do so, you have to make sure that the content of you cookie is encoded.
73
- This can be done using a coder with Rack::Session::Cookie.
74
- See: [https://github.com/rack/rack/blob/master/lib/rack/session/cookie.rb#L28-42]
75
-
76
-
77
- == TODO
78
-
79
- * Add configuration option to specify local http / https ports
80
- * Cleanup tests
81
-
82
-
83
- == Contributors
84
-
85
- * {Dan Mayer}[http://github.com/danmayer]
86
- * {Rémy Coutable}[http://github.com/rymai]
87
- * {Thibaud Guillaume-Gentil}[http://github.com/thibaudgg]
88
- * {Paul Annesley}[https://github.com/pda]
89
- * {Saimon Moore}[https://github.com/saimonmoore]
90
-
91
-
92
- == Credits
93
-
94
- Flagging cookies as secure functionality and HSTS support is greatly inspired by {Joshua Peek's Rack::SSL}[https://github.com/josh/rack-ssl]
95
-
96
-
97
- == Note on Patches/Pull Requests
98
-
99
- * Fork the project.
100
- * Make your feature addition or bug fix.
101
- * Add tests for it. This is important so I don't break it in a
102
- future version unintentionally.
103
- * Commit, do not mess with rakefile, version, or history.
104
- (if you want to have your own version,
105
- that is fine but bump version in a commit by itself I can ignore when I pull)
106
- * Send me a pull request. Bonus points for topic branches.
107
-
108
-
109
- == Copyright
110
-
111
- Copyright (c) 2010 Tobias Matthies. See LICENSE for details.