Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML escaping not working for haml_concat in haml_tag block #718

Closed
jesk opened this issue Oct 17, 2013 · 3 comments
Closed

HTML escaping not working for haml_concat in haml_tag block #718

jesk opened this issue Oct 17, 2013 · 3 comments
Labels

Comments

@jesk
Copy link

jesk commented Oct 17, 2013

HTML escaping does not work when haml_concat is used in a haml_tag block. I reproduced this behaviour in a newly generated rails application (Rails 3.2.15, Ruby 1.9.3-p448, Haml 4.0.2):

Consider the following oneliner view app/views/welcome/index.html.haml:

-haml_concat_test

and the following method in app/helpers/welcome_helper.rb:

module WelcomeHelper
  def haml_concat_test
    haml_concat '<script language="javascript" type="text/javascript">alert("Evil.");</script>'
    haml_tag :p, :class => 'input' do
      haml_concat '<script language="javascript" type="text/javascript">alert("Evil2.");</script>'
      haml_tag :span, '<script language="javascript" type="text/javascript">alert("Evil3.");</script>'
      haml_concat '<b>Bold!</b>'
    end
  end
end

The following HTML will be generated:

&lt;script language=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;alert(&quot;Evil.&quot;);&lt;/script&gt;
<p class='input'>
  <script language="javascript" type="text/javascript">alert("Evil2.");</script>
  <span>&lt;script language=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;alert(&quot;Evil3.&quot;);&lt;/script&gt;</span>
  <b>Bold!</b>
</p>

The '<' and '>' chars of the content inside the haml_tag span have been escaped correctly. However the content added with haml_concat has not been escaped. When opening this view the alert "Evil2" pops up and the text 'Bold!' appears bold.

Why doesn't haml escape the contents when using haml_concat inside of a haml_tag block? Do we need to enable escaping globally anywhere?

Thanks a lot in advance,
Jesko

@mmircea16
Copy link
Contributor

This is the correct behavior, haml_concat outputs should not be escaped when are inside a haml_tag block. When xss safe is enabled the haml_tag implementation is the following:

def haml_tag_with_haml_xss(name, *rest, &block)
    name = haml_xss_html_escape(name.to_s)
    rest.unshift(haml_xss_html_escape(rest.shift.to_s)) unless [Symbol, Hash, NilClass].any? {|t| rest.first.is_a? t}
    with_raw_haml_concat {haml_tag_without_haml_xss(name, *rest, &block)}
end

The docs explanation for with_raw_haml_concat is explaining why it is needed.

@norman
Copy link
Contributor

norman commented Jan 7, 2014

This does seem like a bug. I believe it's happening because the outer call to haml_tag invokes raw_haml_concat, which sets @_haml_concat_raw = true inside the block. Then when haml_concat is called again, the content is simply appended to the buffer with no escaping because @_haml_concat_raw has already been set to true. It would be better to find some way to concat directly with no escaping only for the currently executing block, and not any other blocks that the block might yield to.

norman added a commit that referenced this issue Jan 7, 2014
The old value of _haml_concat_raw was not being set correctly, hence
calls to haml_concat after a call to haml_tag would result in the output
of haml_concat being appeneded unescaped.

Resolves #718
@norman norman closed this as completed in 4d575c1 Jan 7, 2014
@pseidemann
Copy link

actually the explanation from @norman applies for #731 but not for this issue. I've created #732 to address the issue stated here as @jesk wrote:

Why doesn't haml escape the contents when using haml_concat inside of a haml_tag block?

mattwildig added a commit that referenced this issue Nov 19, 2014
Before this commit, haml_tag relied on haml_concat to write its output.
This created a problem when XSS protection was in use - the tags
themselves needed not to be escaped, but the tags contents should be
escaped. The current workaround used the with_raw_haml_concat method to
set a flag to control whether haml_concat should be escaped, but this is
too crude and results in any use of haml_concat inside a block passed to
haml_tag not being escaped when it should.

Create new private methods in Helpers to allow more control of writing
to the buffer, and change haml_tag to use them so that haml_tag and
haml_concat behave correctly when XSS protection is in use.

Also alter haml_concat_with_haml_xss so it still respects
with_raw_haml_concat.

See #718, #731, #732
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants