CVE-2020–15169
- Backend
- 08 Oct, 2020
來看看這個 CVE-2020–15169 漏洞是怎麼回事
看 https://github.com/advisories/GHSA-cfjv-5498-mph5 的說明可以知道,發生的時機在於,如果你使用了 https://guides.rubyonrails.org/i18n.html#using-safe-html-translations 說明的這種翻譯,例如
# app/views/home/index.html.erb
<%= t("welcome_html", default: untrusted_user_controlled_string) %>
在翻譯找不到時,會使用 default 的值,假如這個值裡面有使用者可以放入的字串,就會有 XSS 的風險,因為這個值不會被跳脫。
修補的程式碼可以看這邊 https://gist.github.com/georgeclaghorn/a466e103922ee81f24c32c9034089442#file-6-0-translate-helper-xss-patch
概念就是如果發現 I18n.translate 出來的 translate 值是 MISSING_TRANSLATION,就不做 html_safe 的處理。
玩玩看
我實際做了一個專案來測試這個漏洞,可以看這個 commit
# config/locales/zh-TW.yml
zh-TW:
hello: "你好,世界"
# config/locales/en.yml
en:
hello: "Hello world"
hello_html: <b>hello! %{user_name}</b>
# app/views/users/index.html.erb
<td><%= t('hello_html', user_name: user.name, default: "<b>hello! #{user.name}</b>") %></td>
因為 zh-TW 語系找不到 hello_html 的翻譯,就使用預設的英文翻譯,裡面夾帶使用者的名字,而使用者的名字是一段 js 程式碼,不會被跳脫。當進入 http://localhost:3000/users?locale=zh-Tw 就會跳出
