最近看到一篇文章,文章讲到输入框有被
注入代码攻击
的危险,自己做了一个小示例,发现确实有这样的情况。
先来看小示例吧,一个最简单的留言功能,输入框输入信息,然后把信息插入页面:
<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.cn/post/684490…
MDN element.innerHTML:
developer.mozilla.org/zh-CN/docs/…