举一个示例。
先准备一个输入页面:
<input type="text" id="input">
<button id="btn">Submit</button>
<script>
const input = document.getElementById('input');
const btn = document.getElementById('btn');
let val;
input.addEventListener('change', (e) => {
val = e.target.value;
},false);
btn.addEventListener('click', (e) => {
fetch('http://localhost:8001/save', {
method: 'POST',
body: val
});
}, false);
</script>
启动一个 Node 服务监听 save 请求。为了简化,用一个变量来保存用户的输入:
const http = require('http');
let userInput = '';
function handleReequest(req, res) {
const method = req.method;
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
if (method === 'POST' && req.url === '/save'){
let body = '';
req.on('data',chunk => {
body += chunk;
});
req.on('end', () => {
if (body) {
userInput = body;
}
res.end();
});
} else {
res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'});
res.write(userInput); //将输入的脚本内容返回给前端页面
res.end();
}
}
const server = new http.Server();
server.listen(8001, '127.0.0.1');
server.on('request', handleReequest);
当用户点击提交按钮将输入信息提交到服务端时,服务端通过 userInput 变量保存了输入内容。当用户通过 http://localhost:8001/${id} 访问时,服务端会返回与 id 对应的内容(本示例简化了处理)。如果用户输入了恶意脚本内容,则其他用户访问该内容时,恶意脚本就会在浏览器端执行:

1.3 基于DOM
基于 DOM 的 XSS 攻击是指通过恶意脚本修改页面的 DOM 结构,是纯粹发生在客户端的攻击。
看如下代码:
<h2>XSS: </h2>
<input type="text" id="input">
<button id="btn">Submit</button>
<div id="div"></div>
<script>
const input = document.getElementById('input');
const btn = document.getElementById('btn');
const div = document.getElementById('div');
let val;
input.addEventListener('change', (e) => {
val = e.target.value;
}, false);
btn.addEventListener('click', () => {
div.innerHTML = `<a href=${val}>testLink</a>`
}, false);
</script>
点击 Submit 按钮后,会在当前页面插入一个链接,其地址为用户的输入内容。如果用户在输入时构造了如下内容:
'' onclick=alert(/xss/)
用户提交之后,页面代码就变成了:
