前端安全:CSRF、XSS该怎么防御?

article/2025/11/8 16:26:10

近几年随着业务的不断发展,前端随之面临很多安全挑战。我们在日常开发中也需要不断预防和修复安全漏洞。接下来,梳理一些场景的前端安全问题和对应的解决方案。

XSS攻击介绍

XSS是后端的责任,后端应该在用户提交数据的接口对隐私敏感的数据进行转义。

NO,这种说法不对

所有插到页面的数据,都要进行过滤转移,当没有敏感字符的时候,就可以直接插到页面上显示了。

NO,丝毫没有什么作用

XSS攻击是页面被注入了恶意的代码,利用恶意脚本,攻击者可以获取用户的Cookie、SessionID等敏感信息。

XSS注入的方法:

  • 在HTML中内嵌的文本中,恶意内容通过script标签注入
  • 在内联的JS中,拼接的数据突破了原本的限制
  • 在标签属性中,恶意内容包含引导,从而突破属性值的限制
  • 在标签href、src等属性中,包含javascript:可执行代码
  • 在onload、onerror、onclick事件中,注入不受控制的代码
  • 在style属性中,类似background- image: url("javascript:..")代码

如果开发者没有将用户输入的文本进行合适的过滤,直接插入到HTML中,很容易造成注入漏洞。

XSS攻击的分类

存储型XSS

其攻击步骤如下:

  1. 攻击者将恶意代码提交到目标网站的数据库
  2. 用户打开目标网站,服务端将恶意代码取出,拼在HTML中返回给浏览器
  3. 用户浏览器解析执行,混在HTML中的恶意代码也被执行
  4. 恶意代码窃取用户数据,冒充用户,执行攻击者制定的操作

常见场景:论坛发帖、商品评论、私信

反射型XSS

其攻击步骤如下:

  1. 攻击者构造特殊URL,其中包含恶意代码
  2. 用户点击打开该URL,服务端将恶意代码从URL中取出,拼接在HTML中返回给浏览器
  3. 浏览器解析执行,混在HTML中的恶意代码也被执行
  4. 恶意代码窃取用户数据,冒充用户,执行攻击者制定的操作

看到这里,我们发现反射型XSS和存储型XSS的区别在于恶意代码的存储位置不同:

  • 反射性XSS:恶意代码存URL上
  • 存储型XSS:恶意代码存数据库里

所以反射性XSS攻击通常借助URL传递参数,如网站搜索、跳转等。

DOM型XSS

其攻击步骤如下:

  1. 攻击者构造特殊URL,其中包含恶意代码
  2. 用户点击打开带有恶意代码的URL
  3. 用户浏览器解析执行,前端JS取出URL中恶意代码并执行
  4. 恶意代码窃取用户数据,冒充用户,执行攻击者制定的操作

DOM型XSS和前两种的区别在于:取出和执行恶意代码都在浏览器端执行,属于JS自身的安全漏洞,而存储型XSS、反射型XSS都属于服务端的安全漏洞。

XSS攻击的防御

通过前面的介绍可以发现,XSS攻击两大因素:

  1. 攻击者提交恶意代码
  2. 浏览器执行了恶意代码

所以,我们可以在这两个方面进行防御。

我们要考虑是否能够在用户输入的过程中,过滤到恶意代码,然后提交到后端。

这条路是不可行的,一旦攻击者绕过前端过滤,就可以直接构造请求来提交恶意代码了。

如果我们将过滤的时机转移到:在后端写入数据库前,后端进行过过滤,只存储安全的内容,并返回给前端,这样能成功防御XSS吗?

在实际的开发中,我们并不确定内容要输出到哪里,用户输入的内容可能同时提供给前端和客户端,而一旦经过escapeHtml(),客户端显示的内容就会变成乱码。

所以,这样的方式会引入很大的不确定性和乱码问题,我们通常不这么做。

预防存储型和反射型XSS攻击

这两种攻击都发现在服务端取出恶意代码并拼接在HTML中,最终被浏览器执行,常见的预防方式:

  • 改成纯前端渲染,把代码和数据分离开
  • 对HTML做转义(采用适合的转义库)

预防DOM型XSS攻击

实际上是网站JS代码本身不够严谨,把不可信数据当作可执行代码。

所以我们在使用.innerHTMLouterHTML时要特别注意,不要把不可信数据作为HTML插入页面。

在vue和react中,也不建议使用v-htmldangerouslySetInnerHTML

检测XSS方法

  1. 使用CSS攻击字符串手动检测XSS漏洞
  2. 使用扫描工具检测(ecsypno)

在github小有个工具库:点击直达

在这里插入图片描述
我们将它copy 并拼接在URL参数上,就可以检测了:


jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e

虽然很难通过技术手段完全避免 XSS,但我们可以总结以下原则减少漏洞的产生:

  • 利用模板引擎
  • 避免内联事件
  • 避免拼接 HTML
  • 增加攻击难度,降低攻击后果
  • 主动检测和发现

CSRF攻击介绍

CSRF利用受害者的注册凭证,绕过后台验证,冒充用户执行某些操作。

