XSS攻击常识与防御XSS攻击

探讨XSS攻击原理及分类,介绍通过转义字符与CSP策略防范XSS攻击的方法,强调CSP白名单制度的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

XSS

什么是XSS攻击?如何防范XSS攻击? 什么是CSP?

跨站脚本攻击 XSS 是最常见、危害最大的网页安全漏洞。

跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意的Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

XSS 简单点来说,就是攻击者想尽一切办法将可以执行的代码嵌入网页中。

XSS 可以分为多各类,但是总体上我认为分为两类:持久型和非持久型

持久型也就是攻击的代码被服务端写进数据库中,这种攻击危害性很大,因为如果网站的访问量很大的话,就会导致大量正常访问页面的用户都受到攻击。

举个例子,对于有输入文本的一些输入框如:反馈功能来说,就得防范持久型XSS攻击,因为我可以在评论中输入一些js代码
在这里插入图片描述
这种情况如果前后端没有做好防御的话,这段反馈就会存储到数据库中,这样每个打开该页面的用户都会被攻击到。

非持久型相比于前者危害就小的多了,一般都是通过修改URL参数的方式加入攻击代码,诱导用户访问链接从而进行攻击。

举个例子,如果页面需要从URL中获取某些参数作为内容的话,不经过过滤就会导致攻击代码被执行

<!-- http://www.xxx.com?id=<script>alert(123)</script> -->
<div>{{id}}</div>

但是对于这种攻击方式来说,如果用户使用的是Chorme这类浏览器的话,浏览器就能自动帮助用户防御攻击。但是我们不能因此就不防御攻击了,因为我们不能确定用户都使用了这类浏览器
在这里插入图片描述
对于XSS攻击,通常有两种方法可以用来防御。

第一种: 转义字符

首先,对于用户的输入应该是永远不信任的。最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义

function convert(str) {
    str = str.replace(/&/g, '&amp;')
    str = str.replace(/</g, '&lt;')
    str = str.replace(/>/g, '&gt;')
    str = str.replace(/"/g, '&quto;')
    str = str.replace(/'/g, '&#39;')
    str = str.replace(/`/g, '&#96;')
    str = str.replace(/\//g, '&#x2F;')
    return str
}

// 通过转义可以将攻击代码 <script>alert(123)</script>
// -> &lt;script&gt;alert(123)&lt;&#x2F;script&gt;
convert('<script>alert(123)</script>')
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert(123)</script>'// -> <h1 id="title">XSS Demo</h1>&lt;script&gt;alert(123)&lt;/script&gt;

以上示例使用了js-xss来实现,可以看到在输出中保留了h1标签且过滤了script标签。

但是对于显示富文本来说,显然不能通过上面的办法来转义所有的字符,因为这样会把需要的格式也过滤掉。对于这种情况,通常采用白名单过滤的办法(CSP),考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单方式。

第二种:CSP

为了防止XSS攻击,要采取很多编程措施,非常麻烦。很多人提出,能不能根本上解决问题,浏览器自动禁止外部注入恶意脚本?

这就是"网页安全政策"(Content Security Policy,缩写 CSP)的来历。本文详细介绍如何使用 CSP 防止 XSS 攻击。

CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。我们可以通过这种方式来尽量减少XSS攻击。

通常可以通过两种方式来开启CSP:

1.设置HTTP响应头信息的 Content-Security-Policy 的字段

在这里插入图片描述

2.设置标签。

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">

CSP语法

每一条策略都是指令与指令值组成,策略与策略之间用分号隔开,这是在HTTP响应头的写法
Content-Security-Policy:指令1 指令值1;指令2 指令值2;指令3 指令值3

这是meta标签写法,指令与指令值写在content里面

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">

CSP指令

指令说明
default-src :定义针对 JavaScript 的加载策略。定义针对所有类型指令设置默认值
script-src :定义针对 JavaScript 的加载策略。
style-src :定义针对样式表的加载策略。
img-src :定义针对图片的加载策略。
font-src :定义针对字体的加载策略。
media-src :定义针对多媒体的加载策略,例如:音频标签和视频标签。
object-src :定义针对插件的加载策略,例如:、、。
child-src :定义针对框架的加载策略,例如: ,。
connect-src :定义针对 Ajax/WebSocket 等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为400的响应。
sandbox :定义针对 sandbox 的限制,相当于 的sandbox属性。
report-uri :告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。
form-action :定义针对提交的 form 到特定来源的加载策略。
referrer :定义针对 referrer 的加载策略。
reflected-xss :定义针对 XSS 过滤器使用策略。

CSP指令值

指令值说明
*允许加载任何内容
‘none‘不允许加载任何内容
‘self‘允许加载相同源的内容
www.a.com允许加载指定域名的资源
*.a.com允许加载 a.com 任何子域名的资源
https://a.com允许加载 a.com 的 https 资源
https:允许加载 https 资源
data:允许加载 data: 协议,例如:base64编码的图片

script-src 的特殊值

指令值说明
‘unsafe-inline‘允许执行页面内嵌的<script>标签和事件监听函数,例如style属性、onclick、inline js、inline css等
‘unsafe-eval‘允许将字符串当作代码执行,比如使用eval、setTimeout、setInterval和Function等函数。
nonce每次HTTP回应给出一个授权token,页面内嵌脚本必须有这个token,才会执行。
hash列出允许执行的脚本代码的Hash值,页面内嵌脚本的哈希值只有吻合的情况下,才能执行。

nonce值的例子如下,服务器发送网页的时候,告诉浏览器一个随机生成的token。
Content-Security-Policy: script-src 'nonce-adgd897835uiehfg78e6'

页面内嵌js,必须有这个token才能执行。
<script nonce='adgd897835uiehfg78e6'> // js </script>

hash值的例子如下,服务器给出一个允许执行的代码的hash值。
Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

下面的代码就会允许执行,因为hash值相符。
<script>alert('Hello, world.');</script>

注意,计算hash值的时候,<script>标签不算在内。

除了script-src选项,nonce值和hash值还可以用在style-src选项,控制页面内嵌的样式表。


<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; child-src https:; img-src https:">

Content-Security-Policy: script-src 'self'; object-src 'none';
style-src cdn.example.org third-party.org; child-src https:

上面代码中,CSP 做了如下配置:

script-src: 'self'; // 只允许加载本站资源
object-src 'none'; // 不信任任何URL,即不加载任何资源
child-src https: // 必须使用HTTPS协议加载
img-src https://* // 只允许加载HTTPS图片

注意:

  1. script-src和object-src是必设的,除非设置了default-src。因为攻击者只要能注入脚本,其他限制都可以规避。而object-src必设是因为 Flash 里面可以执行外部脚本。
  2. script-src不能使用unsafe-inline关键字(除非伴随一个nonce值),也不能允许设置data:URL。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值