subdomainbox 0.2.0 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,10 +1,22 @@
1
1
  subdomainbox
2
2
  ============
3
3
 
4
- Subdomain boxing was inspired by Egor Homakov's [post on pageboxing](http://homakov.blogspot.com/2013/02/pagebox-website-gatekeeper.html). Subdomain boxing limits the reach of any XSS attacks. If an attacker manages to insert javascript onto a page of your application, the javascript on that page will be unable to read data from or post data to any pages on different subdomains in your application. Post protection is achieved by creating a separate CSRF token for each subdomain. CSRF protection is also strengthened by changing the CSRF token based on session id.
4
+ Subdomain boxing was inspired by Egor Homakov's [post on pageboxing](http://homakov.blogspot.com/2013/02/pagebox-website-gatekeeper.html). Subdomain boxing limits the reach of any XSS attacks. If an attacker manages to insert javascript onto a page of your application, the javascript on that page will be unable to read data from or post data to any pages on different subdomains in your application. POST protection is achieved by creating a separate CSRF token for each subdomain. CSRF protection is also strengthened by changing the CSRF token based on session id.
5
5
 
6
6
  The subdomainbox gem is simple to add even to existing Rails applications:
7
7
 
8
+ class ApplicationController
9
+
10
+ # set up a default subdomain box for all controllers that won't get an explicit subdomain box
11
+ # this protects regular pages that don't get a dedicated subdomain box from being accessed
12
+ # from a subdomain boxed page
13
+ default_subdomainbox ''
14
+
15
+ ...
16
+
17
+ end
18
+
19
+
8
20
  class PostsController < ApplicationController
9
21
 
10
22
  subdomainbox 'posts', :only => :index
@@ -25,6 +37,32 @@ The subdomainbox gem is simple to add even to existing Rails applications:
25
37
  end
26
38
 
27
39
 
40
+ class AvatarIcon < ApplicationController
41
+
42
+ # for controllers that need to be accessed from many places, that don't need boxing
43
+ # protection, the default subdomain box can be removed (thereby allowing ajax calls
44
+ # from any subdomain)
45
+ remove_default_subdomainbox
46
+
47
+ ...
48
+
49
+ end
50
+
51
+ There is no need to adjust your routes or your path / url helpers. Subdomainbox automatically redirects the browser as needed based on your subdomainbox directives.
52
+
53
+
54
+ Installation
55
+ ============
56
+
57
+ Add subdomainbox to your gemfile and bundle install.
58
+
59
+ Run the generator (for generating the CSRF token secret):
60
+
61
+ $ rails generate subdomainbox
62
+
63
+ Make sure your application has a wildcard SSL certificate.
64
+
65
+
28
66
  Testing
29
67
  =======
30
68
 
@@ -59,4 +97,4 @@ Contributing to subdomainbox
59
97
  Credits
60
98
  =======
61
99
 
62
- Inspired by Egor Homakov's [post on pageboxing](http://homakov.blogspot.com/2013/02/pagebox-website-gatekeeper.html).
100
+ Written by Daniel Nelson. Inspired by Egor Homakov's [post on pageboxing](http://homakov.blogspot.com/2013/02/pagebox-website-gatekeeper.html).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.3
data/lib/subdomainbox.rb CHANGED
@@ -4,14 +4,39 @@ module ActionController
4
4
  class SubdomainboxDomainViolation < StandardError
5
5
  end
6
6
 
7
- def self.subdomainbox(allowed, options={})
8
- before_filter(lambda { subdomainbox(:allowed => allowed) }, options)
7
+ def self.subdomainbox(box_definitions, options={})
8
+ prepend_before_filter(lambda { subdomainbox(box_definitions) }, options)
9
9
  end
10
10
 
11
- def subdomainbox(options)
12
- allowed = subdomainbox_process_definitions(options)
11
+ def self.remove_default_subdomainbox(options={})
12
+ prepend_before_filter(:remove_default_subdomainbox, options)
13
+ end
14
+
15
+ def self.default_subdomainbox(box_definitions)
16
+ before_filter(lambda { default_subdomainbox(box_definitions) }, {})
17
+ end
18
+
19
+ def subdomainbox(box_definitions)
20
+ @remove_default_subdomainbox = true
21
+ allowed = subdomainbox_process_definitions(box_definitions)
13
22
  subdomain_match = subdomainbox_find_subdomain_match(allowed)
