XSS总结

发布于:2025-07-22 ⋅ 阅读:(14) ⋅ 点赞:(0)

声明:本文属于自己学习的掌握程度,有些地方可能理解的不对,需要具体查看内容还请看官方文档!!!

XSS也叫:跨站脚本攻击;

就是在前端页面里提交恶意的javascript代码,当访问改页面时,就会执行插入的恶意javascript代码,存在这个漏洞的主要原因还是对用户提交的数据过滤不严格,导致恶意代码插入。

分类:

  1. 反射型xss  :对用户的输入没做限制,所以用户可以输入恶意JS代码,最终被解析 影响最小
  2. DOM型xss :在js中插入东西,在js中控制
  3. 存储型xss  :有一个form表单存到数据库了   影响最大

另外还有一个和xss类似的漏洞叫原型链污染,它们产生的原因都是未对用户的输入进行过滤导致的

一.反射型XSS

反射型XSS是恶意脚本作为请求的一部分发送到服务器,服务器将恶意脚本"反射"回响应中并在浏览器执行

这个漏洞的基础在于知道 URLcode编码、 html实体编码7、js的unicode编码,要会利用转编码,看懂过滤部分的内容,javascript语言严格遵守大小写,有的时候可能·会隐藏输入控件,在页面里就找不到提交数据的地方

就像这样:

总结:

1.反射型xss的存在位置 可能在搜索 input表单

2.可能会存在过滤。通过编码等方式尝试绕过

3.javascript伪协议 也可以触发xss 例如:<div>欢迎, <a href="javascript:alert('XSS')">Bob</a>!</div>

二.DOM型XSS

这里介绍一个辅助的攻击手段:DOM 破坏

        它是一种 独立的攻击技术,但常被用于增强 XSS 攻击效果。它是一种客户端安全漏洞,攻击者通过操纵DOM结构来干扰或覆盖JavaScript代码中的变量和函数,从而改变网页的正常行为。

        而DOM型XSS是在用户输入的URL里写入恶意js代码 它通过修改页面的DOM结构来触发的XSS攻击,恶意代码不经过服务器处理,直接在客户端执行。(哈希是#,get是?)

这里有几个知识点:

1,<div>&#60;img src=x onerror=alert(4)&#62;</div>  中img未被解析的原因:

        HTML字符实体编码 < 和 >

        当写一个标签时:

        < :进入了标签开始状态(Tag open state) ,并且快速进入标签名状态(Tag name state)

        <标签名字> :然后就进入前属性名状态…最后进入数据状态(Date state)并且释放当前标签的token,他会继续解析,每当发现一个完整标签,就会释放一个token;在这个状态中,有三种情况可以容纳html实体编码,1️⃣数据状态中的字符引用,2️⃣RCDATA状态中的字符引用,3️⃣属性值状态中的字符引用,这些状态中的html字符实体会从"&#.."形式解码,对应的解码字符会被放在数据缓冲区。

    例如本例题,它执行完<div>后进入了数据状态,然后遇到了<,解码为&#60;,但是,它不会转换到标签开始状态,所以不会建立新的标签。

    所以我们可以利用字符实体编码这个行为确保输入的数据只能被解析成数据

2.解码的顺序:1️⃣html实体编码--->2️⃣urlencode编码--->3️⃣ js unicode编码

3.HTML中的五类元素:

  1. 空元素(Void elements),如<area>, ,<base><br><img><hr><link><meta>

空元素,不能容纳任何内容(因为它们没有闭合标签,没有内容能够放在开始标签和闭合标签中间)。 不用考虑没内容,利用不了

 

  1. 原始文本元素(Raw text elements)<script><style>

原始文本元素,可以容纳文本,但不解析HTML标签(内容里的<>不会被当标签,直接当文本)。只能把里面的内容当做文本,利用不了

 

  1. RCDATA元素(RCDATA elements)<textarea><title> 上面小知识有

RCDATA元素,可以容纳文本和字符引用。(如 &lt; 转 <、&amp; 转 &)但不解析 HTML 标签(内容里的<、>不会触发新标签解析)。所以一旦有字符引用可能就无法进入标签开始状态,大概率利用不了

 

  1. 外部元素(Foreign elements),例如MathML命名空间或者SVG命名空间的元素<svg>MathML

外部元素,可以容纳文本、字符引用、CDATA段、其他元素和注释      svg 可以

 

  1. 基本元素(Normal elements),即除了以上4种元素以外的元素<div><p><a><span><h1>等)

基本元素,可以容纳文本、字符引用、其他元素和注释  可以触发