典型的流程:

  1. 受害者登录a.com,并保留了登录cookie
  2. 攻击者诱导用户访问b.com
  3. b.com向a.com发送请求
  4. a.com收到请求后,校验通过,误以为是受害者自己发送的请求
  5. a.con以受害者名义执行某些操作
  6. 攻击完成,受害者浑然不知

常见的CSRF攻击类型

GET

<img src="http://bank.example/withdraw?amount=10000&for=hacker" > 

在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。

POST

通常CSRF利用一个自动提交的表单,相当于模拟用户完成一次POST操作。

CSRF的特点

  • 攻击一般发起在第三方网站,被攻击的网站无法防止攻击
  • 利用受害者的登录凭证,冒充受害者,而不是直接窃取数据
  • 整个过程不能获取到受害者的登录凭证,仅仅是冒用
  • 通常的方式:图片URL、超链接、CORS、From表单提交

CSRF通常是跨域的,所以我们可以专门制定防御策略,比如:

  • 组织不明外域的访问:同源检测、Samesite Cookie
  • 提交时加上本域才有的信息:CSRF Token、双重Cookie验证

同源检测

在HTTP中每个异步请求都会携带两个Header:Origin Header、Referer Header

服务器可以通过解析这两个Header中的域名,确定请求的来源域

CSRF Token

  1. 将CSRF Token输出到页面
  2. 页面提交的请求中携带这个Token
  3. 服务器验证Tojen是否正确

⚠️注意:Token随机生成,不会被攻击者才到

Samesite Cookie

Set-Cookie响应头新增Samesite属性,它用来标明这个 Cookie是个“同站 Cookie”,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie,Samesite 有两个属性值,分别是 Strict 和 Lax:

  1. Strict:严格模式,任何情况下都不能作为第三方Cookie
  2. Lax:宽松模式,Cookie可作为第三方Cookie

双重Cookie验证

比CSRF Token繁琐一些,而且不能在通用的拦截上统一处理所有的接口:

  1. 在用户访问网站时,向请求的域名注入一个cookie,内容为随机字符串
  2. 前端向后端发起请求时,取出cookie,并添加在URL参数中
  3. 后端接口验证cookie字段与URL参数中字段是否一致

它的好处在于无需使用Session,适用面广。且Token存在客户端,也不会给服务器造成压力。但这样Cookie中增加了额外的字段。如果有其他漏洞(如XSS),攻击者可以注入cookie,防御就会失效。

为了更好的防御CSRF,最佳实践就是结合上述的防御措施的优缺点来综合考虑。


http://chatgpt.dhexx.cn/article/jvKwLrBx.shtml

相关文章

如何解决Web前端安全问题?

我国网络技术水平的提升&#xff0c;带动着WEB前端业务量的显著增长&#xff0c;人们对于网络服务的需求也日益复杂&#xff0c;与此同时&#xff0c;越来越多的黑客出现&#xff0c;其攻击水平也有了明显提升&#xff0c;WEB前端也成为了众多黑客进行网络攻击的主要目标。 因…

前端安全问题的解决方法

目录 前言&#xff1a; 1.常见的安全性问题 2.XSS攻击的解释和解决方法 2.1 XSS攻击是什么&#xff1a; 2.2 经常出现的原因&#xff1a;用户输入&#xff0c;如input框 2.3 防御方式&#xff1a; 3.CSRF&#xff08;跨站请求伪造&#xff09;的解释和解决方法 3.1 是什么…

前端常见的安全问题

一、XSS &#xff08;Cross-Site Scripting&#xff09;跨站脚本攻击 通常指通过“HTML注入”篡改了网页&#xff0c;插入了恶意的脚本&#xff0c;从而在用户浏览网页时&#xff0c;获取用户信息、控制用户浏览器等的一种攻击 分类&#xff1a;持久性&#xff08;存储型xss&…

前端常见安全性问题

文章目录 一、常见的安全性问题二、XXS攻击&#xff08;Cross Site Scripting&#xff09;&#xff08;跨站脚本攻击&#xff09;三、CSRF安全漏洞&#xff08;跨站请求伪造&#xff09;四、文件上传漏洞五、限制URL访问&#xff0c;越权访问六、不安全的加密存储七、SQL注入攻…

前端WEB安全

一、浏览器安全 首先了解前端web安全知识&#xff0c;比不可绕开的基础就是同源策略了&#xff0c;同源策略&#xff08;Same Origin Policy&#xff09;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;如果缺少了同源策略&#xff0c;则浏览器的正常功…

前端安全问题以及解决方案汇总

随着大前端的快速发展&#xff0c;各种技术不断更新&#xff0c;前端的安全问题也值得我们重视。今天我们来聊一聊前端常见的7个安全方面问题&#xff1a; 1.iframe 2.opener 3.CSRF&#xff08;跨站请求伪造&#xff09; 4.XSS&#xff08;跨站脚本攻击&#xff09; 5.ClickJa…

浅谈前端安全