14
- subdomainbox_no_subdomain_match!(allowed) if subdomain_match.empty?
23
+ subdomainbox_no_subdomain_match!(allowed) if subdomain_match.nil?
24
+ end
25
+
26
+ # for controllers that need to be accessed from many places, that don't need boxing
27
+ # protection, the default subdomain box can be removed (thereby allowing ajax calls
28
+ # from any subdomain)
29
+ #
30
+ def remove_default_subdomainbox
31
+ @remove_default_subdomainbox = true
32
+ end
33
+
34
+ # set up a default subdomain box for all controllers that won't get an explicit subdomain box
35
+ # this protects regular pages that don't get a dedicated subdomain box from being accessed
36
+ # from a subdomain boxed page
37
+ #
38
+ def default_subdomainbox(box_definitions)
39
+ subdomainbox(box_definitions) unless @remove_default_subdomainbox
15
40
  end
16
41
 
17
42
  private
@@ -44,31 +69,35 @@ module ActionController
44
69
  end
45
70
 
46
71
  def subdomainbox_find_subdomain_match(allowed)
47
- allowed.each do |allowed_subdomain, separator, allowed_id_name|
48
- if allowed_subdomain == ''
49
- next unless request.subdomain.nil? || request.subdomain.empty?
72
+ matches = allowed.collect do |allowed_subdomain, separator, allowed_id_name|
73
+ subdomainbox_check_subdomain(allowed_subdomain, separator, allowed_id_name)
74
+ end
75
+ matches.compact.first
76
+ end
77
+
78
+ def subdomainbox_check_subdomain(allowed_subdomain, separator, allowed_id_name)
79
+ return nil if allowed_subdomain == '' unless request.subdomain == ''
80
+ allowed_prefix = "#{allowed_subdomain}#{separator}"
81
+ return nil unless request.subdomain.index(allowed_prefix) == 0
82
+
83
+ id = request.subdomain[allowed_prefix.length..-1]
84
+ if allowed_id_name
85
+ return nil if id == ''
86
+ if params.keys.include?(allowed_id_name)
87
+ return nil unless id == params[allowed_id_name]
50
88
  else
51
- next unless request.subdomain =~ /\A#{allowed_subdomain}\.?/
89
+ params[allowed_id_name] = id
52
90
  end
53
- if allowed_id_name
54
- if id = request.subdomain.sub(/\A#{allowed_subdomain}\.?/, '')
55
- if params.keys.include?(allowed_id_name)
56
- return [] unless id == params[allowed_id_name]
57
- else
58
- params[allowed_id_name] = id
59
- end
60
- end
61
- end
62
- return [allowed_subdomain, separator, id]
91
+ else
92
+ return nil unless id == ''
63
93
  end
64
- []
94
+ [allowed_subdomain, separator, id]
65
95
  end
66
96
 
67
- def subdomainbox_process_definitions(options)
97
+ def subdomainbox_process_definitions(box_definitions)
68
98
  allowed = []
69
- raw_definitions = options[:allowed]
70
- raw_definitions = [raw_definitions] unless raw_definitions.is_a?(Array)
71
- raw_definitions.each do |definition|
99
+ box_definitions = [box_definitions] unless box_definitions.is_a?(Array)
100
+ box_definitions.each do |definition|
72
101
  discard, allowed_subdomain, separator, allowed_id_name = definition.match(/([^%]*?)(\.?)\%\{([^}]*)\}/).to_a
73
102
  allowed_subdomain = definition if allowed_subdomain.nil?
74
103
  allowed_id_name = allowed_id_name if allowed_id_name
@@ -33,7 +33,7 @@ describe ActionController::Base do
33
33
  params = { 'pet_id' => 'abc' }
34
34
  controller.stub(:params).and_return(params)
35
35
  lambda {
36
- controller.subdomainbox :allowed => 'pets.%{pet_id}'
36
+ controller.subdomainbox('pets.%{pet_id}')
37
37
  }.should_not raise_error
