mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-03-19 04:33:38 +09:00
Adds ipv4_mapped? and ipv4_compat? checks to PrivateNetworkGuard.private_ip? to block SSRF bypass attempts using IPv6 address formats like: - ::ffff:169.254.169.254 (IPv4-mapped) - ::169.254.169.254 (IPv4-compatible) These formats could previously bypass the link_local? check since Ruby treats them as IPv6 addresses, not IPv4. Ref: HackerOne #3481701
26 lines
656 B
Ruby
26 lines
656 B
Ruby
require "resolv"
|
|
|
|
module RestrictedHTTP
|
|
class Violation < StandardError; end
|
|
|
|
module PrivateNetworkGuard
|
|
extend self
|
|
|
|
LOCAL_IP = IPAddr.new("0.0.0.0/8") # "This" network
|
|
|
|
def resolve(hostname)
|
|
Resolv.getaddress(hostname).tap do |ip|
|
|
raise Violation.new("Attempt to access private IP via #{hostname}") if ip && private_ip?(ip)
|
|
end
|
|
end
|
|
|
|
def private_ip?(ip)
|
|
IPAddr.new(ip).then do |ipaddr|
|
|
ipaddr.private? || ipaddr.loopback? || ipaddr.link_local? || ipaddr.ipv4_mapped? || ipaddr.ipv4_compat? || LOCAL_IP.include?(ipaddr)
|
|
end
|
|
rescue IPAddr::InvalidAddressError
|
|
true
|
|
end
|
|
end
|
|
end
|