1 什么是前端安全&#xff1f; 所有发生在浏览器、单页面应用、Web页面当中的安全问题都算是算是“前端安全问题”。或者就是说所有需要前端开发人员去修复的问题都属于前端安全问题。 2 前端目前存在哪些安全问题 2.1 xss&#xff08;Cross Site Scripting&#xff09;跨站…

数据结构中头结点的作用

数据结构中&#xff0c;在单链表的开始结点之前附设一个类型相同的结点&#xff0c;称之为头结点。头结点的数据域可以不存储任何信息&#xff0c;头结点的指针域存储指向开始结点的指针&#xff08;即第一个元素结点的存储位置&#xff09;。 作用 1、防止单链表是空的而设的…

链表的首元结点、头结点、头指针的区别(图示)

1、首元结点&#xff1a;就是指链表中存储第一个数据元素a1的结点。 2、头结点&#xff1a;它是在首元结点之前附设的一个节点&#xff0c;其指针域指向首元结点。头结点的数据域可以不存储任何信息&#xff0c;也可以存储与数据元素类型的其他附加信息&#xff0c;例如&#…

单链表两种结构:头指针,头结点与首元结点辨析

要区分头指针&#xff0c;头结点&#xff0c;首元结点这几个概念分别指什么&#xff0c;需要结构图来帮助阐释。 我们先来看一种不太严谨的表现形式。 1->2->3->4->NULL 头结点这个名词很具有迷惑性。比如这张图中&#xff0c;刚接触的新手很容易以为1就是来自头…

【头指针,头结点、首元节点】

链表中第一个结点的存储位置叫做头指针&#xff0c;那么整个链表的存取就必须是从头指针开始进行了。之后的每一个结点&#xff0c;其实就是上一个的后继指针指向的位置。 这里有个地方要注意&#xff0c;就是对头指针概念的理解&#xff0c;这个很重要。“链表中第一个结点的存…

单链表:头指针 头结点 首元结点区别与联系

单链表组成&#xff1a;头指针头结点第一个结点第二个结点第三个结点.............第N个结点。 注意下图中&#xff1a;首元结点就是第一个结点。 头指针&#xff1a;作用&#xff1a;1.头指针的名字就是本链表的名字 2.头指针也是一个指针&#xff0c;存放头节点地址 头结…

链表:头结点

简介&#xff1a; 头结点的数据域可以不存储任何信息&#xff0c;头结点的指针域存储指向第一个结点的指针&#xff08;即第一个元素结点的存储位置&#xff09;。头结点的作用是使所有链表&#xff08;包括空表&#xff09;的头指针非空&#xff0c;并使对单链表的插入、删除操…

头指针和头结点

在了解头指针和头结点之前&#xff0c;先介绍数据域、指针域、结点和链表的定义&#xff1a; 数据域用来存储元素的数值数据 指针域存储直接后继节点的存储位置 结点是数据元素的存储映像。由数据域和指针域两部分组成 链表 n个结点由指针链组成一个链表。它是线性表的链式…

关于链表中头指针和头结点的理解

线性表使用顺序&#xff08;数组&#xff09;存储时有个弊端&#xff0c;那就是在插入和删除时需要大量的移动数据&#xff0c;这显示是非常消耗时间的&#xff0c;所以可以采用链式存储&#xff0c;即有一个指针域&#xff08;单链表&#xff09;&#xff0c;来记录下个结点的…

首元结点,头结点,头指针区别

https://www.cnblogs.com/letianpaiai/p/13227755.html 首元结点就是指链表中存储的第一个数据元素的结点&#xff0c;就是结点Li 头指针是指向链表中的第一个结点的指针&#xff0c;如果有头结点&#xff0c;那么头指针所指结点为头结点&#xff0c;否则为首元结点 头结点是…

头指针、头结点、首元结点概念区别

转自&#xff1a;https://blog.csdn.net/liangxingda/article/details/52755800 链表中第一个结点的存储位置叫做头指针&#xff0c;那么整个链表的存取就必须是从头指针开始进行了。之后的每一个结点&#xff0c;其实就是上一个的后继指针指向的位置。 这里有个地方要注意&a…

链表的头节点理解

不管带不带头节点&#xff0c;头指针始终指向第一个结点&#xff0c;头指针始终指向第一个结点&#xff0c;而头节点是带头结点的链表的第一个结点&#xff0c;结点内通常不存储信息。 图示如下&#xff1a; 2.在建立链表时&#xff0c;如果是不带头节点&#xff0c;第一个结…

头结点的作用

数据结构中&#xff0c;在单链表的开始结点之前附设一个类型相同的结点&#xff0c;称之为头结点。头结点的数据域可以不存储任何信息&#xff0c;头结点的指针域存储指向开始结点的指针&#xff08;即第一个元素结点的存储位置&#xff09;。 作用 1、防止单链表是空的而设的&…

头结点和头指针的区别

地址&#xff1a; 头指针和头结点的区别&#xff1a;头指针&#xff1a; 头结点&#xff1a; 地址&#xff1a; https://blog.csdn.net/u013593035/article/details/45953605?ops_request_misc%257B%2522request%255Fid%2522%253A%2522162688192816780255294435%2522%252C%…