38
38
  end
39
39
  end
@@ -44,14 +44,14 @@ describe ActionController::Base do
44
44
  params = { 'id' => 'efg' }
45
45
  controller.stub(:params).and_return(params)
46
46
  lambda {
47
- controller.subdomainbox :allowed => 'pets.%{pet_id}'
47
+ controller.subdomainbox('pets.%{pet_id}')
48
48
  }.should_not raise_error
49
49
  end
50
50
 
51
51
  it "should set a param of the specified name on params" do
52
52
  params = {}
53
53
  controller.stub(:params).and_return(params)
54
- controller.subdomainbox :allowed => 'pets.%{pet_id}'
54
+ controller.subdomainbox('pets.%{pet_id}')
55
55
  params['pet_id'].should == 'abc'
56
56
  end
57
57
  end
@@ -78,11 +78,11 @@ describe ActionController::Base do
78
78
 
79
79
  controller.should_receive(:redirect_to).with('https://pets.efg.peanuts.com:8080/pets?e=123')
80
80
  request.stub(:subdomain).and_return('pets')
81
- controller.subdomainbox :allowed => 'pets.%{pet_id}'
81
+ controller.subdomainbox('pets.%{pet_id}')
82
82
 
83
83
  controller.should_receive(:redirect_to).with('https://pets.efg.peanuts.com:8080/pets?e=123')
84
84
  request.stub(:subdomain).and_return('pets.abc')
85
- controller.subdomainbox :allowed => 'pets.%{pet_id}'
85
+ controller.subdomainbox('pets.%{pet_id}')
86
86
  end
87
87
  end
88
88
 
@@ -90,7 +90,7 @@ describe ActionController::Base do
90
90
  it "should not raise an exception or redirect" do
91
91
  controller.should_not_receive(:redirect_to)
92
92
  lambda {
93
- controller.subdomainbox :allowed => 'pets'
93
+ controller.subdomainbox('pets')
94
94
  }.should_not raise_error
95
95
  end
96
96
 
@@ -101,7 +101,7 @@ describe ActionController::Base do
101
101
  controller.stub(:params).and_return(params)
102
102
  controller.should_not_receive(:redirect_to)
103
103
  lambda {
104
- controller.subdomainbox :allowed => 'pets.%{pet_id}'
104
+ controller.subdomainbox('pets.%{pet_id}')
105
105
  }.should_not raise_error
106
106
  end
107
107
  end
@@ -111,7 +111,7 @@ describe ActionController::Base do
111
111
  it "should not raise an exception or redirect" do
112
112
  controller.should_not_receive(:redirect_to)
113
113
  lambda {
114
- controller.subdomainbox :allowed => ['activities', 'pets']
114
+ controller.subdomainbox(['activities', 'pets'])
115
115
  }.should_not raise_error
116
116
  end
117
117
 
@@ -122,7 +122,7 @@ describe ActionController::Base do
122
122
  controller.stub(:params).and_return(params)
123
123
  controller.should_not_receive(:redirect_to)
124
124
  lambda {
125
- controller.subdomainbox :allowed => ['activities%{pet_id}', 'pets%{pet_id}']
125
+ controller.subdomainbox(['activities%{pet_id}', 'pets%{pet_id}'])
126
126
  }.should_not raise_error
127
127
  end
128
128
  end
@@ -152,18 +152,18 @@ describe ActionController::Base do
152
152
  flash.should_receive(:[]=).with(:notice, 'The notice flash')
153
153
  flash.should_receive(:[]=).with(:info, 'The info flash')
154
154
 
155
- controller.subdomainbox :allowed => 'pets'
155
+ controller.subdomainbox('pets')
156
156
  end
157
157
 
158
158
  it "should redirect to the same path (including http variables) at the specified subdomain prefixing the root of the origin domain" do
159
159
  controller.should_receive(:redirect_to).with('https://pets.peanuts.com:8080/pets?e=123')
160
- controller.subdomainbox :allowed => 'pets'
160
+ controller.subdomainbox('pets')
161
161
  end
162
162
 
163
163
  context "when the specified subdomain is an empty string" do
164
164
  it "should redirect to the root domain" do
