跨站脚本攻击(XSS攻击,Cross-Site Scripting)是一种常见的Web安全漏洞,攻击者通过在Web页面中注入恶意脚本,使其在用户的浏览器上执行。攻击者可以通过恶意脚本窃取用户的敏感信息,如登录凭据、Cookie等,或者对用户进行其他恶意操作。
XSS攻击通常分为三种类型:
存储型(Stored XSS): 恶意脚本被存储在服务器上,当用户访问包含这些脚本的页面时触发。
反射型(Reflected XSS): 恶意脚本作为用户输入的一部分,被服务器返回并执行。这种攻击方式通常通过诱导用户点击包含攻击代码的恶意链接实现。
DOM-based XSS: 攻击不涉及服务器端,而是通过修改页面的DOM结构,触发恶意脚本的执行。
防御 XSS 攻击的方法:
输入验证和过滤: 对用户输入的数据进行验证和过滤,确保不包含恶意脚本。可以使用白名单过滤用户输入,只允许安全的标签和属性。
输出编码: 在将用户输入显示到页面时,对其进行HTML编码。这样可以确保浏览器不会将用户输入解释为可执行的脚本。
HttpOnly Cookie: 使用HttpOnly标志设置Cookie,使其不可通过脚本访问,从而减少Cookie被盗取的风险。
Content Security Policy(CSP): 使用CSP头部来指定浏览器只加载指定来源的资源,减少XSS攻击的风险。
下面是一个简单的演示,展示了一个容易受到 XSS 攻击的情况以及如何防御:
<!DOCTYPE html>
<html>
<head>
<title>XSS演示</title>
</head>
<body>
<!-- 受攻击的情况 -->
<h1>欢迎,<span id="username">用户</span>!</h1>
<script>
var username = getParameterByName('username');
document.getElementById('username').innerText = username;
</script>
<!-- 防御 XSS 攻击 -->
<h1>欢迎,<span id="safeUsername"></span>!</h1>
<script>
var username = getParameterByName('username');
// 对用户输入进行HTML编码
document.getElementById('safeUsername').innerText = encodeHTML(username);
function encodeHTML(value) {
return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
</script>
</body>
</html>
在这个例子中,原始版本容易受到XSS攻击,因为它直接将URL参数中的输入插入到HTML中。而防御版本使用了HTML编码来确保用户输入不会被解释为可执行的脚本。