前言
最近看到一篇文章, 文章讲到输入框有被 注入代码攻击 的危险, 自己做了一个小示例, 发现确实有这样的情况.
示例
先来看小示例吧, 一个最简单的留言功能, 输入框输入信息, 然后把信息插入页面:
页面效果
关键代码
- <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>
代码注入输入框 可能引发攻击的几种方式
HTML 代码注入输入框
在输入框中输入 <h1 > 哈哈, 你的页面结构被我破坏了 </h1>, 然后提交, 效果如下:
<script> 标签注入输入框
在输入框中输入 <script> alert(0); </script> , 然后提交.
我们会发现没有弹窗, 这里没有执行 JavaScript 程序的原因是: HTML 5 中不执行由 innerHTML 插入的 <script> 标签, 但是在代码结构中可以看到被插入的代码片段.
其他不通过 <script> 标签执行 JavaScript 程序的代码注入输入框
不通过 <script> 标签执行 JavaScript 的方式还是会有被攻击的风险, 比如 MDN 中举到的例子: <img src='x' onerror='alert(1)'> , 我们输入后可以看到程序是可以执行的:
防范
既然输入框有被攻击的风险, 那我们就应该做好防范, 好在 vue 已经替我们最好了防范. 如果没有使用 Vue , 也有合适的解决办法.
Vue 的防范原理
Vue 在动态插入元素的时候, 会将标签的 <,> 等转换为转义字符 < , > 等来避免 JavaScript 程序的执行, 使用 Vue 通过输入框插入代码后, 插入的页面的代码会被转义如下:
未防范的情况下, 插入页面的代码如下:
原生 JavaScript 防范方法
我们可以使用和 Vue 同样的防范方法, 将 <,> ,& , '," 等符号替换成转义字符来规避风险, 这里使用 zhangxiangliang 同学在 《每日 30 秒 大家一起被捕吧》 文章中写的方法来做处理:
- // 将输入框的字符串通过正则, 将符号替换成转义字符
- const escapeHTML = str =>
- str.replace(/[&<>'"]/g, tag => ({
- '&': '&',
- '<': '<',
- '>': '>',
- "'":''',
- '"':'"'
- }[tag] || tag));
总结
虽然有些攻击的方式, 在控制台编辑后也能让页面错乱, 但如果我们有规避风险方法, 还是不要给工作和公司带来麻烦比较好.
参考资料
每日 30 秒 大家一起被捕吧: juejin.im/post/5c92c1...
MDN element.innerHTML:
来源: https://juejin.im/post/5c94579d518825573578c8b3