我正在Rails應用程式中呈現一個.js.erb
檔案。在這個文件中,我正在更新一個選擇框的選項。
最重要的是,我以一種XSS安全的方式進行操作。根據這個Stack Overflow的解決方案,引用了OWASP DOM based XSS Prevention Cheat Sheet,我以以下方式更新選擇框的選項:
嘗試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 %>
blog.name
的顯示文字被進行了HTML編碼。例如,"Johnson & Johnson"的文字顯示為:"Johnson &
Johnson"。其他特殊字元如撇號也會有相同的顯示問題。 嘗試2
我知道Rails有一個html_safe
方法,所以我嘗試使用它:我將"<%= blog.name %>";
更新為" <%= blog.name.html_safe %>";
。
blog.name
設定為alert("Gotcha");
來測試XSS時,它會出錯:選項根本沒有被更新。最終似乎問題是在這種上下文中使用html_safe
,應用程式不知道如何處理雙引號。 嘗試3
#這個方法似乎有效。它更新了選項,顯示文字也正常運作,而顯示文字為alert("gotcha");
的選項只是作為文字顯示,而不會執行為程式碼:
// 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) %>");
j
(escape_javascript
的別名)是不安全的。 目前還不清楚我如何以一種既安全又正確顯示文字的方式從.js.erb
範本中更新選擇選項。
嘗試給出我的理解:
雖然你可以解碼特殊字元,但這不是Rails的方式。
html_safe並不能確保字串結果是安全的,而是你明確指定字串是安全的,這樣字串中的HTML標籤才能以HTML形式顯示,因此它不能解決XSS問題。
根據這篇文章,在單引號或雙引號中使用
escape_javascript
是安全的。因此,嘗試3是XSS安全的,也是Rails的方式,是首選的。
你的程式碼可以簡化為: