Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Content_tag_string Sanitizes Possibly Unsafe HTML

#3785

This ticket is related to the ongoing work on HTML safe strings (ticket #3018 Introduce notion of 'html_safe?' to Strings in preparation for on-by-default ...). It is related to tickets #3448 Button_to does not return an HTML-safe string #3450 Field_set_tag doesn't escape the legend #3449 Label tag doesn't escape its input and points to the underlying problem.

Tag helpers in Rails (indirectly) use content_tag_string to output a string to render. In Rails 2.3.5, content_tag_string liberally marks its output as html safe.

def content_tag_string(name, content, options, escape = true)
  tag_options = tag_options(options, escape) if options
        "<#{name}#{tag_options}>#{content}</#{name}>".html_safe!
end

In particular, content_tag, which can be used to generate any HTML tag, passes its second argument, which could easily be user-supplied data, straight through to content_tag_string, where the output is marked as HTML safe.

content_tag(:p, "<script>alert('hello');</script>")

Content_tag is used in other tag helpers:

      def label_tag(name, text = nil, options = {})
        content_tag :label, text || name.to_s.humanize, { "for" => sanitize_to_id(name) }.update(options.stringify_keys)
      end

Reported by Todd Sundsted · January 25th, 2010 @ 02:20 AM

State: resolved
Milestone: none
Assigned to: Michael Koziarski Michael Koziarski
Importance: Low

Activity

  1. Todd Sundsted
    Todd Sundsted
    • Tag changed from content_tag, content_tag_string, html_safe to 2.3.5, content_tag, content_tag_string, html_safe

    January 25th, 2010 @ 02:21 AM

  2. Todd Sundsted
    Todd Sundsted
    • Tag changed from 2.3.5, content_tag, content_tag_string, html_safe to 2, content_tag, content_tag_string, html_safe

    I committed the following patch to my fork of rails_xss, which handles all of the problems I've come across. Needs testing against other reported issues:

    http://github.com/toddsundsted/rails_xss/commit/2df604fdf86200c80f7...

    module ActionView
      module Helpers
        module TagHelper
          private
            def content_tag_string(name, content, options, escape = true)
              tag_options = tag_options(options, escape) if options
              content = ERB::Util.h(content) unless content.html_safe?
              "<#{name}#{tag_options}>#{content}</#{name}>".html_safe!
            end
        end
      end
    end
    

    February 3rd, 2010 @ 02:16 AM

  3. José Valim
    José Valim
    • Assigned user set to Michael Koziarski

    February 3rd, 2010 @ 09:59 AM

  4. Rohit Arondekar
    Rohit Arondekar

    Any updates to this ticket? Is this still an issue?

    June 23rd, 2010 @ 02:59 AM

  5. Santiago Pastorino
    Santiago Pastorino

    Todd the current code of rails_xss escapes the content as you are doing here ... take a look and please reply the ticket so we can close it ;).
    http://github.com/rails/rails_xss/blob/master/lib/rails_xss/action_...

    June 23rd, 2010 @ 04:09 AM

  6. Todd Sundsted
    Todd Sundsted

    Thanks, guys! Will do.

    June 23rd, 2010 @ 04:44 AM

  7. Todd Sundsted
    Todd Sundsted

    Everything looks good.

    I tested with Rails 2.3.8 and the latest Erubis.

      > x = '<script>alert("pwned")</script>'
     => "<script>alert(\"pwned\")</script>" 
      > x.html_safe?
     => nil 
      > y = helper.content_tag("div", x)
     => "<div>&lt;script&gt;alert(&quot;pwned&quot;)&lt;/script&gt;</div>" 
      > x = x.html_safe
     => "<script>alert(\"pwned\")</script>" 
      > x.html_safe?
     => true
      > y = helper.content_tag("div", x)
     => "<div><script>alert(\"pwned\")</script></div>"
    

    Thanks again!

    June 23rd, 2010 @ 02:07 PM

  8. José Valim
    José Valim
    • State changed from new to resolved

    June 23rd, 2010 @ 02:08 PM

  9. Andrea Campi
    Andrea Campi
    • Tag changed from 2, content_tag, content_tag_string, html_safe to 2-3-stable, content_tag, content_tag_string, html_safe
    • Importance changed from to Low

    October 16th, 2010 @ 11:41 PM