最近看到一篇文章,文章講到輸入框有被 注入代碼攻擊 的危險,本身作了一個小示例,發現確實有這樣的狀況。javascript
先來看小示例吧,一個最簡單的留言功能,輸入框輸入信息,而後把信息插入頁面:html
<body>
<div id="content"></div>
<input id='input'>
<input type="button" id='button' value="提交">
</body>
<script> const btn = document.getElementById('button'); const myInput = document.getElementById('input'); const content = document.getElementById('content'); btn.onclick = ()=> { content.innerHTML = myInput.value }; </script>
複製代碼
在輸入框中輸入 <h1>哈哈,你的頁面結構被我破壞了</h1>
,而後提交,效果以下:java
<script>
標籤注入輸入框在輸入框中輸入 <script> alert(0); </script>
,而後提交。
咱們會發現沒有彈窗,這裏沒有執行 JavaScript
程序的緣由是:HTML 5
中不執行由 innerHTML
插入的 <script>
標籤,可是在代碼結構中能夠看到被插入的代碼片斷。 post
<script>
標籤執行 JavaScript
程序的代碼注入輸入框不經過 <script>
標籤執行 JavaScript
的方式仍是會有被攻擊的風險,好比 MDN 中舉到的例子: <img src='x' onerror='alert(1)'>
,咱們輸入後能夠看到程序是能夠執行的:ui
既然輸入框有被攻擊的風險,那咱們就應該作好防範,好在 Vue
已經替咱們最好了防範。若是沒有使用 Vue
,也有合適的解決辦法。spa
Vue
在動態插入元素的時候,會將標籤的 <
、 >
等轉換爲轉義字符 <
、 >
等來避免 JavaScript
程序的執行,使用 Vue
經過輸入框插入代碼後,插入的頁面的代碼會被轉義以下:code
未防範的狀況下,插入頁面的代碼以下:regexp
咱們可使用和 Vue
一樣的防範方法,將 <
、 >
、&
、 '
、 "
等符號替換成轉義字符來規避風險,這裏使用 zhangxiangliang 同窗在 《每日 30 秒 ⏱ 你們一塊兒被捕吧》 文章中寫的方法來作處理:cdn
// 將輸入框的字符串經過正則,將符號替換成轉義字符
const escapeHTML = str =>
str.replace(/[&<>'"]/g, tag => ({
'&': '&',
'<': '<',
'>': '>',
"'": ''',
'"': '"'
}[tag] || tag));
複製代碼
雖然有些攻擊的方式,在控制檯編輯後也能讓頁面錯亂,但若是咱們有規避風險方法,仍是不要給工做和公司帶來麻煩比較好。htm
每日 30 秒 ⏱ 你們一塊兒被捕吧: juejin.im/post/5c92c1…
MDN element.innerHTML:developer.mozilla.org/zh-CN/docs/…