165
165
  controller.should_receive(:redirect_to).with('https://peanuts.com:8080/pets?e=123')
166
- controller.subdomainbox :allowed => ''
166
+ controller.subdomainbox('')
167
167
  end
168
168
  end
169
169
 
@@ -172,7 +172,7 @@ describe ActionController::Base do
172
172
  controller.should_receive(:redirect_to).with('https://pets.abc.peanuts.com:8080/pets?e=123')
173
173
  params = { 'pet_id' => 'abc' }
174
174
  controller.stub(:params).and_return(params)
175
- controller.subdomainbox :allowed => 'pets.%{pet_id}'
175
+ controller.subdomainbox('pets.%{pet_id}')
176
176
  end
177
177
 
178
178
  context "when no id param matching the specified id name exists" do
@@ -180,7 +180,7 @@ describe ActionController::Base do
180
180
  controller.should_receive(:redirect_to).with('https://pets.peanuts.com:8080/pets?e=123')
181
181
  params = { 'id' => 'abc' }
182
182
  controller.stub(:params).and_return(params)
183
- controller.subdomainbox :allowed => 'pets.%{pet_id}'
183
+ controller.subdomainbox('pets.%{pet_id}')
184
184
  end
185
185
  end
186
186
  end
@@ -190,7 +190,7 @@ describe ActionController::Base do
190
190
  controller.should_receive(:redirect_to).with('https://pets.peanuts.com:8080/pets?e=123')
191
191
  params = { 'pet_id' => 'abc' }
192
192
  controller.stub(:params).and_return(params)
193
- controller.subdomainbox :allowed => 'pets'
193
+ controller.subdomainbox('pets')
194
194
  end
195
195
  end
196
196
  end
@@ -199,7 +199,7 @@ describe ActionController::Base do
199
199
  it "should raise SubdomainboxDomainViolation" do
200
200
  request.stub(:get?).and_return(false)
201
201
  lambda {
202
- controller.subdomainbox :allowed => 'pets'
202
+ controller.subdomainbox('pets')
203
203
  }.should raise_error(ActionController::Base::SubdomainboxDomainViolation)
204
204
  end
205
205
  end
@@ -219,7 +219,7 @@ describe ActionController::Base do
219
219
  it "should redirect to the same path (http variables) at the first subdomain in the list prefixing the root of the origin domain" do
220
220
  request.stub(:get?).and_return(true)
221
221
  controller.should_receive(:redirect_to).with('https://activities.peanuts.com:8080/pets?e=123')
222
- controller.subdomainbox :allowed => ['activities', 'pets']
222
+ controller.subdomainbox(['activities', 'pets'])
223
223
  end
224
224
  end
225
225
 
@@ -227,7 +227,7 @@ describe ActionController::Base do
227
227
  it "should raise SubdomainboxDomainViolation" do
228
228
  request.stub(:get?).and_return(false)
229
229
  lambda {
230
- controller.subdomainbox :allowed => ['activities', 'pets']
230
+ controller.subdomainbox(['activities', 'pets'])
231
231
  }.should raise_error(ActionController::Base::SubdomainboxDomainViolation)
232
232
  end
233
233
  end
@@ -247,18 +247,9 @@ describe ActionController::Base do
247
247
  it "should not raise an exception" do
248
248
  request.stub(:subdomain).and_return('pets')
249
249
  lambda {
250
- controller.subdomainbox :allowed => 'pets'
250
+ controller.subdomainbox('pets')
251
251
  }.should_not raise_error
252
252
  end
253
-
254
- context "when the origin subdomain includes an id" do
255
- it "should not raise an exception" do
256
- request.stub(:subdomain).and_return('pets.abc')
257
- lambda {
258
- controller.subdomainbox :allowed => 'pets'
259
- }.should_not raise_error
260
- end
261
- end
262
253
  end
263
254
 
264
255
 
@@ -266,18 +257,9 @@ describe ActionController::Base do
266
257
  it "should not raise an exception" do
267
258
  request.stub(:subdomain).and_return('pets')
268
259
  lambda {
269
- controller.subdomainbox :allowed => ['activities', 'pets']
260
+ controller.subdomainbox(['activities', 'pets'])
270
261
  }.should_not raise_error
