Web 安全之 XSS 攻击

简介: Web 安全之 XSS 攻击

XSS 攻击中文为跨站脚本攻击,全拼为 Cross-Site Scripting,其缩写本应为 CSS,但这个名称已经被作为 Cascading Style Sheets(层叠样式表) 的缩写,为了避免冲突,就将 Cross(交叉) 缩写成了看起来像一个交叉形状的字母 X。

攻击原理

XSS 攻击是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。攻击成功后,攻击者可能得到更高的权限,如窃取网站个人主页信息、Cookie 信息等。

攻击分类

根据攻击来源的不同,XSS 攻击一般可以分为三类:存储型、反射型(非持久型) 和 DOM 型。

  • 存储型攻击步骤:
  1. 攻击者将恶意代码通过表单等方式提交至目标网站数据库中。
  2. 用户访问目标网站,目标网站后端程序从数据库中提取出恶意代码并返回给浏览器。
  3. 浏览器解析并渲染响应结果的过程中执行了恶意代码。
  4. 恶意代码此时便可以执行窃取用户数据等非法操作。
  • 反射型攻击步骤:
  1. 攻击者将恶意代码嵌入至 URL 中并诱导用户点击。
  2. 用户点击恶意 URL,目标网站后端程序从 URL 中提取出恶意代码并返回给浏览器。
  3. 浏览器解析并渲染响应结果的过程中执行了恶意代码。
  4. 恶意代码此时便可以执行窃取用户数据等非法操作。
  • DOM 型攻击步骤:
  1. 攻击者将恶意代码嵌入至 URL 中并诱导用户点击。
  2. 用户点击恶意 URL,目标网站前端程序从 URL 中提取出恶意代码。
  3. 浏览器在渲染过程中执行了恶意代码。
  4. 恶意代码此时便可以执行窃取用户数据等非法操作。

存储型攻击和反射型攻击恶意代码都是经由目标网站后端程序返回,存储型攻击恶意代码被存储到了数据库中,反射型攻击恶意代码通常存在于 URL 中,因此也称作非持久型攻击。

DOM 型攻击恶意代码通常也存在于 URL 中,与存储型攻击和反射型攻击区别在于恶意代码不经过后端程序,完全由浏览器端触发。

可以发现 XSS 攻击的本质就是浏览器执行了非法的恶意代码,从而出现用户信息被窃取等非法操作。

攻击示例

这里我用 Flask 编写一个简单的 Web 应用来作为反射型 XSS 攻击的示例。执行以下代码之前你需要使用 pip install flask 的方式安装 Flask

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import Flask, request, make_response
app = Flask(__name__)
@app.route('/hello')
defhello():
    name = request.args.get('name')
    response = make_response(f'<h1>Hello {name}!</h1>')
    response.set_cookie('csrftoken', '0yz8xHMCQEfUwuUBIfiOmrre1XV2GyFAYgwdscY4XxpK9BLBuT34nSP1wFhK3GFD')
return response
if __name__ == '__main__':
    app.run()

这个 Web 应用中只包含一个 hello 视图函数,它返回一个简单的欢迎页面,并设置了一条 Cookie 信息到用户浏览器中。

启动 Flask 应用,使用浏览器访问 http://127.0.0.1:5000/hello?name=xiaoming 即可看到 Hello xiaoming!

目前来看,我们的 Web 程序似乎能够正常工作,接下来我将演示如何通过传入恶意代码来实现 XSS 攻击。

这次我们使用浏览器访问 http://127.0.0.1:5000/hello?name=<script>alert(document.cookie);</script> 就可以通过 XSS 攻击的方式获取到用户浏览器中的 Cookie 信息。

既然 alert 可以执行,并且成功获取到了 Cookie 信息,那么就意味着任意 JavaScript 代码都可以被执行,这是相当危险的。比如通过 AJAX 请求将获取到的 Cookie 信息发送至攻击者的服务器,此时攻击者就可以使用窃取到的用户 Cookie 信息来做一些非法操作。

由于几种不同类型 XSS 攻击的本质是一样的,所以其他类型 XSS 攻击不再进行演示,读者可以自行尝试。

防范方法

防范 XSS 攻击最主要的手段就是在前端渲染 HTML 之前对将要渲染的内容进行转义操作。转义后的内容在浏览器中将会被看作文本,而不是可执行的代码。

修改 hello 视图函数,不再通过拼接字符串的形式构造响应内容,而是使用 Jinja2 模板对内容进行渲染。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import Flask, request, make_response, render_template
app = Flask(__name__)
@app.route('/hello')
defhello():
    name = request.args.get('name')
    response = make_response(render_template('index.html', name=name))
    response.set_cookie('csrftoken', '0yz8xHMCQEfUwuUBIfiOmrre1XV2GyFAYgwdscY4XxpK9BLBuT34nSP1wFhK3GFD')
return response
if __name__ == '__main__':
    app.run()

index.html 模板内容如下:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<metacharset="UTF-8">
<title>Hello</title>
</head>
<body>
<h1>Hello {{ name }}!</h1>
</body>
</html>

再次使用浏览器访问 http://127.0.0.1:5000/hello?name=<script>alert(document.cookie);</script> 将不会看到 alert 弹框。

