pezza_action_push_web 0.2.0 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b38a01863916f285ea98b99ea79483767c4633bc1bf51a54c232703260e947c
4
- data.tar.gz: e0cad328df4292a41a013554ff90176b8fe34baaaf77477a03e26620ae7e0075
3
+ metadata.gz: 93d488729aae040d4f85f2251e45aefb608835869b9c5d568f8e538c02b0e41d
4
+ data.tar.gz: f6984298ffdcf0b4722bf7eb4a7efdd860befe66ac602add26061596a2bef0c2
5
5
  SHA512:
6
- metadata.gz: 1f8cc2f332367bfef4d89b06864379447337e09ae825354aa712de31c863d3b2b5ea90451cab640aca6756b4808bb013f9afe8572d258c3288b097b38d5e8418
7
- data.tar.gz: 151514426c7a3218ada6b191a8fe917364d7a571577ec9d0b1174cb0d73e2b0cc3a91182dfabfa23934823879ab7d1a0dcdd409a1eb3b074b9ed85f1c7c108c5
6
+ metadata.gz: eb237077e3d17e665abe9213a2a1aac9dbb53458b78ffef87ae3533c7239b2695927f3d94f3c0d01c0ed97e0c568fe12c4a6432a0bdcbac2f326ce2eb0469fdc
7
+ data.tar.gz: 0d72b0362ea10d90bd530e89eaf4efb083f8e00dff5cf287f966106782bc3ca33f014e45e7498a183844fd2b6e5c3db2441e2c36aa214e29ef3486acc010c717
@@ -23,7 +23,12 @@ module ActionPushWeb
23
23
 
24
24
  def resolved_endpoint_ip
25
25
  return @resolved_endpoint_ip if defined?(@resolved_endpoint_ip)
26
- @resolved_endpoint_ip = SsrfProtection.resolve_public_ip(endpoint_uri&.host)
26
+ @resolved_endpoint_ip = Surfguard.resolve_public_ips(endpoint_uri&.host).first
27
+ rescue Surfguard::Unresolvable
28
+ # A host that resolves to nothing has no usable public IP, same outcome as
29
+ # one whose only addresses are blocked: no endpoint IP to pin, which fails
30
+ # endpoint validation. Push has no lookup-failed surface to distinguish.
31
+ @resolved_endpoint_ip = nil
27
32
  end
28
33
 
29
34
  private
@@ -1,3 +1,3 @@
1
1
  module ActionPushWeb
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -4,6 +4,7 @@ require "action_push_web/errors"
4
4
  require "net/http"
5
5
  require "net/http/persistent"
6
6
  require "jwt"
7
+ require "surfguard"
7
8
 
8
9
  loader= Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
9
10
  loader.ignore("#{__dir__}/generators")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pezza_action_push_web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Pezza
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: surfguard
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
96
110
  description: Send push notifications to web apps
97
111
  email:
98
112
  - pezza@hey.com
@@ -112,7 +126,6 @@ files:
112
126
  - app/controllers/action_push_web/subscriptions_controller.rb
113
127
  - app/helpers/action_push_web/application_helper.rb
114
128
  - app/jobs/action_push_web/notification_job.rb
115
- - app/models/action_push_web/ssrf_protection.rb
116
129
  - app/models/action_push_web/subscription.rb
117
130
  - config/importmap.rb
118
131
  - config/routes.rb
@@ -159,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
172
  - !ruby/object:Gem::Version
160
173
  version: '0'
161
174
  requirements: []
162
- rubygems_version: 4.0.11
175
+ rubygems_version: 4.0.18
163
176
  specification_version: 4
164
177
  summary: Send push notifications to web apps
165
178
  test_files: []
@@ -1,52 +0,0 @@
1
- module ActionPushWeb
2
- module SsrfProtection
3
- extend self
4
-
5
- DNS_RESOLUTION_TIMEOUT = 2
6
-
7
- DNS_NAMESERVERS = %w[
8
- 1.1.1.1
9
- 8.8.8.8
10
- ]
11
-
12
- DISALLOWED_IP_RANGES = [
13
- IPAddr.new("0.0.0.0/8"), # "This" network (RFC1700)
14
- IPAddr.new("100.64.0.0/10"), # Carrier-grade NAT (RFC6598)
15
- IPAddr.new("198.18.0.0/15") # Benchmark testing (RFC2544)
16
- ].freeze
17
-
18
- def resolve_public_ip(hostname)
19
- ip_addresses = resolve_dns(hostname)
20
- public_ips = ip_addresses.reject { |ip| blocked_address?(ip) }
21
- public_ips.sort_by { |ipaddr| ipaddr.ipv4? ? 0 : 1 }.first&.to_s
22
- end
23
-
24
- def blocked_address?(ip)
25
- ip = IPAddr.new(ip.to_s) unless ip.is_a?(IPAddr)
26
-
27
- ip.private? ||
28
- ip.loopback? ||
29
- ip.link_local? ||
30
- ip.ipv4_mapped? ||
31
- ip.ipv4_compat? ||
32
- in_disallowed_range?(ip)
33
- end
34
-
35
- private
36
- def resolve_dns(hostname)
37
- ip_addresses = []
38
-
39
- Resolv::DNS.open(nameserver: DNS_NAMESERVERS, timeouts: DNS_RESOLUTION_TIMEOUT) do |dns|
40
- dns.each_address(hostname) do |ip_address|
41
- ip_addresses << IPAddr.new(ip_address.to_s)
42
- end
43
- end
44
-
45
- ip_addresses
46
- end
47
-
48
- def in_disallowed_range?(ip)
49
- DISALLOWED_IP_RANGES.any? { |range| range.include?(ip) }
50
- end
51
- end
52
- end