Web安全中的XSS攻击详细教学,Xss-Labs靶场通关全教程(建议收藏) - 白小雨 - 博客园跨站脚本攻击(XSS)主要是攻击者通过注入恶意脚本到网页中,当用户访问该页面时,恶意脚本会在用户的浏览器中执行,从而可能导致数据被篡改、用户信息泄露等问题。为了防止 XSS 攻击导致的数据篡改,可以从输入验证与过滤、输出编码、设置 CSP、HttpOnly 等方面着手,以下是详细介绍:
function validateInput(input) {
// 只允许字母和数字
const regex = /^[a-zA-Z0-9]+$/;
return regex.test(input);
}
const userInput = document.getElementById('userInput').value;
if (validateInput(userInput)) {
// 处理合法输入
} else {
// 提示用户输入不合法
}
he
库对输出进行 HTML 编码。const he = require('he');
const userInput = '';
const encodedInput = he.encode(userInput);
// 输出编码后的内容,如 <script>alert("XSS")</script>
console.log(encodedInput);
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self'");
next();
});
app.get('/', (req, res) => {
res.send('Hello, World!');
});
const port = 3000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
HttpOnly
属性,这样 JavaScript 脚本就无法访问这些 Cookie,从而防止攻击者通过 XSS 攻击窃取或篡改 Cookie 中的数据。HttpOnly
属性的 Cookie。const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.cookie('session_id', '123456', { httpOnly: true });
res.send('Cookie has been set');
});
const port = 3000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
onclick
、onload
)和内联脚本容易受到 XSS 攻击,应尽量避免使用。可以通过分离 HTML、CSS 和 JavaScript 代码,使用事件委托等方式来处理事件。
推荐的事件委托写法:
在处理潜在的不信任输入时,直接使用 innerHTML
是非常危险的,因为它可以导致跨站脚本攻击(XSS)。当您将不受信任的数据插入到网页中时,如果使用了 innerHTML
,那么这段数据可能会包含恶意脚本,这些脚本会在用户的浏览器上执行。
例如,如果你直接从用户输入获取数据并将其赋值给 innerHTML
,如下所示:
const userInput = "
";
someElement.innerHTML = userInput;
在这种情况下,用户的输入包含了恶意脚本,它会创建一个带有错误图片链接的
标签,并且当加载图像失败时触发 onerror
事件,从而执行 JavaScript 警告框。这种行为就是 XSS 攻击的一个简单例子。
为了避免这种情况,你应该尽量避免直接使用 innerHTML
来插入不信任的内容。如果必须使用,应该确保对内容进行适当的转义或清理,以去除任何可能的脚本元素或其他危险代码。更安全的选择是使用文本显示方法如 textContent
或者 innerText
来显示不信任的内容,因为它们不会解析 HTML,因此不会执行其中的脚本。
另外,对于一些特定场景,比如需要允许某些格式化但不允许脚本执行,可以考虑使用库如 DOMPurify 对输入进行清理,这样可以安全地移除潜在的有害部分但仍保留一定的富文本格式。例如:
import DOMPurify from 'dompurify';
const cleanUserInput = DOMPurify.sanitize(userInput);
someElement.innerHTML = cleanUserInput;
总之,在处理用户输入时务必小心谨慎,尤其是在将其插入到页面中时,应采取一切必要措施防止 XSS 攻击。
使用正则表达式对用户输入进行验证,只允许特定字符通过,避免恶意脚本注入。
输入验证防止 XSS
在这个示例中,validateInput
函数使用正则表达式对用户输入进行验证,确保输入只包含字母、数字、空格和常见标点符号。如果输入合法,将其显示在页面上;否则,给出错误提示。
将用户输入的内容进行 HTML 实体编码,避免浏览器将其解析为 HTML 标签或脚本。可以使用 DOMPurify
库来实现。首先需要引入 DOMPurify
库,你可以通过 CDN 引入:
输出编码防止 XSS
在这个示例中,当用户点击提交按钮时,使用 DOMPurify.sanitize
方法对用户输入进行净化,将其中的恶意脚本等危险内容过滤掉,然后将净化后的内容插入到页面中。
内联事件(如 onclick
、onload
)和内联脚本容易受到 XSS 攻击,应尽量避免使用。可以通过事件委托等方式来处理事件。
避免内联事件防止 XSS
在这个示例中,使用 addEventListener
方法为按钮添加点击事件,而不是使用内联的 onclick
事件,这样可以避免潜在的 XSS 风险。
textContent
而不是 innerHTML
当需要向页面插入文本内容时,使用 textContent
而不是 innerHTML
,因为 textContent
会将内容作为纯文本处理,不会解析其中的 HTML 标签。
使用 textContent 防止 XSS
在这个示例中,使用 textContent
将用户输入的内容插入到页面中,确保内容以纯文本形式显示,避免 HTML 标签和脚本的执行。