Rails Helpers

Loofah::Helpers provides small, drop-in replacements for the Rails Action View helpers strip_tags, sanitize, and sanitize_css, plus sanitizer classes shaped like the ones Rails uses internally. This page documents exactly what each helper does, which is simpler (and in places different) from what the Rails helpers of the same name do today.

Note: Modern Rails applications get their sanitizers from rails-html-sanitizer, which is built on Loofah and offers configurable tags and attributes. Loofah::Helpers is a lightweight alternative when you want Loofah's default behavior with no extra configuration, inside or outside Rails.

Loading the Helpers

The helpers are not loaded by require "loofah". Load them explicitly:

require "loofah/helpers"

Loofah::Helpers.strip_tags

Loofah::Helpers.strip_tags(string_or_io) # => String

Removes all markup and returns the text, with HTML special characters escaped. It is exactly Loofah.html4_fragment(string_or_io).text.

Loofah::Helpers.strip_tags("<div>Hello <b>there</b></div>")
# => "Hello there"

Loofah::Helpers.strip_tags("&lt;script&gt;alert('evil')&lt;/script&gt;")
# => "&lt;script&gt;alert('evil')&lt;/script&gt;"

Things to know:

  • The input is not scrubbed first, so the text of <script> and <style> elements is included in the result (escaped).
  • Because entities stay escaped, the result is safe to insert into HTML but shows &amp;, &lt;, and so on if you put it in a plain-text context. For plain text, use Loofah.html5_fragment(input).text(encode_special_chars: false) instead (see Text Output).
  • It always uses the HTML4 parser.

Loofah::Helpers.sanitize

Loofah::Helpers.sanitize(string_or_io) # => String

Sanitizes HTML with Loofah's default safelist. The implementation is:

  1. Parse with Loofah.html4_fragment.
  2. Scrub with :strip: unsafe tags are removed but their text is kept.
  3. Remove <form> elements that are top-level nodes of the fragment, including their contents.
  4. Return to_s.
Loofah::Helpers.sanitize("<div>omgwtfbbq</div><span>!!1!</span>")
# => "<div>omgwtfbbq</div><span>!!1!</span>"

Loofah::Helpers.sanitize("<script>alert('evil')</script><span>w00t</span>")
# => "alert('evil')<span>w00t</span>"

Loofah::Helpers.sanitize("<script>alert('evil')</script><form action=\"/foo/bar\" method=\"post\"><input></form><span>w00t</span>")
# => "alert('evil')<span>w00t</span>"

Warning: The form removal uses the XPath ./form, which only matches forms at the top level of the fragment. A form nested inside another element, such as <div><form>...</form></div>, is kept, because form and input are on the safelist. If forms must never appear, add your own scrubber (recipe).

Note: Because :strip keeps text, the body of a <script> element appears in the output as plain text, as the second example shows. It cannot execute, but readers will see it. Use Loofah.html5_fragment(input).scrub!(:prune).to_s if you prefer to drop it.

Unlike Rails' sanitize, this helper accepts no tags: or attributes: options; it takes exactly one argument.

Loofah::Helpers.sanitize_css

Loofah::Helpers.sanitize_css(style_string) # => String

Sanitizes the contents of a style attribute by delegating to Loofah::HTML5::Scrub.scrub_css:

Loofah::Helpers.sanitize_css("display:block;background-image:url(http://example.com/foo.jpg)")
# => "display:block;"

Declarations with url(...) are removed, as are disallowed properties and values. See URI and CSS Sanitization for the exact rules and output format.

Note: The method comment shows the result as "display: block;" with a space, but the current CSS scrubber emits name:value; without a space after the colon, as the test suite's regex and the scrub_css tests show.

Loofah::Helpers.remove_extraneous_whitespace

Loofah::Helpers.remove_extraneous_whitespace(string) # => String

Collapses three or more newlines (with any whitespace between them) into two. It delegates to Loofah.remove_extraneous_whitespace, and the source marks it with a TODO to remove it in a future major release, so prefer calling Loofah.remove_extraneous_whitespace directly.

Action View Sanitizer Classes

Loofah::Helpers::ActionView contains classes with the same interface as the sanitizer classes Rails' SanitizeHelper uses:

Class Method Delegates to
Loofah::Helpers::ActionView::FullSanitizer sanitize(html, *args) Loofah::Helpers.strip_tags(html)
Loofah::Helpers::ActionView::SafeListSanitizer sanitize(html, *args) Loofah::Helpers.sanitize(html)
Loofah::Helpers::ActionView::SafeListSanitizer sanitize_css(style_string, *args) Loofah::Helpers.sanitize_css(style_string)

Any extra arguments (such as Rails' tags: and attributes: options) are accepted and ignored.

Loofah::Helpers::ActionView::WhiteListSanitizer is a deprecated alias of SafeListSanitizer; referencing it prints a Ruby deprecation warning.

The class comments suggest plugging them into Rails in an initializer:

# config/initializers/sanitizers.rb
require "loofah/helpers"

ActionView::Helpers::SanitizeHelper.full_sanitizer =
  Loofah::Helpers::ActionView::FullSanitizer.new
ActionView::Helpers::SanitizeHelper.safe_list_sanitizer =
  Loofah::Helpers::ActionView::SafeListSanitizer.new

Whether those setters exist depends on your Rails version; check your Rails' SanitizeHelper before relying on this.

Note: The same comments also mention Loofah::Helpers::ActionView.set_as_default_sanitizer, but no such method is defined anywhere in the library. Use explicit assignments as shown above.

The module also defines Loofah::Helpers::ActionView::ClassMethods (marked :nodoc:) with memoized full_sanitizer, safe_list_sanitizer, and a deprecated white_list_sanitizer (which prints warning: white_list_sanitizer is deprecated, please use safe_list_sanitizer instead.). Loofah does not include this module anywhere itself.

See Also