最近看到一篇文章,文章講到輸入框有被 注入代碼攻擊 的危險,本身作了一個小示例,發現確實有這樣的狀況。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>
標籤,可是在代碼結構中能夠看到被插入的代碼片斷。 markdown
<script>
標籤執行 JavaScript
程序的代碼注入輸入框不經過 <script>
標籤執行 JavaScript
的方式仍是會有被攻擊的風險,好比 MDN 中舉到的例子: <img src='x' onerror='alert(1)'>
,咱們輸入後能夠看到程序是能夠執行的:oop
既然輸入框有被攻擊的風險,那咱們就應該作好防範,好在 Vue
已經替咱們最好了防範。若是沒有使用 Vue
,也有合適的解決辦法。post
Vue
在動態插入元素的時候,會將標籤的 <
、 >
等轉換爲轉義字符 <
、 >
等來避免 JavaScript
程序的執行,使用 Vue
經過輸入框插入代碼後,插入的頁面的代碼會被轉義以下:spa
未防範的狀況下,插入頁面的代碼以下:code
咱們可使用和 Vue
一樣的防範方法,將 <
、 >
、&
、 '
、 "
等符號替換成轉義字符來規避風險,這裏使用 zhangxiangliang 同窗在 《每日 30 秒 ⏱ 你們一塊兒被捕吧》 文章中寫的方法來作處理:orm
// 將輸入框的字符串經過正則,將符號替換成轉義字符 const escapeHTML = str => str.replace(/[&<>'"]/g, tag => ({ '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' }[tag] || tag)); 複製代碼
雖然有些攻擊的方式,在控制檯編輯後也能讓頁面錯亂,但若是咱們有規避風險方法,仍是不要給工做和公司帶來麻煩比較好。htm
每日 30 秒 ⏱ 你們一塊兒被捕吧: juejin.cn/post/684490…
MDN element.innerHTML:developer.mozilla.org/zh-CN/docs/…