Skip to content
  • Jonathan Hefner's avatar
    5e9973d6
    Refactor CVE-2021-22881 fix · 5e9973d6
    Jonathan Hefner authored
    Follow-up to 83a6ac3f.
    
    This allows `HTTP_HOST` to be omitted as before, and reduces the number
    of object allocations per request.
    
    Benchmark:
    
    ```ruby
     # frozen_string_literal: true
    require "benchmark/memory"
    
    HOST = "example.com:80"
    BEFORE_REGEXP = /\A(?<host>[a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\])(:\d+)?\z/
    AFTER_REGEXP = /(?:\A|,[ ]?)([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\])(?::\d+)?\z/i
    
    Benchmark.memory do |x|
      x.report("BEFORE (non-nil X-Forwarded-Host)") do
        origin_host = BEFORE_REGEXP.match(HOST.to_s.downcase)[:host]
        forwarded_host = BEFORE_REGEXP.match(HOST.to_s.split(/,\s?/).last)[:host]
      end
    
      x.report("BEFORE (nil X-Forwarded-Host)") do
        origin_host = BEFORE_REGEXP.match(HOST.to_s.downcase)[:host]
        forwarded_host = BEFORE_REGEXP.match(nil.to_s.split(/,\s?/).last)
      end
    
      x.report("AFTER (non-nil X-Forwarded-Host)") do
        origin_host = HOST&.slice(AFTER_REGEXP, 1) || ""
        forwarded_host = HOST&.slice(AFTER_REGEXP, 1) || ""
      end
    
      x.report("AFTER (nil X-Forwarded-Host)") do
        origin_host = HOST&.slice(AFTER_REGEXP, 1) || ""
        forwarded_host = nil&.slice(AFTER_REGEXP, 1) || ""
      end
    end
    ```
    
    Results:
    
    ```
    BEFORE (non-nil X-Forwarded-Host)
                           616.000  memsize (   208.000  retained)
                             9.000  objects (     2.000  retained)
                             2.000  strings (     1.000  retained)
    BEFORE (nil X-Forwarded-Host)
                           328.000  memsize (     0.000  retained)
                             5.000  objects (     0.000  retained)
                             2.000  strings (     0.000  retained)
    AFTER (non-nil X-Forwarded-Host)
                           248.000  memsize (   168.000  retained)
                             3.000  objects (     1.000  retained)
                             1.000  strings (     0.000  retained)
    AFTER (nil X-Forwarded-Host)
                            40.000  memsize (     0.000  retained)
                             1.000  objects (     0.000  retained)
                             1.000  strings (     0.000  retained)
    ```
    
    [CVE-2021-22942]
    5e9973d6
    Refactor CVE-2021-22881 fix
    Jonathan Hefner authored
    Follow-up to 83a6ac3f.
    
    This allows `HTTP_HOST` to be omitted as before, and reduces the number
    of object allocations per request.
    
    Benchmark:
    
    ```ruby
     # frozen_string_literal: true
    require "benchmark/memory"
    
    HOST = "example.com:80"
    BEFORE_REGEXP = /\A(?<host>[a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\])(:\d+)?\z/
    AFTER_REGEXP = /(?:\A|,[ ]?)([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\])(?::\d+)?\z/i
    
    Benchmark.memory do |x|
      x.report("BEFORE (non-nil X-Forwarded-Host)") do
        origin_host = BEFORE_REGEXP.match(HOST.to_s.downcase)[:host]
        forwarded_host = BEFORE_REGEXP.match(HOST.to_s.split(/,\s?/).last)[:host]
      end
    
      x.report("BEFORE (nil X-Forwarded-Host)") do
        origin_host = BEFORE_REGEXP.match(HOST.to_s.downcase)[:host]
        forwarded_host = BEFORE_REGEXP.match(nil.to_s.split(/,\s?/).last)
      end
    
      x.report("AFTER (non-nil X-Forwarded-Host)") do
        origin_host = HOST&.slice(AFTER_REGEXP, 1) || ""
        forwarded_host = HOST&.slice(AFTER_REGEXP, 1) || ""
      end
    
      x.report("AFTER (nil X-Forwarded-Host)") do
        origin_host = HOST&.slice(AFTER_REGEXP, 1) || ""
        forwarded_host = nil&.slice(AFTER_REGEXP, 1) || ""
      end
    end
    ```
    
    Results:
    
    ```
    BEFORE (non-nil X-Forwarded-Host)
                           616.000  memsize (   208.000  retained)
                             9.000  objects (     2.000  retained)
                             2.000  strings (     1.000  retained)
    BEFORE (nil X-Forwarded-Host)
                           328.000  memsize (     0.000  retained)
                             5.000  objects (     0.000  retained)
                             2.000  strings (     0.000  retained)
    AFTER (non-nil X-Forwarded-Host)
                           248.000  memsize (   168.000  retained)
                             3.000  objects (     1.000  retained)
                             1.000  strings (     0.000  retained)
    AFTER (nil X-Forwarded-Host)
                            40.000  memsize (     0.000  retained)
                             1.000  objects (     0.000  retained)
                             1.000  strings (     0.000  retained)
    ```
    
    [CVE-2021-22942]
Loading