ruby-on-railshtml-sanitizingactiontext

Allow ActionText tags in Rails 7.1 with new sanitizers


In Rails 7.0 and earlier, we customized the Trix editor to embed YouTube videos. As is customary, the video will be embedded via an iframe tag. The Rails sanitizer removes this tag as it can be abused to embed malicious websites.

Allowing the tag in config/initializers/action_text.rb used to do the trick.

Rails.application.config.after_initialize do
  ActionText::ContentHelper.allowed_tags << "iframe"
end

Rails 7.1 has a new HTML5 sanitizer, but the old HTML4 one can still be used. This means ActionText::ContentHelper is not yet defined when the application boots, so the snippet above will crash the server. I expected the after_initialize to wait long enough for the sanitizer to be loaded, but no dice.

Unable to load application: NoMethodError: undefined method `<<' for nil:NilClass
config/initializers/action_text.rb:2:in `block in <top (required)>': undefined method `<<' for nil:NilClass (NoMethodError)

Any ideas on how to allow sanitized tags in Rails 7.1?


Solution

  • I was stuck with the same problem. According to ActionView 7.1.0 CHANGELOG it's nil until is set in the application.

    The Rails 7.1 configuration will set this to Rails::HTML5::Sanitizer when it is supported, and fall back to Rails::HTML4::Sanitizer. Previous configurations default to Rails::HTML4::Sanitizer.

    As a result of this change, the defaults for ActionText::ContentHelper.allowed_tags and .allowed_attributes are applied at runtime, so the value of these attributes is now 'nil' unless set by the application. You may call sanitizer_allowed_tags or sanitizer_allowed_attributes to inspect the tags and attributes being allowed by the sanitizer.

    So, I decided to copy all tags from 'rails-html-sanitizer' gem to config/initializers/action_text.rb and also added my specific tags there

    Rails.application.config.after_initialize do
      ActionText::ContentHelper.allowed_tags = Set.new([
        "a",
        "abbr",
        "acronym",
        "address",
        ...  # more tags go here
      ]).freeze
    end
    

    It did the job.