Update js.erb template for select box options - handle XSS securely and display text correctly
P粉674757114
P粉674757114 2024-03-31 00:36:22
0
1
567

I'm rendering a .js.erb file in a Rails application. In this file, I'm updating the options of a select box.

The most important thing is that I do it in an XSS safe way. Based on this Stack Overflow solution, referencing the OWASP DOM based XSS Prevention Cheat Sheet, I update the select box's options in the following way:

Try 1

// app/views/blogs/blogs_select_listing.js.erb

// 删除所有选项
$('#blog_select_box').children().remove();

// 遍历@blogs集合,将每个博客项目作为选项添加到选择框中
<% @blogs.each do |blog| %>
  var opt = document.createElement("option");
  opt.setAttribute("value", "<%= blog.id %>");
  opt.textContent = "<%= blog.name %>";
  $('#blog_select_box').append(opt);
<% end %>
  • Problem: The display text of blog.name is HTML encoded. For example, the text for "Johnson & Johnson" reads: "Johnson & Johnson". Other special characters such as apostrophes will have the same display problem.

Try 2

I know Rails has a html_safe method, so I tried using it: I updated "<%= blog.name %>"; to " <%= blog.name.html_safe %>";.

  • Problem: When I test for XSS by setting blog.name to alert("Gotcha"); it gives the error: option at all has not been updated. Ultimately it seems the problem is that using html_safe in this context, the application doesn't know what to do with double quotes.

Try 3

This methodseemseffective. It updates the options and the display text works fine, while the options with the display text alert("gotcha"); just display as text and don't execute as code:

// app/views/blogs/blogs_select_listing.js.erb

// 删除所有选项
$('#blog_select_box').children().remove();

// 遍历@blogs集合,将每个博客项目作为选项添加到选择框中
$('#blog_select_box')
.html("<%= j options_from_collection_for_select(@blogs, :id, :name) %>");
  • Question: I'm not sure if this is safe. I'm not sure because I saw this article which stated that j (an alias for escape_javascript) is unsafe.

It's unclear how I can update the selection options from the .js.erb template in a way that is both safe and displays the text correctly.

P粉674757114
P粉674757114

reply all(1)
P粉594941301

Try to give my understanding:

  • Try 1

While you can decode special characters , that's not the Rails way.

  • Try 2

html_safe does not ensure that the string result is safe, but you explicitly specify that the string is safe so that the HTML tags in the string can be displayed in HTML form, so it does not solve the XSS problem .

string = '<div>html with string</div>'
<%= string.html_safe %> # 以HTML形式显示
<%= string %> # 以字符串形式显示
  • Try 3

According to this article, it is safe to use escape_javascript within single or double quotes.

# 安全
'<%= j string %>' # 或者
"<%= j string %>"

# 不安全
<%= j string %>  # 或者
`<%= j string %>`

Therefore, attempt 3 is XSS safe and the Rails way, and is preferred.

Your code can be simplified to:

# html()方法会替换原始内容,所以你不需要先删除它
$('#blog_select_box')
  .html("<%= j options_from_collection_for_select(@blogs, :id, :name) %>");
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template