ssrf_filter 1.0.0 → 1.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 +4 -4
- data/lib/ssrf_filter/ssrf_filter.rb +28 -11
- data/lib/ssrf_filter/version.rb +1 -1
- metadata +17 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 855ec5e3486aa13ddfebb55690b3e7d30f6148d2
         | 
| 4 | 
            +
              data.tar.gz: 6df3da50c9087158e4cb2911a290ba694406e111
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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 | 
            -
              ]. | 
| 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 | 
            -
                 | 
| 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
         | 
    
        data/lib/ssrf_filter/version.rb
    CHANGED
    
    
    
        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. | 
| 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- | 
| 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. | 
| 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
         |