Add config.action_text.sanitizer_vendor

Rails 7.1 defaults to Rails::HTML::Sanitizer.best_supported_vendor,
earlier configs will use Rails::HTML4::Sanitizer.

Related to #48523 / 55bca6b8.
This commit is contained in:
Mike Dalessio 2023-07-03 17:27:43 -04:00
parent 68fb1e40d1
commit 44d3b44d9d
No known key found for this signature in database
GPG Key ID: FCF96ED17542E12F
7 changed files with 86 additions and 5 deletions

@ -1,3 +1,16 @@
* Use `Rails::HTML5::SafeListSanitizer` by default in the Rails 7.1 configuration if it is
supported.
Action Text's sanitizer can be configured by setting
`config.action_text.sanitizer_vendor`. Supported values are `Rails::HTML4::Sanitizer` or
`Rails::HTML5::Sanitizer`.
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`.
*Mike Dalessio*
* Attachables now can override default attachment missing template.
When rendering Action Text attachments where the underlying attachable model has

@ -4,7 +4,7 @@
module ActionText
module ContentHelper
mattr_accessor(:sanitizer) { Rails::Html::Sanitizer.best_supported_vendor.safe_list_sanitizer.new }
mattr_accessor(:sanitizer, default: Rails::HTML4::Sanitizer.safe_list_sanitizer.new)
mattr_accessor(:allowed_tags) { sanitizer.class.allowed_tags + [ ActionText::Attachment.tag_name, "figure", "figcaption" ] }
mattr_accessor(:allowed_attributes) { sanitizer.class.allowed_attributes + ActionText::Attachment::ATTRIBUTES }
mattr_accessor(:scrubber)

@ -82,5 +82,11 @@ def to_trix_content_attachment_partial_path
initializer "action_text.configure" do |app|
ActionText::Attachment.tag_name = app.config.action_text.attachment_tag_name
end
initializer "action_text.sanitizer_vendor" do |app|
if klass = app.config.action_text.delete(:sanitizer_vendor)
ActionText::ContentHelper.sanitizer = klass.safe_list_sanitizer.new
end
end
end
end

@ -63,6 +63,7 @@ Below are the default values associated with each target version. In cases of co
- [`config.action_controller.allow_deprecated_parameters_hash_equality`](#config-action-controller-allow-deprecated-parameters-hash-equality): `false`
- [`config.action_dispatch.debug_exception_log_level`](#config-action-dispatch-debug-exception-log-level): `:error`
- [`config.action_dispatch.default_headers`](#config-action-dispatch-default-headers): `{ "X-Frame-Options" => "SAMEORIGIN", "X-XSS-Protection" => "0", "X-Content-Type-Options" => "nosniff", "X-Permitted-Cross-Domain-Policies" => "none", "Referrer-Policy" => "strict-origin-when-cross-origin" }`
- [`config.action_text.sanitizer_vendor`](#config-action-text-sanitizer-vendor): `Rails::HTML::Sanitizer.best_supported_vendor`
- [`config.action_view.sanitizer_vendor`](#config-action-view-sanitizer-vendor): `Rails::HTML::Sanitizer.best_supported_vendor`
- [`config.active_job.use_big_decimal_serializer`](#config-active-job-use-big-decimal-serializer): `true`
- [`config.active_record.allow_deprecated_singular_associations_name`](#config-active-record-allow-deprecated-singular-associations-name): `false`
@ -2821,6 +2822,17 @@ has no effect if Sprockets is not used. The default value is `true`.
Accepts a string for the HTML tag used to wrap attachments. Defaults to `"action-text-attachment"`.
#### `config.action_text.sanitizer_vendor`
Configures the HTML sanitizer used by Action Text by setting `ActionText::ContentHelper.sanitizer` to an instance of the class returned from the vendor's `.safe_list_sanitizer` method. The default value depends on the `config.load_defaults` target version:
| Starting with version | The default value is | Which parses markup as |
|-----------------------|--------------------------------------|------------------------|
| (original) | `Rails::HTML4::Sanitizer` | HTML4 |
| 7.1 | `Rails::HTML5::Sanitizer` (see NOTE) | HTML5 |
NOTE: `Rails::HTML5::Sanitizer` is not supported on JRuby, so on JRuby platforms Rails will fall back to use `Rails::HTML4::Sanitizer`.
### Configuring a Database
Just about every Rails application will interact with a database. You can connect to the database by setting an environment variable `ENV['DATABASE_URL']` or by using a configuration file called `config/database.yml`.

@ -319,6 +319,10 @@ def load_defaults(target_version)
if respond_to?(:action_view)
action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
end
if respond_to?(:action_text)
action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
end
end
else
raise "Unknown version #{target_version.to_s.inspect}"

@ -184,13 +184,23 @@
# Configure Action View to use HTML5 standards-compliant sanitizers when they are supported on your
# platform.
#
# `Rails::HTML::Sanitizer.best_supported_vendor` will return `Rails::HTML5::Sanitizer` if it's
# supported, else fall back to `Rails::HTML4::Sanitizer`.
# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action View to use HTML5-compliant
# sanitizers if they are supported, else fall back to HTML4 sanitizers.
#
# In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer`.
# In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor.
#
# Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
# Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your
# platform.
#
# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action Text to use HTML5-compliant
# sanitizers if they are supported, else fall back to HTML4 sanitizers.
#
# In previous versions of Rails, Action Text always used `Rails::HTML4::Sanitizer` as its vendor.
#
# Rails.application.config.action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
# Configure the log level used by the DebugExceptions middleware when logging
# uncaught exceptions during requests
# Rails.application.config.action_dispatch.debug_exception_log_level = :error

@ -23,7 +23,13 @@ def self.delivered_email(email); email; end
class ::MyOtherMailObserver < ::MyMailObserver; end
class ::MySanitizerVendor < ::Rails::HTML::Sanitizer; end
class ::MySafeListSanitizer < Rails::HTML4::SafeListSanitizer; end
class ::MySanitizerVendor < ::Rails::HTML::Sanitizer
def self.safe_list_sanitizer
::MySafeListSanitizer
end
end
class MyLogRecorder < Logger
def initialize
@ -4504,6 +4510,36 @@ def new(app); self; end
assert_equal ::MySanitizerVendor, ActionView::Helpers::SanitizeHelper.sanitizer_vendor
end
test "Action Text uses the best supported safe list sanitizer in new apps" do
app "development"
assert_kind_of(
Rails::HTML::Sanitizer.best_supported_vendor.safe_list_sanitizer,
ActionText::ContentHelper.sanitizer,
)
end
test "Action Text uses the HTML4 safe list sanitizer in upgraded apps" do
remove_from_config '.*config\.load_defaults.*\n'
add_to_config 'config.load_defaults "7.0"'
app "development"
assert_kind_of(
Rails::HTML4::Sanitizer.safe_list_sanitizer,
ActionText::ContentHelper.sanitizer,
)
end
test "Action Text uses the specified vendor's safe list sanitizer" do
add_to_config "config.action_text.sanitizer_vendor = ::MySanitizerVendor"
app "development"
assert_kind_of(
::MySafeListSanitizer,
ActionText::ContentHelper.sanitizer,
)
end
private
def set_custom_config(contents, config_source = "custom".inspect)
app_file "config/custom.yml", contents