此时查看网页源码将会看到 <script>alert(document.cookie);</script>Jinja2 模板转义成了 &lt;script&gt;alert(document.cookie);&lt;/script&gt;

可以发现 <script> 标签中的 < 被转义成了 &lt;> 被转义成了 &gt;。这样,浏览器就不会把用户输入的内容作为代码进行解析了,而是当作普通文本进行渲染,从而避免了 XSS 攻击。

但是转义并不能完全过滤 XSS 攻击。将以上演示代码再次进行修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from flask import Flask, request, make_response, render_template
app = Flask(__name__)
@app.route('/hello')
defhello():
    name = request.args.get('name')
    url = 'javascript:alert(document.cookie)'# 假如这是一个用户提交的 URL
    response = make_response(render_template('index.html', name=name, url=url))
    response.set_cookie('csrftoken', '0yz8xHMCQEfUwuUBIfiOmrre1XV2GyFAYgwdscY4XxpK9BLBuT34nSP1wFhK3GFD')
return response
if __name__ == '__main__':
    app.run()
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<metacharset="UTF-8">
<title>Hello</title>
</head>
<body>
<h1>Hello {{ name }}!</h1>
<ahref="{{ url }}">这是一个用户提交的 URL</a>
</body>
</html>

index.html 中添加了一个 a 标签作为跳转链接,假设 javascript:alert(document.cookie) 是用户提交的非法 URL,如果我们仅仅是对内容进行转义,则无法过滤此 XSS 攻击。当用户点击页面中的 a 标签时依然会看到 alert 弹框。

所以针对 a 标签的 href 属性,我们还要做特殊处理,判断 URL 是否以 javascript: 开头,过滤掉非法 URL

虽然 XSS 攻击常见类型只有三种,但可以被攻击的漏洞却非常多。如 HTML 中的内嵌文本、a标签的 href 属性、img 标签的 src 属性、标签的 onclick 等内联事件。一切渲染用户输入数据的地方都有可能存在漏洞,所以开发人员一定要对用户输入的文本进行合适的过滤操作。

不要试图在前端页面用户提交数据的地方对内容进行过滤,因为攻击者可能不通过前端页面进行数据提交。所以要在浏览器渲染代码之前对内容进行过滤。

如果你对 Jinja2 比较熟悉,可能用过 safe 过滤器,当你了解了 XSS 攻击以后请一定要慎用,确保数据源安全的情况下才可以将不转义的内容原样返回给浏览器。对于 Vuev-htmlReactdangerouslySetInnerHTML 功能同理。

当然,所谓安全都是相对的,并没有绝对的安全,对于 XSS 攻击的防范,开发者应该保持警惕,做到尽量降低安全风险。

相关文章
|
24天前
|
JavaScript 安全 前端开发
同源策略如何防止 XSS 攻击?
【10月更文挑战第31天】同源策略通过对 DOM 访问、Cookie 访问、脚本执行环境和跨源网络请求等多方面的严格限制,构建了一道坚实的安全防线,有效地防止了 XSS 攻击,保护了用户在网络浏览过程中的数据安全和隐私。
89 49
|
18天前
|
Web App开发 网络协议 安全
基于Web攻击的方式发现并攻击物联网设备介绍
基于Web攻击的方式发现并攻击物联网设备介绍
|
27天前
|
SQL 负载均衡 安全
安全至上:Web应用防火墙技术深度剖析与实战
【10月更文挑战第29天】在数字化时代,Web应用防火墙(WAF)成为保护Web应用免受攻击的关键技术。本文深入解析WAF的工作原理和核心组件,如Envoy和Coraza,并提供实战指南,涵盖动态加载规则、集成威胁情报、高可用性配置等内容,帮助开发者和安全专家构建更安全的Web环境。
48 1
|
29天前
|
安全 前端开发 Java
Web安全进阶:XSS与CSRF攻击防御策略深度解析
【10月更文挑战第26天】Web安全是现代软件开发的重要领域,本文深入探讨了XSS和CSRF两种常见攻击的原理及防御策略。针对XSS,介绍了输入验证与转义、使用CSP、WAF、HTTP-only Cookie和代码审查等方法。对于CSRF,提出了启用CSRF保护、设置CSRF Token、使用HTTPS、二次验证和用户教育等措施。通过这些策略,开发者可以构建更安全的Web应用。
72 4
|
28天前
|
安全 Go PHP
Web安全进阶:XSS与CSRF攻击防御策略深度解析
【10月更文挑战第27天】本文深入解析了Web安全中的XSS和CSRF攻击防御策略。针对XSS,介绍了输入验证与净化、内容安全策略(CSP)和HTTP头部安全配置;针对CSRF,提出了使用CSRF令牌、验证HTTP请求头、限制同源策略和双重提交Cookie等方法,帮助开发者有效保护网站和用户数据安全。
60 2
|
24天前
|
SQL 存储 安全
什么是XSS攻击?什么是SQL注入攻击?什么是CSRF攻击?
理解并防范XSS、SQL注入和CSRF攻击是Web应用安全的基础。通过采用严格的输入验证、使用安全编码实践以及实现适当的身份验证和授权机制,可以有效防止这些常见的Web攻击,保障应用程序和用户的数据安全。
29 0
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
126 3
|
28天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
139 45
|
10天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
25 2
|
24天前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
40 1