跨站脚本攻击 XSS 简介
在现代网站架构中,动态内容已成为不可或缺的组成部分。所谓动态内容,是指Web应用程序能够根据用户的环境特征和特定需求,实时生成并输出相应的定制化内容。这种动态特性在提升用户体验的同时,也带来了潜在的安全隐患。
其中,跨站脚本攻击(Cross Site Scripting,简称XSS)是动态站点面临的主要安全威胁之一。值得注意的是,XSS最初应被缩写为CSS,但为避免与层叠样式表(Cascading Style Sheet, CSS)混淆,安全界统一采用了XSS这一命名。与动态站点形成鲜明对比的是,静态站点因其特性完全不受XSS攻击的影响。
XSS攻击的本质在于恶意攻击者通过在Web页面中植入精心构造的恶意Script代码。当不知情用户访问该页面时,嵌入的恶意代码会被浏览器执行,从而实现攻击者的恶意目的。从技术层面来看,跨站脚本攻击是一种针对网站应用程序的安全漏洞利用技术,属于代码注入攻击的范畴。这种攻击允许恶意用户将代码注入目标网页,当其他用户浏览该页面时,便会受到攻击影响。成功实施XSS攻击后,攻击者可能获取包括高级权限、敏感网页内容、会话信息以及Cookie数据在内的多种重要信息。
特别值得关注的是,攻击者利用XSS漏洞可以绕过关键的安全控制机制,如同源策略(Same origin policy)。这类漏洞因其常被用于实施更具危害性的网络钓鱼(Phishing)攻击而备受关注。在黑客界,XSS攻击被普遍视为新型的"缓冲区溢出攻击",而JavaScript则被认为是新型的"ShellCode"。
从技术本质来看,XSS攻击的核心策略在于诱导用户的浏览器执行原本不在网页代码中的前端代码。这种攻击方式充分利用了浏览器对JavaScript等脚本语言的解析执行机制,通过构造特殊的输入,使得恶意代码能够被合法地嵌入并执行,从而实现对目标系统的攻击。
XXS 分类:反射型、存储型、DOM型
反射型 XXS 网络攻击
原理:反射型 xss 又称非持久型 xss,是目前最普遍的类型,这种攻击方式往往具有一次性。发出请求时,XSS代码出现在 URL 中,作为输入提交到服务器端,服务器端解析后响应,XSS 代码随响应内容一起传回给浏览器,最后浏览器解析执行 XSS 代码。这个过程像一次反射,所以称反射型 XSS。
攻击方式:攻击者通过电子邮件等方式将包含 xss 代码的恶意链接发送给目标用户。当目标用户访问该链接时,服务器接受该用户的请求并进行处理,然后服务器把带有 xss 代码的数据发送给目标用户的浏览器,浏览器解析这段带有 xss 代码的恶意脚本后就会触发 xss 漏洞
反射型靶场实训
- 进入靶场: xss-game.appspot.com
- 随意输入内容,点击 Search ,可看到搜索内容以 query=Apex 的形式发送处理,并在网页内显示搜索的内容
- 在 URL 中修改
Apex为<h1>XSS</h1>,然后点击回车,发现网页显示的内容变大,探测成功。 - 网站运行我们修改内容并使用 html 标签,我们可以利用这一点来运行脚本,改为
<script>alert('XSS')</script>,再次回车,发现弹出窗口,攻击成功。
存储型 XSS 网络攻击
原理:存储型XSS和反射型XSS的差别仅在于提交的代码会存储在服务器端(数据库、内存、文件系统等),下次请求目标页面时不用再提交XSS代码。最典型的例子就是留言板 XSS,用户提交一条包含XSS代码的留言存储到数据库,目标用户查看留言板时,那些留言就会从数据库中加载出来并显示,于是触发了XSS攻击。
攻击方式:这种攻击多见于论坛、博客和留言板中,攻击者在发帖的过程中,将恶意脚本连同正常的信息一起注入帖子的内容中。随着帖子被服务器存储下来,恶意脚本也永久的存放在服务器的后端存储器中。当其他用户浏览这个被注入了恶意脚本的帖子时,恶意脚本会在它们的浏览器中得到执行。
DOM型 XSS 网络攻击
原理:文档对象模型Document Object Model(DOM)是一个与平台、编程语言不相干的接口,允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果会成为展示页面的一部分
DOM型xss其实是一种特殊类型的反射型xss,也被称作本地跨站,它是基于DOM文档对象模型的一种漏洞。DOM XSS和反射型XSS、存储型XSS的区别在于DOM XSS代码并不需要服务器参与,出发XSS靠的是浏览器的DOM解析,完全是客户端的事情
DOM中有很多对象,其中一些对象可以被用户所操纵,如url,location等。客户端的脚本程序可以通过DOM来动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而是从客户端取得DOM中的数据后并在本地执行,因此仅从服务器端是没有办法防御DOM型XSS漏洞的,如若DOM中的数据没有经过严格的验证,便会产生基于DOM的XSS漏洞。
基于DOM的XSS是反射的特例,其中JavaScript隐藏在URL中,并在其呈现时由页面中的JavaScript取出,而不是在提供服务时嵌入到页面中。这可以使其比其他攻击更隐蔽,并且监控页面正文的WAF或其他防护检测不出恶意内容。
攻击方式:用户请求一个经过专门设计的URL,它由攻击者提交,而且其中包含xss代码。服务器的响应不会以任何的形式包含攻击者的脚本,当用户的浏览器处理这个响应时,DOM对象就会处理xss代码,导致存在 xss 漏洞
防御手段
输入验证与过滤
- 对用户输入进行严格验证:确保用户输入的数据符合预期的格式和类型(如邮箱、电话号码等)。
- 过滤特殊字符:对用户输入中的特殊字符(如
<,>,",',&,/等)进行过滤或转义,防止其被解释为HTML或JavaScript代码。
输出编码
对动态内容进行编码:在将用户输入的数据插入到HTML、JavaScript或URL中时,使用适当的编码函数。
- HTML 编码:将特殊字符转换为HTML实体(如
<转为<)。 - JavaScript 编码:将特殊字符转换为Unicode转义序列(如
<转为\u003c)。 - URL 编码:对URL参数进行编码(如
&转为%26)。
使用安全的框架和库
- 选择安全性高的框架:现代前端框架(如 React、Vue、Angular)通常内置了XSS防护机制。例如,React 会自动对动态内容进行转义。
- 使用安全的库:例如 DOMPurify 或 sanitize-html 来清理HTML内容。
内容安全策略(CSP)
-
启用 CSP:通过设置HTTP头
Content-Security-Policy,限制浏览器加载和执行外部脚本的权限。- 示例:
Content-Security-Policy: default-src 'self'; script-src 'self';表示只允许加载同源的脚本。
- 示例:
-
禁用内联脚本和事件处理器:通过
unsafe-inline和unsafe-eval的限制,防止恶意代码通过内联脚本或eval()执行。
避免直接操作 DOM
- 使用安全的API:避免直接使用
innerHTML、document.write()等容易引入XSS的API。改用textContent或innerText。 - 动态创建元素时进行编码:在动态创建DOM元素时,确保对属性值和内容进行编码。
Cookie 安全
- 设置
HttpOnly标志:防止JavaScript通过document.cookie访问敏感Cookie。 - 设置
Secure标志:确保Cookie仅通过HTTPS传输。 - 设置
SameSite属性:防止跨站请求伪造(CSRF)攻击。
服务器端配合
-
双重验证:前端防御只是第一道防线,服务器端也应进行严格的输入验证和输出编码。
-
使用安全头:除了CSP,还可以设置
X-XSS-Protection和X-Content-Type-Options等HTTP头增强安全性。
参考网站: