[Rails] Rails 內顯示輸入的HTML
這次的範例如下
首先使用 simple format <%= simple_format @comment.description %>
,顯示出來會是:
原始碼:
跟當初輸入的不一樣。這是因為 simple_format 的安全機制會過濾 HTML的輸出。
另外,在輸入框中的換行,輸出時會多包一層 <p>
tag來區分段落。
所以 simple_format 不適合用在用戶輸入 HTML 的情況。
那我們來試試看 Rails默認的輸出 <%= @comment.description %>
,顯示出來是:
原始碼:
Rails 默認的安全機制,會將HTML 脫逸,例如 <
會變成 <
。
所以Rails 默認的輸出也不適合用在用戶輸入 HTML 的情況。
下一個我們來嘗試 <%= raw @comment.description %>
或 <%= @comment.description.html_safe %>
,顯示出來是:
原始碼:
結果看起來是對的,但完全沒有脫逸 HTML,會有一些安全性問題
例如在輸入框輸入:
那麼當其他用戶瀏覽到這一頁時,瀏覽器就會盲目的執行這段 JavaScript
這種攻擊方式叫 XSS 跨站腳本攻擊。任何網站只要允許用戶輸入資料,就有這個風險。防範的方式就是在輸出時,進行過濾或一律脫逸。
使用 raw 或 html_safe 的話,就是告訴 Rails 這個輸出字串是安全的。
所以 raw 與 html_safe 也不適合用在讓用戶輸入的情況。
需要顯示用戶輸入的 HTML 又要有安全性,那就需要一種白名單的過濾機制了,Rails 提供了 sanitize helper。
使用<%= sanitize @comment.description %>
:
看起來比較正常了,但還是少了table 標籤和style 屬性
這是因為
- 允許的HTML 標籤 strong em b i p code pre tt samp kbd var sub sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr acronym a img blockquote del ins
- 允許的HTML 屬性 href src width height alt cite datetime title class name xml:lang abbr
table 跟 style 不在裡面,我們需要自己加。修改 config/application.rb
加入
config.action_view.sanitized_allowed_tags = Rails::Html::WhiteListSanitizer.allowed_tags + %w(table tr td)
config.action_view.sanitized_allowed_attributes = Rails::Html::WhiteListSanitizer.allowed_attributes + %w(style border)
重啟 server 再看一次結果
這樣就能滿足安全性要求,又達到我們要的結果了。