例子1:
源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
const data = decodeURIComponent(location.hash.substring(1));
const root = document.createElement('div');
root.innerHTML = data;
//这里模拟了xss过滤的过程,方法是移除所有属性
for(let el of root.querySelectorAll('*')) {
for (let attr of el.attributes) {
el.removeAttribute(attr.name);
}
}
document.body.appendChild(root);
</script>
</html>
因为现在是没有任何属性的,所以输出aaa
输入<script>alert(1)</script>
这样的标签确实没有任何属性,但是源码中是innerHTML,所以只能用img标签
输入<img src="1" onerror="alert(1)">
,发现把src属性删掉了
我们去断点调试一下,看看究竟为什么只删除了src属性,没有删除onerror属性
1、首先el是没有值的
2、el有值了,它是img,因为img传进来了
关键的是去看img中的attributes,有两个属性,一个src,一个onerror,看上去像数组一样的一个东西,有索引0和索引1。