safe_redirect 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 432d56c2fe2e256b7040f00a82822d9778ef257c
4
- data.tar.gz: 4cd2ccdf44e92e79d613b5ad960b81f486a80009
3
+ metadata.gz: 73595819096734251288a747c73948f27deb1470
4
+ data.tar.gz: f1f7de8ed97ee7a9bf50dc7e67d687e896d19e40
5
5
  SHA512:
6
- metadata.gz: e615e2700b962aae967a8894aef1af26484d5ccf7ba1b4c8868090ea49f426f9007ec0e5950f93dc20cb7624049c3d0129fe963470be00073da1f741de92b023
7
- data.tar.gz: 71d7558aac96b2a794daf3edb895998b8321b4e03fbde1ed182964612171d8252469034d6927ebc483b7a7b04b682466fd16da987c31c3be71321ba27ce9e2fb
6
+ metadata.gz: 645b2a52d54d86d5e4e023e511c85ec1fc3ff7f057f25561bb430ebd18708ba0fe158756100171263eb0eedbb4c3c096e7bff26c7ec9cebab8bf3f647e9f897f
7
+ data.tar.gz: f8fc5d77f0eb82bf925abfcb8d701b690d9f40e007bd8df03f1ae33c89928c6a94b81417d196889d64c21fdd9b4f9ef3ab33fcd49d5d9e9cbb9a2628e73377b1
data/README.md CHANGED
@@ -21,6 +21,14 @@ SafeRedirect.configure do |config|
21
21
  end
22
22
  ```
23
23
 
24
+ We can also use wildcard subdomain on domain whitelists (thanks to [Mike Campbell](https://github.com/mikecmpbll)).
25
+
26
+ ```rb
27
+ SafeRedirect.configure do |config|
28
+ config.domain_whitelists = ['*.foo.org'] # whitelisting foo.org, m.foo.org, www.foo.org, ...
29
+ end
30
+ ```
31
+
24
32
  Add this line to the controllers you wish to secure from open redirection.
25
33
 
26
34
  ```rb
@@ -12,11 +12,20 @@ module SafeRedirect
12
12
  end
13
13
 
14
14
  class Configuration
15
- attr_accessor :default_path, :domain_whitelists
15
+ attr_accessor :default_path
16
+ attr_reader :domain_whitelists
16
17
 
17
18
  def initialize
18
19
  self.default_path = '/'
19
20
  self.domain_whitelists = []
20
21
  end
22
+
23
+ def domain_whitelists=(whitelists)
24
+ if whitelists.any?{ |w| w =~ /\*\z/ }
25
+ raise ArgumentError, "whitelisted domain cannot end with a glob (*)"
26
+ end
27
+
28
+ @domain_whitelists = whitelists
29
+ end
21
30
  end
22
31
  end
@@ -3,17 +3,37 @@ require 'uri'
3
3
  module SafeRedirect
4
4
  def safe_domain?(uri)
5
5
  return true if uri.host.nil? && uri.scheme.nil?
6
- SafeRedirect.configuration.domain_whitelists.include?(uri.host)
6
+ return false if uri.host.nil?
7
+
8
+ SafeRedirect.configuration.domain_whitelists.any? do |domain|
9
+ if domain.include?("*")
10
+ rf = domain.split(/(\*)/).map{ |f| f == "*" ? "\\w*" : Regexp.escape(f) }
11
+ regexp = Regexp.new("\\A#{rf.join}\\z")
12
+
13
+ safe = uri.host.match(regexp)
14
+
15
+ # if domain starts with *. and contains no other wildcards, include the
16
+ # naked domain too (e.g. foo.org when *.foo.org is the whitelist)
17
+ if domain =~ /\A\*\.[^\*]+\z/
18
+ naked_domain = domain.gsub("*.", "")
19
+ safe || uri.host == naked_domain
20
+ else
21
+ safe
22
+ end
23
+ else
24
+ uri.host == domain
25
+ end
26
+ end
7
27
  end
8
28
 
9
29
  def safe_path(path)
10
30
  case path
11
31
  when String
12
32
  clean_path(path)
13
- when Symbol, Hash
14
- path
33
+ when Hash
34
+ sanitize_hash(path)
15
35
  else
