网页攻击 和 跨域 的相关问题梳理

本文深入解析了XSS攻击(包括持久型与非持久型)和CSRF攻击的原理,探讨了浏览器同源策略、跨域限制,以及如何利用CORS进行AJAX跨域请求。重点讲解了预检请求、缓存策略和防御措施。

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

之前对 XSS攻击 和 CSRF攻击 了解地不透彻,导致有些原理似懂非懂。最近刚好查了一些资料,解开了心里的疑问,顺便在这记录一下。

一般常见的网页攻击方式有 XSS攻击 和 CSRF攻击,具体可以先了解一下:

疑问1:CSRF攻击 能获取到用户所在域的cookie吗?

我们知道,cookie用于存储用户登录成功后的会话等信息,那么 CSRF攻击者 在第三方网站伪造用户的请求,是如何获取到用户所在域的cookie呢?

首先,这种攻击方式是跨域的,所以攻击者在第三方网站是获取不到用户cookie的(浏览器的同源策略规定 不允许获取 跨域cookie、localStorage、sessionStorage等信息),但浏览器会为该请求自动携带上对应域的cookie

也就是说,攻击者并不需要获取到用户cookie,只需利用 浏览器的默认行为(即 cookie策略)即可实施攻击。

浏览器的 cookie 有两种类型,CSRF 利用的就是第 2种(浏览器cookie策略

  • Session Cookie
  • Third-party Cookie

需要注意的是:并非所有的浏览器都会自动带上第三方cookie,比如 IE6/7/8、Safari、chrome80 以上版本(参考文章),默认会拦截第三方cookie的。不同的浏览器厂商,各自的cookie策略也不一样。

如果想获取跨域cookie,单纯靠CSRF攻击是做不到的,但结合XSS就可以

需要注意一点:在防御CSRF攻击的方法中,服务器检查 referer 这种方法并不靠谱,因为有些浏览器可以改 referer,或者用 postman 这种工具,也可以随意设置 referer。

疑问2:三种 XSS攻击 到底如何理解?

持久型

  • 存储型-xss:恶意代码被保存到数据库,后续每次访问,服务器都会返回带有恶意代码的页面。

举个例子,博客文章编辑保存时,注入恶意代码。

非持久型

  • 反射型-xss:在 前端(输入框等交互元素)或者 url参数中 先注入恶意代码,然后向后端发起请求。后端拿到参数解析,并动态生成问题页面(后端必须是 类似php等动态网页语言 生成的页面。如果只是返回静态页面,后端无需解析,则无法注入恶意代码),接下来只要别人一访问该页面,后端就会返回 携带恶意代码的问题页面。

举个例子,假设访问某个商品详情页的url中,可能带有商品名字段,当后端拿到url(即动态路由)去生成动态页面的时候,会把该商品名字段渲染到页面中。那么我们只要把商品名字段的值改成恶意脚本,就可以注入到动态生成的页面中。当有用户访问同一个商品详情页时,就会执行我们的恶意脚本。

  • dom型-xss:一般只在url参数中 注入恶意脚本,然后将该url(比如伪造成美女图片或官网图片等)发给用户。用户点击恶意链接打开网页,在操作页面时被动执行了恶意代码。

举个例子,假如某网页存在操作DOM元素的交互动作,且该交互动作 会从url中取参数(比如订单编号之类的)进行渲染,那么就可以从url中注入恶意脚本,然后将url伪造成美女图片忽悠用户打开,当用户在该页面触发交互动作时,恶意代码就会随着渲染 被植入页面元素中,并被浏览器执行。

2种非持久型xss的区别

反射型-xss:由后端动态网页语言解析恶意代码(服务器重启可以清掉恶意代码)。

dom型-xss:由前端浏览器解析恶意代码(服务器重启没用)。

2种非持久型xss的相同点

二者都可通过伪造url实施攻击,通常是用来获取用户的cookies。

持久型与非持久型xss的区别

取决于 恶意代码 是否被存入到数据库。

 题外话

由于现在的开发模式 基本都是前后端分离,很多 非计算机专业 的同学,学的都是 纯前端技术(如 vue、react 等),在理解XSS攻击原理的时候,就会觉得似懂非懂,因为有些XSS攻击是需要结合 后端网页语言(如 php 等)实现的。

纯前端技术(如 vue、react 等)是提前把项目 打包成 静态资源(html / css / js 文件等),并放到服务器上;而后端网页语言(如 php 等)是根据 浏览器的 url 在服务器上动态生成 html 文件等资源,再返回给浏览器。也就是说,对用户而言是无感知的,用户只是输入url,然后服务器返回页面显示,但中间生成页面的过程是不一样的

 疑问3:浏览器的 同源策略 限制什么?不限制什么?

限制

  • Cookie、LocalStorage、sessionStorage和 IndexDB 只能读取同源的
  • DOM 节点只能读取和设置同源的
  • AJAX只能发起同源的请求

不限制

  • form表单提交跨域请求(无论 post 还是 get)
  • 页面中的跨域链接(如标签 <script> | <img> | <link>)、跨域资源引入(如标签 <iframe>)

为何form表单请求不限制,而AJAX请求限制呢?

 因为 同源策略 就是 限制你获取其他域的资源,而AJAX跨域请求之后,页面可以拿到AJAX返回的跨域数据,相当于绕过了同源策略,所以默认被限制了。当然,限制可以解开的(如CORS),疑问4中会具体说明。

form表单提交跨域请求 不被同源策略限制,是因为 form表单提交有个默认行为,当 submit 成功之后,页面会自动跳转到该请求的域名页面下,原来的页面就拿不到form请求返回的跨域数据,所以不被限制(其实也有办法拿到的)。

 疑问4:AJAX跨域请求 是 发出前 还是 返回后 被浏览器拦截?

网页的源与请求的源,只要 协议、IP地址、端口号 中有一个不同,即认为是跨域。在疑问3中咱们聊到,同源策略限制了AJAX的跨域请求,那么 AJAX跨域请求 到底可以实现么?

这就需要我们了解一个W3C标准:CORS参考《CORS详解 - 阮一峰》)。

