XSS(Cross-Site Scripting)是一种常见的安全漏洞,攻击者通过在页面中注入恶意脚本代码,诱导用户的浏览器执行这些代码,从而达到窃取用户数据、伪造操作或劫持用户会话的目的。
XSS 的攻击目标通常是用户的浏览器,而不是服务器本身。
XSS 分类
-
存储型 XSS:
- 恶意脚本被永久存储在服务器上(如数据库中)。
- 用户访问包含恶意脚本的页面时,脚本被加载并执行。
- 示例: 攻击者在留言板中输入:
如果网站没有对用户输入进行过滤,其他用户访问留言板时会触发这个脚本。<script>alert('Your session is hijacked!');</script>
-
反射型 XSS:
- 恶意脚本通过 URL 参数或其他途径传递,服务器直接将其返回到页面中。
- 用户点击带有恶意脚本的链接时,脚本被执行。
- 示例: 用户访问这样的链接:
如果服务器直接将http://example.com?query=<script>alert('Hacked');</script>
query
参数渲染到页面中,脚本会执行。
-
DOM 型 XSS:
- 恶意脚本通过浏览器端的 JavaScript 操作直接注入,不经过服务器。
- 示例: 如果网站的某个功能是从 URL 中读取参数并插入到 DOM 中,而没有过滤:
当用户访问document.body.innerHTML = "Welcome, " + location.search.substring(1);
http://example.com/?<script>alert('XSS');</script>
时,恶意代码会直接被执行。
XSS 的危害
- 窃取用户的登录信息(如 Cookies 和 Session Token)。
- 劫持用户会话(冒充用户进行操作)。
- 在页面中加载恶意内容(如钓鱼网站、广告等)。
- 操作用户的浏览器(如重定向到恶意网站)。
XSS 的防范措施
1. 输入过滤
- 对用户的输入进行严格过滤和验证。
- 禁止用户输入 HTML、JavaScript 等脚本内容。
- 示例: 使用 正则表达式 或专用库过滤用户输入:
const sanitizeInput = (input) => input.replace(/<[^>]+>/g, "");
2. 输出编码
- 在将用户输入的内容输出到页面之前,对内容进行编码。
- 确保 HTML 特殊字符(如
<
,>
,"
,'
等)不会被解释为 HTML。 - 示例: 使用框架自带的转义工具:
Vue 和 React 等现代前端框架默认会对动态内容进行 HTML 编码。{{ userInput }}
3. Content Security Policy (CSP)
- 设置 CSP 限制页面中允许加载的资源。
- 禁止页面加载外部的 JavaScript 文件或执行内联脚本。
- 示例(设置 HTTP 响应头):
这会阻止外部脚本的执行。Content-Security-Policy: script-src 'self'
4. 避免使用危险的 DOM 操作
- 避免直接插入 HTML 到页面中。
- 不安全的代码:
document.body.innerHTML = userInput;
- 安全的代码: 使用安全的 DOM API,比如:
const div = document.createElement("div"); div.textContent = userInput; document.body.appendChild(div);
5. 使用框架的安全特性
- 使用现代框架(如 Vue、React、Angular),它们默认会对动态内容进行 HTML 转义。
- 在 Vue 中,默认情况下:
会将<p>{{ userInput }}</p>
userInput
中的<script>
转义为普通字符串。
6. HTTP-Only 和 Secure Cookie
- 避免将敏感信息存储在客户端可访问的地方(如
localStorage
或sessionStorage
)。 - 将 token 或 session ID 存储在 HttpOnly 的 Cookie 中,这样 JavaScript 无法读取它。
- 示例(后端设置 Cookie):
Set-Cookie: token=abc123; HttpOnly; Secure
7. 验证用户输入
- 检查输入的格式和内容是否符合预期。
- 例如,用户名只能包含字母和数字:
const isValidUsername = (input) => /^[a-zA-Z0-9]+$/.test(input);
8. 使用专用库
- 使用可靠的第三方库处理用户输入或 HTML 内容。
- 示例库:
- DOMPurify:清理用户输入的 HTML,防止 XSS。
import DOMPurify from "dompurify"; const cleanHtml = DOMPurify.sanitize(userInput);
- DOMPurify:清理用户输入的 HTML,防止 XSS。
9. 设置 SameSite Cookie
- 限制 Cookie 的跨站点发送,防止被用于跨站请求伪造(CSRF)攻击。
- 示例:
Set-Cookie: sessionId=abc123; SameSite=Strict;
总结
优先事项
- 对用户输入 过滤 和 转义。
- 避免直接操作 HTML,优先使用框架的模板引擎。
- 使用安全的存储方式(如
HttpOnly
Cookie)管理 token。 - 设置 CSP 限制脚本执行来源。
- 检查后端是否也对用户数据进行了验证,前后端共同防范。
如果你想了解具体实现的代码或者更多示例,我可以进一步说明!