271
262
  end
272
-
273
- context "when the origin subdomain includes an id" do
274
- it "should not raise an exception" do
275
- request.stub(:subdomain).and_return('pets.abc')
276
- lambda {
277
- controller.subdomainbox :allowed => ['activities', 'pets']
278
- }.should_not raise_error
279
- end
280
- end
281
263
  end
282
264
 
283
265
 
@@ -286,7 +268,7 @@ describe ActionController::Base do
286
268
  # recommend using around filter to rescue these exceptions and respond accordingly from that one place
287
269
  request.stub(:subdomain).and_return('houses')
288
270
  lambda {
289
- controller.subdomainbox :allowed => 'pets'
271
+ controller.subdomainbox('pets')
290
272
  }.should raise_error(ActionController::Base::SubdomainboxDomainViolation)
291
273
  end
292
274
 
@@ -294,7 +276,7 @@ describe ActionController::Base do
294
276
  it "should not raise an exception" do
295
277
  request.stub(:subdomain).and_return('houses.abc')
296
278
  lambda {
297
- controller.subdomainbox :allowed => 'pets'
279
+ controller.subdomainbox('pets')
298
280
  }.should raise_error
299
281
  end
300
282
  end
@@ -304,7 +286,7 @@ describe ActionController::Base do
304
286
  it "should raise SubdomainboxDomainViolation" do
305
287
  request.stub(:subdomain).and_return('houses')
306
288
  lambda {
307
- controller.subdomainbox :allowed => ['activities', 'pets']
289
+ controller.subdomainbox(['activities', 'pets'])
308
290
  }.should raise_error(ActionController::Base::SubdomainboxDomainViolation)
309
291
  end
310
292
 
@@ -312,15 +294,53 @@ describe ActionController::Base do
312
294
  it "should raise an exception" do
313
295
  request.stub(:subdomain).and_return('houses.abc')
314
296
  lambda {
315
- controller.subdomainbox :allowed => ['activities', 'pets']
297
+ controller.subdomainbox(['activities', 'pets'])
316
298
  }.should raise_error(ActionController::Base::SubdomainboxDomainViolation)
317
299
  end
318
300
  end
319
301
  end
320
302
 
303
+ context "when the subdomainbox specifies no id, but the current subdomain includes an id" do
304
+ it "should raise an exception (eg: a specific post is trying to reach the index of posts)" do
305
+ request.stub(:subdomain).and_return('pets-abc')
306
+ lambda {
307
+ controller.subdomainbox('pets')
308
+ }.should raise_error(ActionController::Base::SubdomainboxDomainViolation)
309
+ end
310
+ end
311
+
312
+ context "when the subdomainbox specifies multiple subdomains, some with an id, some without an id" do
313
+ it "should raise an exception whenever the subdomain includes an id but matches a subdomainbox that specifies no id" do
314
+ request.stub(:subdomain).and_return('pets-abc')
315
+ lambda {
316
+ controller.subdomainbox(['pets', 'houses-%{id}'])
317
+ }.should raise_error(ActionController::Base::SubdomainboxDomainViolation)
318
+ end
319
+
320
+ it "should raise an exception whenever the subdomain omits an id but matches a subdomainbox that specifies an id" do
321
+ request.stub(:subdomain).and_return('houses')
322
+ lambda {
323
+ controller.subdomainbox(['pets', 'houses-%{id}'])
324
+ }.should raise_error(ActionController::Base::SubdomainboxDomainViolation)
325
+ end
326
+
327
+ it "should not raise an exception whenever the subdomain includes an id and matches a subdomainbox that specifies an id" do
328
+ request.stub(:subdomain).and_return('houses-abc')
329
+ lambda {
330
+ controller.subdomainbox(['pets', 'houses-%{id}'])
331
+ }.should_not raise_error
332
+ end
333
+
334
+ it "should not raise an exception whenever the subdomain omits an id and matches a subdomainbox that specifies no id" do
335
+ request.stub(:subdomain).and_return('pets')
336
+ lambda {
337
+ controller.subdomainbox(['pets', 'houses-%{id}'])
338
+ }.should_not raise_error
339
+ end
340
+ end
341
+
321
342
  end