16
- SafeRedirect.configuration.default_path
36
+ path
17
37
  end
18
38
  end
19
39
 
@@ -27,8 +47,16 @@ module SafeRedirect
27
47
 
28
48
  def clean_path(path)
29
49
  uri = URI.parse(path)
30
- safe_domain?(uri) ? path : '/'
50
+ safe_domain?(uri) ? path : SafeRedirect.configuration.default_path
31
51
  rescue URI::InvalidURIError
32
- '/'
52
+ SafeRedirect.configuration.default_path
53
+ end
54
+
55
+ def sanitize_hash(hash)
56
+ protocol = hash[:protocol] || 'http'
57
+ host = hash[:host]
58
+ uri = URI.parse("#{protocol}://#{host}")
59
+ hash.delete(:host) unless safe_domain?(uri)
60
+ hash
33
61
  end
34
62
  end
@@ -1,3 +1,3 @@
1
1
  module SafeRedirect
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.2'
3
3
  end
@@ -6,6 +6,16 @@ module SafeRedirect
6
6
  reset_config
7
7
  end
8
8
 
9
+ it 'errors if you try to end whitelisted domain with glob' do
10
+ config_update = -> do
11
+ SafeRedirect.configure do |config|
12
+ config.domain_whitelists = ["foo.*"]
13
+ end
14
+ end
15
+
16
+ expect(config_update).to raise_error(ArgumentError)
17
+ end
18
+
9
19
  it 'default default_path is /' do
10
20
  expect(SafeRedirect.configuration.default_path).to eq('/')
11
21
  end
@@ -15,8 +15,11 @@ module SafeRedirect
15
15
  '/',
16
16
  '/foobar',
17
17
  'http://www.twitter.com',
18
+ 'http://blah.foo.org',
19
+ 'http://foo.org',
18
20
  :back,
19
- { controller: 'home', action: 'index' }
21
+ ['some', 'object'],
22
+ { controller: 'home', action: 'index' },
20
23
  ]
21
24
 
22
25
  UNSAFE_PATHS = [
@@ -26,6 +29,7 @@ module SafeRedirect
26
29
  "%@%@%@%@%@%@%@%@%@%@evil.com",
27
30
  "https://www-bukalapak.com",
28
31
  "https://www.bukalapak.com\n.evil.com",
32
+ "http://blah.blah.foo.org",
29
33
  ]
30
34
 
31
35
  SAFE_PATHS.each do |path|
@@ -36,10 +40,16 @@ module SafeRedirect
36
40
 
37
41
  UNSAFE_PATHS.each do |path|
38
42
  it "considers #{path} an unsafe path" do
39
- expect(Controller.safe_path(path)).to eq('/')
43
+ expect(Controller.safe_path(path)).to eq(SafeRedirect.configuration.default_path)
40
44
  end
41
45
  end
42
46
 
47
+ it 'filters host, port, and protocol options when hash is passed to safe_path' do
48
+ hash = { host: 'yahoo.com', port: 80, protocol: 'https', controller: 'home', action: 'index' }
49
+ safe_hash = { port: 80, protocol: 'https', controller: 'home', action: 'index' }
50
+ expect(Controller.safe_path(hash)).to eq(safe_hash)
51
+ end
52
+
43
53
  it 'can use redirect_to method with only the target path' do
44
54
  Controller.redirect_to '/'
45
55
  end
data/spec/spec_helper.rb CHANGED
@@ -10,7 +10,7 @@ end
10
10
  def load_config
11
11
  SafeRedirect.configure do |config|
12
12
  config.default_path = '/sdsdkkk'
13
- config.domain_whitelists = ['www.twitter.com', 'www.bukalapak.com']
13
+ config.domain_whitelists = %w{www.twitter.com www.bukalapak.com *.foo.org}
14
14
  end
15
15
  end
16
16
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safe_redirect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edwin Tunggawan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-05 00:00:00.000000000 Z
11
+ date: 2016-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -71,3 +71,4 @@ test_files:
71
71
  - spec/lib/safe_redirect/configuration_spec.rb
72
72
  - spec/lib/safe_redirect/safe_redirect_spec.rb
73
73
  - spec/spec_helper.rb
74
+ has_rdoc: