faraday-restrict-ip-addresses 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 62485d16c4a53ef8a30e2b940b858dc44e8077bd
4
+ data.tar.gz: 35a0b0937db1175f7d2eaaa0c4b16271b2f85283
5
+ SHA512:
6
+ metadata.gz: 531fae725622bc033b69d27973ebfd4bc151f7626fe8c1da52c075bd5382323c081acc1dbd79e8e28c3c9729fe7fdd9f9d790286a8c975243cef5b903b7909d9
7
+ data.tar.gz: d38b0a07810abc7065bf0fe37e3643d0daa712af6630a9b9b911ac69b07a39ce1c83295ff3a2c646912b0cb5206ff3b1cafadcbd04cfda33dc2da5538065d5a4
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ Faraday::RestrictIPAddresses
2
+ ============================
3
+
4
+ Prevent Faraday from hitting an arbitrary list of IP addresses, with helpers
5
+ for RFC 1918 networks and localhost.
6
+
7
+ System DNS facilities are used, so lookups should be cached.
8
+
9
+ Usage
10
+ =====
11
+
12
+ ```ruby
13
+ faraday = Faraday.new do |builder|
14
+ builder.request :url_encoded
15
+ builder.use :restrict_ip_addresses, deny_rfc1918: true,
16
+ allow_localhost: true
17
+ deny: ['8.0.0.0/8',
18
+ '224.0.0.0/7'],
19
+ allow: ['192.168.0.0/24']
20
+ builder.adapter Faraday.default_adapter
21
+ end
22
+
23
+ faraday.get 'http://www.badgerbadgerbadger.com' # 150.0.0.150 or something
24
+ # => cool
25
+
26
+ faraday.get 'http://malicious-callback.com # 172.0.0.150, maybe a secret internal server? Maybe not?
27
+ # => raises Faraday::RestrictIPAddresses::AddressNotAllowed
28
+ ```
29
+
30
+ Permit/denied order is:
31
+
32
+ * All addresses are allowed, except
33
+ * Addresses that are denied, except
34
+ * Addresses that are allowed.
35
+
36
+ #### Author
37
+
38
+ Dat @bhuga with shoutouts to @mastahyeti's [gist.](https://gist.github.com/mastahyeti/8497793)
39
+
40
+ #### UNLICENSE
41
+
42
+ It's right there.
43
+
44
+
data/UNLICENSE ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
@@ -0,0 +1,20 @@
1
+ require_relative 'lib/faraday/restrict_ip_addresses'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.add_dependency 'faraday', ['>= 0.8', '< 0.9']
5
+ spec.add_development_dependency 'bundler', '~> 1.0'
6
+ spec.authors = ["Ben Lavender"]
7
+ spec.description = %q{Restrict the IP addresses Faraday will connect to}
8
+ spec.email = ['bhuga@github.com']
9
+ spec.files = %w(UNLICENSE README.md faraday-restrict-ip-addresses.gemspec)
10
+ spec.files += Dir.glob("lib/**/*.rb")
11
+ spec.files += Dir.glob("spec/**/*")
12
+ spec.homepage = 'https://github.com/bhuga/faraday-restrict-ip-addresses'
13
+ spec.licenses = ['Unlicense']
14
+ spec.name = 'faraday-restrict-ip-addresses'
15
+ spec.require_paths = ['lib']
16
+ spec.required_rubygems_version = '>= 1.3.5'
17
+ spec.summary = spec.description
18
+ spec.test_files += Dir.glob("spec/**/*")
19
+ spec.version = Faraday::RestrictIPAddresses::VERSION
20
+ end
@@ -0,0 +1,48 @@
1
+ require 'faraday'
2
+ require 'ipaddr'
3
+
4
+ module Faraday
5
+ class RestrictIPAddresses < Faraday::Middleware
6
+ class AddressNotAllowed < Faraday::Error::ClientError ; end
7
+ VERSION = '0.0.1'
8
+
9
+ RFC_1918_NETWORKS = %w(
10
+ 127.0.0.0/8
11
+ 10.0.0.0/8
12
+ 172.16.0.0/12
13
+ 192.168.0.0/16
14
+ ).map { |net| IPAddr.new(net) }
15
+
16
+ def initialize(app, options = {})
17
+ super(app)
18
+ @denied_networks = (options[:deny] || []).map { |n| IPAddr.new(n) }
19
+ @allowed_networks = (options[:allow] || []).map { |n| IPAddr.new(n) }
20
+
21
+ @denied_networks += RFC_1918_NETWORKS if options[:deny_rfc1918]
22
+ @allowed_networks += [IPAddr.new('127.0.0.1')] if options[:allow_localhost]
23
+ end
24
+
25
+ def call(env)
26
+ raise AddressNotAllowed.new "Address not allowed for #{env[:url]}" if denied?(env)
27
+ @app.call(env)
28
+ end
29
+
30
+ def denied?(env)
31
+ addresses(env[:url].host).any? { |a| denied_ip?(a) }
32
+ end
33
+
34
+ def denied_ip?(address)
35
+ @denied_networks.any? { |net| net.include?(address) and !allowed_ip?(address) }
36
+ end
37
+
38
+ def allowed_ip?(address)
39
+ @allowed_networks.any? { |net| net.include? address }
40
+ end
41
+
42
+ def addresses(hostname)
43
+ Socket.gethostbyname(hostname).map { |a| IPAddr.new_ntoh(a) rescue nil }.compact
44
+ end
45
+ end
46
+
47
+ register_middleware restrict_ip_addresses: lambda { RestrictIPAddresses }
48
+ end
@@ -0,0 +1,73 @@
1
+ require 'faraday/restrict_ip_addresses'
2
+ require 'spec_helper'
3
+
4
+ describe Faraday::RestrictIPAddresses do
5
+ def middleware(opts = {})
6
+ @rip = described_class.new(lambda{|env| env}, opts)
7
+ end
8
+
9
+ def allowed(string_address)
10
+ url = URI.parse("http://test.com")
11
+ ip = IPAddr.new(string_address).hton
12
+
13
+ Socket.expects(:gethostbyname).with(url.host).returns(['garbage', [], 30, ip])
14
+
15
+ env = { url: url }
16
+ @rip.call(env)
17
+ end
18
+
19
+ def denied(string_address)
20
+ expect(-> { allowed(string_address) }).to raise_error(Faraday::RestrictIPAddresses::AddressNotAllowed)
21
+ end
22
+
23
+ it "defaults to allowing everything" do
24
+ middleware
25
+
26
+ allowed '10.0.0.10'
27
+ allowed '255.255.255.255'
28
+ end
29
+
30
+ it "allows disallowing addresses" do
31
+ middleware deny: ["8.0.0.0/8"]
32
+
33
+ allowed '7.255.255.255'
34
+ denied '8.0.0.1'
35
+ end
36
+
37
+ it "blacklists RFC1918 addresses" do
38
+ middleware deny_rfc1918: true
39
+
40
+ allowed '5.5.5.5'
41
+ denied '127.0.0.1'
42
+ denied '192.168.15.55'
43
+ denied '10.0.0.252'
44
+ end
45
+
46
+ it "allows exceptions to disallowed addresses" do
47
+ middleware deny_rfc1918: true,
48
+ allow: ["192.168.0.0/24"]
49
+
50
+ allowed '192.168.0.15'
51
+ denied '192.168.1.0'
52
+ end
53
+
54
+ it "has an allow_localhost exception" do
55
+ middleware deny_rfc1918: true,
56
+ allow_localhost: true
57
+ denied '192.168.0.15'
58
+ allowed '127.0.0.1'
59
+ denied '127.0.0.5'
60
+ end
61
+
62
+ it "lets you mix and match your denied networks" do
63
+ middleware deny_rfc1918: true,
64
+ deny: ['8.0.0.0/8'],
65
+ allow: ['8.5.0.0/24', '192.168.14.0/24']
66
+ allowed '8.5.0.15'
67
+ allowed '192.168.14.14'
68
+ denied '8.8.8.8'
69
+ denied '192.168.13.14'
70
+ end
71
+
72
+ end
73
+
@@ -0,0 +1,5 @@
1
+ Bundler.require
2
+ $:.unshift 'lib'
3
+ require 'faraday/restrict_ip_addresses'
4
+ require 'pry'
5
+ require 'mocha/mini_test'
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: faraday-restrict-ip-addresses
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Lavender
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.8'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '0.9'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '0.8'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.9'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ description: Restrict the IP addresses Faraday will connect to
48
+ email:
49
+ - bhuga@github.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - README.md
55
+ - UNLICENSE
56
+ - faraday-restrict-ip-addresses.gemspec
57
+ - lib/faraday/restrict_ip_addresses.rb
58
+ - spec/restrict_ip_addresses_spec.rb
59
+ - spec/spec_helper.rb
60
+ homepage: https://github.com/bhuga/faraday-restrict-ip-addresses
61
+ licenses:
62
+ - Unlicense
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 1.3.5
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.2.0
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Restrict the IP addresses Faraday will connect to
84
+ test_files:
85
+ - spec/restrict_ip_addresses_spec.rb
86
+ - spec/spec_helper.rb