2026-02-05 21:42:03
XSS(跨站脚本攻击)是一种通过注入恶意脚本窃取用户敏感信息的代码注入攻击,主要分为反射型、存储型和DOM型三种。防御XSS需结合输入输出处理、前端安全编码及CSP策略等综合措施。
一、XSS攻击类型及原理反射型XSS
攻击流程:攻击者构造含恶意代码的URL→用户点击后服务端将恶意代码拼接到HTML返回→浏览器执行恶意脚本窃取数据。
特点:恶意代码仅通过URL传递,不存储在服务端,常见于搜索、跳转等通过URL传参的功能。
示例场景:
用户访问恶意URL:
服务端未过滤直接将keyword参数拼接到HTML中返回,导致浏览器执行脚本。
存储型XSS
攻击流程:攻击者提交恶意代码至数据库→其他用户访问时服务端从数据库取出恶意代码拼接到HTML→浏览器执行脚本窃取数据。
特点:恶意代码持久化存储在数据库中,影响范围广,常见于评论、文章详情等交互功能。
示例场景:
攻击者在评论区提交包含恶意脚本的内容:<script>alert('xss')</script>
其他用户访问该页面时,服务端从数据库读取评论内容并拼接到HTML中,导致脚本执行。
DOM型XSS
攻击流程:攻击者构造含恶意代码的URL→用户打开后浏览器解析响应,前端JavaScript取出URL中的恶意代码并执行。
特点:恶意代码执行完全在浏览器端完成,属于前端安全漏洞,与服务端无关。
示例场景:
用户访问恶意URL:
前端JavaScript通过location.search获取URL参数并直接插入DOM,触发onerror事件执行脚本。
输入过滤的局限性
前端过滤易被绕过(如直接构造请求提交恶意代码)。
后端入库前转义可能导致数据输出到非浏览器客户端时乱码(如10 < 20转义为10 < 20后,在APP端显示异常)。
结论:输入阶段不建议转义,应在输出时处理。
防御反射型与存储型XSS
纯前端渲染:
通过静态HTML加载JavaScript脚本,业务数据通过Ajax请求获取,再通过DOM API(如.innerText、.setAttribute)更新页面。
优势:代码与数据分离,避免服务端拼接HTML的风险。
注意:需防范DOM型XSS(如避免使用.innerHTML插入未过滤数据)。
HTML转义:
必须拼接HTML时,使用转义库(如Node.js的js-xss)对&、<、>、"、'等字符进行转义。
示例:
const xss = require('xss');const html = xss('<script>alert("xss")</script>', { whiteList: {} }); // 输出转义后的安全HTML防御DOM型XSS
安全编码实践:
避免使用.innerHTML、.outerHTML、document.write()等直接执行字符串的API,优先使用.textContent、.setAttribute()。
示例:
// 不安全:可能执行恶意脚本document.getElementById('demo').innerHTML = userInput;// 安全:仅作为文本处理document.getElementById('demo').textContent = userInput;URL参数处理:
对从URL中获取的参数(如location.search、location.hash)进行严格验证或转义后再使用。
CSP(内容安全策略)
作用:通过HTTP头Content-Security-Policy限制资源加载来源,阻止内联脚本执行,降低XSS攻击风险。
配置示例:
Content-Security-Policy: default-src 'self'; script-src 'self'default-src 'self':仅允许加载同源资源。
script-src:限制脚本加载来源,禁止内联脚本(如<script>标签或javascript:协议URL)。
object-src 'none':禁止加载插件(如Flash)。
通过综合应用上述策略,可显著降低XSS攻击风险,保护用户数据安全。