lib/securenative/utils/request_utils.rb in securenative-0.1.36 vs lib/securenative/utils/request_utils.rb in securenative-0.1.37
- old
+ new
@@ -1,7 +1,9 @@
# frozen_string_literal: true
+require 'ipaddr'
+
module SecureNative
module Utils
class RequestUtils
SECURENATIVE_COOKIE = '_sn'
SECURENATIVE_HEADER = 'x-securenative'
@@ -22,56 +24,92 @@
begin
h = request.env[header]
if h.nil?
h = request.env[self.parse_ip(header)]
end
- return h.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless h.nil?
+ parsed = self.parse_proxy_header(h, header)
+ if self.validate_ip(parsed)
+ return parsed
+ end
rescue NoMethodError
begin
h = request[header]
if h.nil?
h = request.env[self.parse_ip(header)]
end
- return h.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless h.nil?
+ parsed = self.parse_proxy_header(h, header)
+ if self.validate_ip(parsed)
+ return parsed
+ end
rescue NoMethodError
# Ignored
end
end
}
end
begin
- x_forwarded_for = request.env['HTTP_X_FORWARDED_FOR']
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
+ header_value = request.env['HTTP_X_FORWARDED_FOR']
+ if header_value.include? ','
+ header_value = ip.split(',')[0]
+ end
+ if self.validate_ip(header_value)
+ return header_value
+ end
rescue NoMethodError
begin
- x_forwarded_for = request['HTTP_X_FORWARDED_FOR']
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
+ header_value = request['HTTP_X_FORWARDED_FOR']
+ if header_value.include? ','
+ header_value = ip.split(',')[0]
+ end
+ if self.validate_ip(header_value)
+ return header_value
+ end
rescue NoMethodError
# Ignored
end
end
begin
- x_forwarded_for = request.env['HTTP_X_REAL_IP']
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
+ header_value = request.env['HTTP_X_REAL_IP']
+ if header_value.include? ','
+ header_value = ip.split(',')[0]
+ end
+ if self.validate_ip(header_value)
+ return header
+ end
rescue NoMethodError
begin
- x_forwarded_for = request['HTTP_X_REAL_IP']
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
+ header_value = request['HTTP_X_REAL_IP']
+ if header_value.include? ','
+ header_value = ip.split(',')[0]
+ end
+ if self.validate_ip(header_value)
+ return header_value
+ end
rescue NoMethodError
# Ignored
end
end
begin
- x_forwarded_for = request.env['REMOTE_ADDR']
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
+ header_value = request.env['REMOTE_ADDR']
+ if header_value.include? ','
+ header_value = ip.split(',')[0]
+ end
+ if self.validate_ip(header_value)
+ return header_value
+ end
rescue NoMethodError
begin
- x_forwarded_for = request['REMOTE_ADDR']
- return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
+ header_value = request['REMOTE_ADDR']
+ if header_value.include? ','
+ header_value = ip.split(',')[0]
+ end
+ if self.validate_ip(header_value)
+ return header_value
+ end
rescue NoMethodError
# Ignored
end
end
@@ -93,9 +131,38 @@
end
def self.parse_ip(headers)
h = headers.gsub('-', '_')
return PREFIX + h.upcase
+ end
+
+ def self.parse_proxy_header(headers, header_key)
+ h = headers.gsub(header_key + ': ', '')
+ if headers.include? ','
+ h = h.split(',')[0]
+ end
+ return h
+ end
+
+ def self.validate_ip(ip)
+ if ip.nil?
+ return false
+ end
+
+ begin
+ ipaddr = IPAddr.new(ip)
+ if ipaddr.ipv4?
+ return true
+ end
+
+ if ipaddr.ipv6?
+ return true
+ end
+ rescue Exception
+ # Ignored
+ end
+
+ return false
end
end
end
end