地址

Web安全-XSS

XSS攻击方式

反射型

发出请求时,XSS代码(一般是JS代码)出现在URL中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,故叫反射型XSS。

简单来说就是:

  • 服务端解析了URL中的XSS代码
  • 之后服务端把XSS代码和HTML代码一起下发给浏览器
  • 最后浏览器解析执行XSS代码。

示例:

1
2
3
4
5
6
7
8
# urls.py
url(r'^$',views.index,name='index'),

# views.py
def index(request):
xss = request.GET.get('xss')
context = {'xss':xss}
return render(request,'index.html',context)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- index.html -->
<!DOCTYPE html>
<html lang='cn'>
<head>
<meta charset="UTF-8">
<title>XSS</title>
</head>

<body>
<h1>Index</h1>
<!-- 重点 -->
{{ xss | safe }}

</body>
</html>

url为:

1
localhost:3000/?xss=<img scr='null' onerror="alert(1)">
  1. 后台从url中获取了xss代码
  2. 解析xss代码,并且连同HTML返回

存储型

存储型XSS和反射型XSS的差别仅在于,提交的代码会存储在服务器端(数据库,内存,文件系统等),下次请求目标页面时不用再提交XSS代码

  • 简单来说反射型存储在URL中

  • 存储型需要存储

所以造成的区别就是:

1
2
3
4
5
6
# views.py
def index(request):
# 从数据库中获取XSS代码
xss = Model.object.get(...)
context = {'xss':xss}
return render(request,'index.html',context)

XSS防范措施

编码

对用户输入的数据进行HTML Entity编码

下面截取部分HTML Entity编码

Character Entity Name
&nbsp;
! &excl;
&quot;
# &num;
$ &dollar;
% &percnt;
& &amp;
&apos;

过滤

将不安全的东西过滤掉

  • 移除用户上传的DOM属性,如 onerror等(基本和事件相关的属性都要过滤掉)
  • 移除用户上传的Style节点、Script节点、iframe节点等

校正

  • 避免直接对 HTML Entity解码
  • 使用 DOM Parse转换,校正不配对的DOM标签

XSS实战

使用评论功能演示

构造接口

掌握XSS的防范措施(反转义、 DOM Parse)

掌握XSS的防范措施(过滤 、校正)