CORS跨域资源共享,全称Cross-origin resource sharing,它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。该标准由W3C制定。目前所有浏览器几乎都支持CORS标准(IE10 以下 不支持)。

了解完CORS,我们知道 AJAX跨域请求 肯定可以实现,只不过取决于服务器如何配置

另外,CORS只是解决了 AJAX跨域请求 的问题,如果 只想 获取跨域的数据(非AJAX),方法就很多了(比如 JSONP、WebSocket、设置代理 等等)。

疑问4解答

 AJAX跨域请求,其实要分2种情况来阐述:

如果是 简单请求浏览器会直接发出该http请求,服务器收到并返回response给浏览器。浏览器检查response中的字段,看是否允许 AJAX跨域请求:

  • 允许,则使用服务器返回的跨域内容
  • 不允许,则浏览器会拦截掉返回的内容,并在console提示不允许跨域 

简单请求 必须同时满足以下2个条件(否则即视为复杂请求):

  • 请求方法是GET、POST或HEAD。
  • 请求头信息不超出以下字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(仅限于application/x-www-form-urlencoded、multipart/form-data、text/plain)。

如果是 复杂请求浏览器会先将该http请求拦截,同时会 自动生成 并 发出一个预检请求(即type为preflight,method为options),用于询问后台服务器是否允许 AJAX跨域请求。服务器同样会返回response,浏览器检查response中的字段:

  • 允许,则继续发起复杂请求,获取跨域数据
  • 不允许,则该复杂请求被丢弃,并在console提示

结论:在服务器不允许跨域的情况下,AJAX跨域请求 是 发出前 还是 返回后 被浏览器拦截,取决于该请求是 简单请求 还是 复杂请求

疑问5:如何让 复杂请求 对应的 预检请求preflight 只发一次?

在控制台可以看到,每个复杂请求发出之前,都会先发出一个预检请求(preflight)。但每次都发,其实挺浪费网络资源的。如何让它只发送一次呢?

解决办法:在服务器上可以通过设置 Access-Control-Max-Age 字段(单位秒)来指定预检请求在浏览器的缓存时间。当同一个复杂请求 下一次被发出时,如果其对应的 preflight 还没过期,那么复杂请求就可以直接被发出。

需要注意一点:比如在chrome浏览器,开发人员习惯 勾选“Disable Cache”(表示禁用浏览器缓存,如下图),这样Access-Control-Max-Age就失效了,预检请求 还是会每次都被发出。所以想看到测试效果的话,记得先 取消“Disable Cache”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值