Skip to content

Commit

Permalink
Merge pull request #48644 from flavorjones/flavorjones-default-config…
Browse files Browse the repository at this point in the history
…-for-action-text-sanitizer

Introduce config for Action Text sanitizer
  • Loading branch information
guilleiguaran committed Jul 4, 2023
2 parents 2d6f523 + 44d3b44 commit fe6b96a
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 4 deletions.
13 changes: 13 additions & 0 deletions actiontext/CHANGELOG.md
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion actiontext/app/helpers/action_text/content_helper.rb
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions actiontext/lib/action_text/engine.rb
Expand Up @@ -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
12 changes: 12 additions & 0 deletions guides/source/configuring.md
Expand Up @@ -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`
Expand Down Expand Up @@ -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`.
Expand Down
4 changes: 4 additions & 0 deletions railties/lib/rails/application/configuration.rb
Expand Up @@ -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}"
Expand Down
Expand Up @@ -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
59 changes: 59 additions & 0 deletions railties/test/application/configuration_test.rb
Expand Up @@ -23,6 +23,14 @@ def self.delivered_email(email); email; end

class ::MyOtherMailObserver < ::MyMailObserver; 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
@io = StringIO.new
Expand Down Expand Up @@ -4481,6 +4489,57 @@ def new(app); self; end
assert_equal OpenSSL::Digest::SHA1, ActiveRecord::Encryption.config.hash_digest_class
end

test "sanitizer_vendor is set to best supported vendor in new apps" do
app "development"

assert_equal Rails::HTML::Sanitizer.best_supported_vendor, ActionView::Helpers::SanitizeHelper.sanitizer_vendor
end

test "sanitizer_vendor is set to HTML4 in upgraded apps" do
remove_from_config '.*config\.load_defaults.*\n'
add_to_config 'config.load_defaults "7.0"'
app "development"

assert_equal Rails::HTML4::Sanitizer, ActionView::Helpers::SanitizeHelper.sanitizer_vendor
end

test "sanitizer_vendor is set to a specific vendor" do
add_to_config "config.action_view.sanitizer_vendor = ::MySanitizerVendor"
app "development"

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
Expand Down

0 comments on commit fe6b96a

Please sign in to comment.