4.RCDATA(解析字符数据,Raw Character Data 

是 HTML 解析器中的一种特殊状态,用于处理特定标签内的文本内容。在 RCDATA 状态下,解析器对标签语法的解析更为宽松,但仍会处理字符实体(如 &lt; 转为 <)。

核心特点

  1. 允许未转义的 <
    与普通文本(数据状态)不同,RCDATA 状态允许直接包含 < 字符,而不会将其解析为新标签的开始。
  2. 处理字符实体
    会将 &lt;&amp; 等实体编码转换为对应字符,但不处理标签语法。
  3. 仅适用于特定标签
    仅以下 HTML 标签使用 RCDATA 解析模式:
    • <title>
    • <textarea>
    • <style>HTML5 中为 CDATA,但历史上曾为 RCDATA
    • <xmp>(已废弃)
    • <iframe><noembed><noframes>(部分浏览器实现)

然后这里就讲了差不多这些吧

三、存储型xss(这块理解的不好)

这个就是恶意脚本被永久存储在服务器(如数据库、文件、缓存等)中,并在其他用户访问相关页面时被服务器 “主动” 返回并执行,攻击影响范围广且具有持久性。

然后这个分两步,

        1️⃣,注入:攻击者通过输入框(如留言、评论、个人简介)提交包含恶意脚本的内容,服务器未过滤或编码就将其存入数据库。

        2️⃣,触发:其他用户访问包含该内容的页面时,服务器从数据库读取恶意脚本并返回给浏览器,浏览器误将其当作正常代码执行。

这个需要用到bp工具

四、原型列污染

要学会这个,你得有一定的javascript功底,你得了解对象与类,

原型链:JavaScript 规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain):对象到原型,再到原型的原型……

原型链污染: `foo.__proto__` 指向的是 `Foo`类的`prototype` 。那么,修改了 `foo.__proto__` 中的值,就可以修改Foo类。

所以攻击者控制并修改了一个对象的原型,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。这种攻击方式就是  原型链污染

原型链污染的目的 是RCE 执行系统命令


小知识:

     类是抽象的,比如学生,你无法知道这个学生具体是谁,当我们给类加上一些属性,比如名字,性别1,身份证等,我们就知道他具体是谁了,也就是对象。然后对象是一个具体的事物,所以我们需要一个模板,用来表示一类相似事物的特征,根据这个模板我们生成对象。所以说,类"就是对象的模板,对象就是“类"的实例。

            但是,JavaScript 语言的对象体系,不是基于“类”的,而是基于构造函数(constructor)和原型链(prototype)。,javaScript 语言使用构造函数(constructor)作为对象的模板。所谓"构造函数",就是专门用来生成实例对象的函数。它就是对象的模板,描述实例对象的基本结构。一个构造函数,可以生成多个实例对象,这些实例对象都有相同的结构。

构造函数的特点有两个:

- 函数体内部使用了`this`关键字,代表了所要生成的对象实例。

- 生成对象的时候,必须使用`new`命令。

-  构造函数名字的第一个字母通常大写

        大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承。

prototype       __proto__

        prototype`是一个类的属性,所有类对象在实例化的时候将会拥有`prototype`中的属性和方法,(父亲里面可以构造方法,但是每当他有一个儿子,就要调用一次这个函数,所以就使用prototype属性,有了它,就可以解决每次调用构造函数了)

      但是   父.prototype   可以访问  父亲,但不能访问他的儿子们,这时候,就该使用    __proto__   属性,让儿子访问父亲,

儿子.__proto__ == 父亲.prototype

但这样写有一个问题,就是每当我们新建一个Foo对象时,`this.show = function...`就会执行一次,这个`show`方法实际上是绑定在对象上的,而不是绑定在“类”中。

我希望在创建类的时候只创建一次`show`方法,这时候就则需要使用原型(prototype)了

总结:

1. 每个构造函数(constructor)都有一个原型对象(prototype)

2. 对象的`__proto__`属性,指向类的原型对象`prototype`

3. JavaScript使用prototype链实现继承机制

HTML实体编码

        即HTML中的转义字符。

命名实体:以&开头,以;结尾,如&lt;表示<。

数字实体:以&#开头,后跟字符的 Unicode 码点(十进制或十六进制),以;结尾。

十进制:如&#60;表示<。

十六进制:如&#x3C;表示<(x表示十六进制)

编码

urlcode编码:(ASCII码转16进制加%)

        urlcode 是一种编码方式,就是把http请求串的url 进行urlcode的编码,让httpserver 可以识别,不至于http的client、server 之前出现乱码或者误解。

utf-8编码:这里的关系是,UTF-8 是 Unicode 的实现方式之一。

       UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

js unicode编码在 JavaScript 中,Unicode 编码的处理涉及将字符转换为其对应的 Unicode 代码点表示,以及反向操作(将代码点转回字符)。以下是几种常见的处理方式:1. 获取字符的 Unicode 代码点2.  Unicode 代码点转换为字符3. Unicode 转义序列4. 处理辅助平面字符(Surrogate Pairs)5. 编码为 Unicode 转义字符串6. 解码 Unicode 转义字符串

     URL 解码(URL Decode

        是将经过 URL 编码(URL Encode)处理的字符串还原为原始内容的过程。

     在 URL 编码中,特殊字符、非 ASCII 字符会被转换为 % 后跟两位十六进制数的形式(例如 %20 代表空格),而 URL 解码则是将这些编码还原为原始字符。



网站公告

今日签到

点亮在社区的每一天
去签到