ssrf_filter 1.0.0 → 1.0.1

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: 68db49bb250c05d11655c0afe1913b34247d783c
4
- data.tar.gz: f1d11ee2913e121b3c996a1af745926a3da953e2
3
+ metadata.gz: 855ec5e3486aa13ddfebb55690b3e7d30f6148d2
4
+ data.tar.gz: 6df3da50c9087158e4cb2911a290ba694406e111
5
5
  SHA512:
6
- metadata.gz: 201bf113012c32ddb97e79df1fe9428d9dff43be894d340789a6b937f819e4538e680f8ec66e0d458a396ed7e082d1d20374d4b8c0fc0833970fb6b1d9a81bad
7
- data.tar.gz: 769532a2d3f68fe97a20a001d73fc930855dbdd7c1dbe4ac115c29e2f7661f509c3d89cbe21480a7630e503af7bb3bea7b4fedbb625fb2e51e5a08aa4a1a1dc4
6
+ metadata.gz: ac67704b7c90ba7c2b7a43b94e1d2a7f9230776f5754e195cc74076abe1a0e90c2cfa05b43fe5d8d7da40359729e7df056f15f6c00b16763e37c8f8e5e6d30a9
7
+ data.tar.gz: 0f0f93dc6016603c49d151006c70564f9eb9dfc60ddbe4cd28b537f091ae4ba0b4830739987e70d9deaff307a18a2c0f5f89a19c5cb6ca10188c1b1002728b5a
@@ -4,6 +4,22 @@ require 'resolv'
4
4
  require 'uri'
5
5
 
6
6
  class SsrfFilter
7
+ def self.prefixlen_from_ipaddr(ipaddr)
8
+ mask_addr = ipaddr.instance_variable_get('@mask_addr')
9
+ raise ArgumentError, 'Invalid mask' if mask_addr.zero?
10
+
11
+ mask_addr >>= 1 while (mask_addr & 0x1).zero?
12
+
13
+ length = 0
14
+ while mask_addr & 0x1 == 0x1
15
+ length += 1
16
+ mask_addr >>= 1
17
+ end
18
+
19
+ length
20
+ end
21
+ private_class_method :prefixlen_from_ipaddr
22
+
7
23
  # https://en.wikipedia.org/wiki/Reserved_IP_addresses
8
24
  IPV4_BLACKLIST = [
9
25
  ::IPAddr.new('0.0.0.0/8'), # Current network (only valid as source address)
@@ -24,7 +40,7 @@ class SsrfFilter
24
40
  ::IPAddr.new('255.255.255.255') # Broadcast
25
41
  ].freeze
26
42
 
27
- IPV6_BLACKLIST = [
43
+ IPV6_BLACKLIST = ([
28
44
  ::IPAddr.new('::1/128'), # Loopback
29
45
  ::IPAddr.new('64:ff9b::/96'), # IPv4/IPv6 translation (RFC 6052)
30
46
  ::IPAddr.new('100::/64'), # Discard prefix (RFC 6666)
@@ -36,7 +52,14 @@ class SsrfFilter
36
52
  ::IPAddr.new('fc00::/7'), # Unique local address
37
53
  ::IPAddr.new('fe80::/10'), # Link-local address
38
54
  ::IPAddr.new('ff00::/8'), # Multicast
39
- ].freeze
55
+ ] + IPV4_BLACKLIST.flat_map do |ipaddr|
56
+ prefixlen = prefixlen_from_ipaddr(ipaddr)
57
+
58
+ ipv4_compatible = ipaddr.ipv4_compat.mask(96 + prefixlen)
59
+ ipv4_mapped = ipaddr.ipv4_mapped.mask(80 + prefixlen)
60
+
61
+ [ipv4_compatible, ipv4_mapped]
62
+ end).freeze
40
63
 
41
64
  DEFAULT_SCHEME_WHITELIST = %w[http https].freeze
42
65
 
@@ -110,14 +133,7 @@ class SsrfFilter
110
133
  return true if ipaddr_has_mask?(ip_address)
111
134
 
112
135
  return IPV4_BLACKLIST.any? { |range| range.include?(ip_address) } if ip_address.ipv4?
113
-
114
- if ip_address.ipv6?
115
- result = IPV6_BLACKLIST.any? { |range| range.include?(ip_address) }
116
- # TODO: convert these to be members of IPV6_BLACKLIST
117
- result ||= ip_address.ipv4_compat? && IPV4_BLACKLIST.any? { |range| range.include?(ip_address.ipv4_compat) }
118
- result ||= ip_address.ipv4_mapped? && IPV4_BLACKLIST.any? { |range| range.include?(ip_address.ipv4_mapped) }
119
- return result
120
- end
136
+ return IPV6_BLACKLIST.any? { |range| range.include?(ip_address) } if ip_address.ipv6?
121
137
 
122
138
  true
123
139
  end
@@ -140,7 +156,8 @@ class SsrfFilter
140
156
  uri.hostname = ip
141
157
 
142
158
  request = VERB_MAP[verb].new(uri)
143
- request['host'] = hostname
159
+ # Attach port for non-80 as per RFC2616
160
+ request['host'] = uri.port == 80 ? hostname : "#{hostname}:#{uri.port}"
144
161
 
145
162
  Array(options[:headers]).each do |header, value|
146
163
  request[header] = value
@@ -1,3 +1,3 @@
1
1
  class SsrfFilter
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.0.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssrf_filter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkadiy Tetelman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-25 00:00:00.000000000 Z
11
+ date: 2017-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler-audit
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.4'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -110,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
124
  version: '0'
111
125
  requirements: []
112
126
  rubyforge_project:
113
- rubygems_version: 2.4.6
127
+ rubygems_version: 2.6.12
114
128
  signing_key:
115
129
  specification_version: 4
116
130
  summary: A gem that makes it easy to prevent server side request forgery (SSRF) attacks