322
343
 
323
344
  end
324
345
 
325
-
326
346
  end
@@ -0,0 +1,70 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "subdomainbox"
8
+ s.version = "0.3.3"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Daniel Nelson"]
12
+ s.date = "2013-03-16"
13
+ s.description = "use subdomains to prevent XSS from accessing your entire application if it should happen to be injected into some page in your app"
14
+ s.email = "dnelson@centresource.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ ".rvmrc",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.md",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "lib/generators/subdomainbox_generator.rb",
30
+ "lib/secure_xsrf_token.rb",
31
+ "lib/subdomainbox.rb",
32
+ "spec/secure_xsrf_token_spec.rb",
33
+ "spec/spec_helper.rb",
34
+ "spec/subdomainbox_spec.rb",
35
+ "subdomainbox.gemspec"
36
+ ]
37
+ s.homepage = "http://github.com/populr/subdomainbox"
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = "1.8.10"
41
+ s.summary = "prevent XSS incursions from accessing entire application"
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<uuidtools>, [">= 0"])
48
+ s.add_development_dependency(%q<rspec>, ["= 2.10.0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
50
+ s.add_development_dependency(%q<pry>, [">= 0"])
51
+ s.add_development_dependency(%q<pry-nav>, [">= 0"])
52
+ s.add_development_dependency(%q<pry-stack_explorer>, [">= 0"])
53
+ else
54
+ s.add_dependency(%q<uuidtools>, [">= 0"])
55
+ s.add_dependency(%q<rspec>, ["= 2.10.0"])
56
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
57
+ s.add_dependency(%q<pry>, [">= 0"])
58
+ s.add_dependency(%q<pry-nav>, [">= 0"])
59
+ s.add_dependency(%q<pry-stack_explorer>, [">= 0"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<uuidtools>, [">= 0"])
63
+ s.add_dependency(%q<rspec>, ["= 2.10.0"])
64
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
65
+ s.add_dependency(%q<pry>, [">= 0"])
66
+ s.add_dependency(%q<pry-nav>, [">= 0"])
67
+ s.add_dependency(%q<pry-stack_explorer>, [">= 0"])
68
+ end
69
+ end
70
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subdomainbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-15 00:00:00.000000000 Z
12
+ date: 2013-03-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: uuidtools
16
- requirement: &2152124540 !ruby/object:Gem::Requirement
16
+ requirement: &2156188260 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152124540
24
+ version_requirements: *2156188260
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2152122180 !ruby/object:Gem::Requirement
27
+ requirement: &2156187400 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - =
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.10.0
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2152122180
35
+ version_requirements: *2156187400
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: jeweler
38
- requirement: &2152121100 !ruby/object:Gem::Requirement
38
+ requirement: &2156186760 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.8.4
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2152121100
46
+ version_requirements: *2156186760
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: pry
49
- requirement: &2152119700 !ruby/object:Gem::Requirement
49
+ requirement: &2156095860 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2152119700
57
+ version_requirements: *2156095860
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: pry-nav
60
- requirement: &2152133520 !ruby/object:Gem::Requirement
60
+ requirement: &2156091720 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2152133520
68
+ version_requirements: *2156091720
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pry-stack_explorer
71
- requirement: &2152131660 !ruby/object:Gem::Requirement
71
+ requirement: &2152127700 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2152131660
79
+ version_requirements: *2152127700
80
80
  description: use subdomains to prevent XSS from accessing your entire application
81
81
  if it should happen to be injected into some page in your app
82
82
  email: dnelson@centresource.com
@@ -101,6 +101,7 @@ files:
101
101
  - spec/secure_xsrf_token_spec.rb
102
102
  - spec/spec_helper.rb
103
103
  - spec/subdomainbox_spec.rb
104
+ - subdomainbox.gemspec
104
105
  homepage: http://github.com/populr/subdomainbox
105
106
  licenses:
106
107
  - MIT
@@ -116,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
117
  version: '0'
117
118
  segments:
118
119
  - 0
119
- hash: 1510684682428060724
120
+ hash: 21616900788936139
120
121
  required_rubygems_version: !ruby/object:Gem::Requirement
121
122
  none: false
122
123
  requirements: