How to safely render Action Text?

The Action Text guide instructs to render rich text with = @message.content (I don’t use the <% %> symbols as I am using slim templates).

However this renders the raw HTML source code:

I can fix this by replacing with == @message.content:

But then it yields a brakeman vulnerability error:

Confidence: Weak
Category: Cross-Site Scripting
Check: CrossSiteScripting
Message: Unescaped parameter value
Code: authorize(@posts.find_by_uid!(params.require(:id))[/.*--(.*)/, 1]).body
File: app/views/posts/show.html.slim
Line: 26

What is the correct and safe way to render Action Text?

OK, I’ve escaped the parameter using CGI::escapeHTML. This makes brakeman happy.

However I still wonder why the guide instructs using = instead of ==?


I’ve tried looking into this and see if I can reproduce your issue.

I’m on Rails 6.1 and currently use ERB templates, but used HAML in the past (which don’t require enclosing Ruby injection in <% %>).

I’ve added brakeman to my project and ran a quick scan. I did not get the XSS error for rendering the ActionText content, and from what brakeman reports the issue is with a different line in your view (your authorize call). I’m not sure this is related to ActionText. Maybe if you can add more context to this, I can continue dig into the issue (your controller action + complete view content).

For Slim it seems like you should use == according to this (GitHub - slim-template/slim: Slim is a template language whose goal is to reduce the syntax to the essential parts without becoming cryptic.) to not escape, just as it is with a yield call. The ActionText guide is based on ERB templates so that’s why it puts only one = instead of two.

Thanks Raul, about brakeman I found a proper fix so it’s not a problem. For historical reasons I’m loading my posts from the URL in a pretty non-standard way (find_by_uid!(params.require(:id))[/.*--(.*)/, 1])), so maybe escapeHTML is needed because of this, but anyway it doesn’t matter. This fix is good enough and I’ll see in the future if it’s still needed when cleaning up the code.

Also good to know about this difference between erb and slim (= vs. ==)!

1 Like

I have the exact same problem. Have tried a variety of things.

I believe this is the same issue as: ActionText: renders raw html when using slim-rails. Rails 6.0.0rc2 & ruby 2.5.5 · Issue #36955 · rails/rails · GitHub.

1 Like