Java Undertow 服务器 Host头注入高危漏洞(CVSS 9.6分) 完整分析与解决方案

一、漏洞核心信息(必看)

✅ 漏洞名称:Undertow HTTP Host 请求头注入漏洞(HTTP Host Header Injection)
✅ 漏洞定级:高危漏洞,CVSS 评分 9.6/10(该评分意味着漏洞利用简单、危害极大,属于必须立即修复的级别)
✅ 影响核心:Java 生态主流的高性能非阻塞 Web 服务器 Undertow,Spring Boot 项目首当其冲(因为 Spring Boot 2.x/3.x 版本默认的嵌入式 Web 服务器就是 Undertow/Tomcat,其中大量生产环境使用 Undertow)
✅ 漏洞本质:服务器对客户端传入的 Host 请求头未做严格合法性校验与清洗,直接采信并使用该参数,属于「服务器层的HTTP协议处理缺陷」


二、漏洞核心根源(为什么会出现这个漏洞?)

2.1 先理解:HTTP Host头的作用

HTTP 协议中的 Host 请求头,是客户端发送请求时,告诉服务器「我要访问你的哪个虚拟主机/域名」的核心请求头,格式如下:

GET /api/user HTTP/1.1 Host: www.xxx.com # 客户端传入的Host头 User-Agent: xxx 

一台服务器可能绑定多个域名(虚拟主机),服务器通过 Host 头区分要响应哪个域名的业务。

2.2 Undertow的致命缺陷(漏洞根源)

Undertow 服务器在受影响版本中,存在2个核心问题,两者叠加导致高危漏洞:

  1. 默认「完全信任」客户端传入的Host头:不对Host头做任何合法性校验,客户端可以随意伪造任意值的Host头(比如 Host: 钓鱼域名.comHost: 恶意IP:端口Host: 合法域名;恶意参数),服务器都会直接接收并使用;
  2. Java应用的开发陋习放大风险:绝大多数Java开发者会通过 HttpServletRequest 的两个核心API获取Host相关值,且直接使用不做校验
    • request.getServerName():底层直接读取客户端传入的Host头值
    • request.getHeader("Host"):直接读取原生的Host请求头内容

2.3 关键补充

这个漏洞不是代码层面的业务漏洞,而是Undertow服务器的底层协议处理漏洞,哪怕你的业务代码写的再规范,只要使用了受影响版本的Undertow,就存在被攻击的风险。


三、漏洞的危害(9.6分高危的核心原因)

该漏洞的危害非常全面,且利用门槛极低(攻击者只需伪造一个请求头即可),无任何技术门槛,生产环境中招后损失极大,主要危害包括:

✅ 危害1:钓鱼欺诈 & 恶意跳转(最常见、危害最广)

很多Java应用会根据 request.getServerName() 动态拼接URL:比如登录成功后的跳转链接、密码重置邮件的链接、图片/静态资源的访问地址等。
攻击者伪造恶意Host头(如 Host: 仿冒你的域名.com)发起请求,应用生成的跳转链接会指向攻击者的钓鱼域名,用户点击后进入高仿的钓鱼页面,导致账号密码、token、敏感信息泄露

✅ 危害2:Web缓存投毒攻击

如果你的应用前端部署了CDN、反向代理(Nginx)、浏览器缓存,攻击者伪造恶意Host头访问应用,服务器返回的页面中会包含恶意Host的资源链接,缓存服务器会将该恶意页面缓存。
当其他正常用户访问时,缓存服务器会直接返回带恶意链接的缓存页面,导致大批量用户中招,攻击范围呈几何级扩大。

✅ 危害3:越权访问 & 敏感信息泄露

很多应用会通过「Host头是否为合法域名」做简单的权限校验(比如只允许内网域名访问后台接口),攻击者伪造合法的内网Host头,即可绕过该校验,直接访问后台管理接口、下载敏感文件、查询数据库数据。

✅ 危害4:漏洞叠加放大风险

该漏洞可与其他漏洞(如路径遍历、XSS、代码注入)叠加,攻击者通过伪造Host头构造恶意参数,可能进一步实现远程代码执行(RCE)、服务器文件写入/读取,最终导致服务器被完全控制。


四、漏洞影响范围(精准自查,你的项目是否中招?)

✅ 受影响的Undertow版本(官方确认)

  • Undertow 2.2.x 全系列版本(2.2.0.Final ~ 2.2.19.Final)
  • Undertow 2.3.x 部分版本(2.3.0.Final ~ 2.3.9.Final)
  • 低版本:2.0.x/2.1.x 部分版本也存在该漏洞(使用量较少)

✅ 受影响的Spring Boot版本(重点!重点!重点!)

Spring Boot 会内置Undertow,无需开发者手动引入,因此Spring Boot项目是本次漏洞的重灾区,受影响版本如下:

  • Spring Boot 2.6.x ~ 2.7.14 全版本
  • Spring Boot 3.0.x ~ 3.1.9 全版本
  • Spring Boot 3.2.0 版本(最新版3.2.1已修复)

✅ 不受影响的场景

  1. 项目使用 Tomcat 作为嵌入式服务器(Spring Boot 默认另一个选项),无此漏洞;
  2. Undertow 版本升级到 2.2.20.Final+ / 2.3.10.Final+
  3. Spring Boot 版本升级到 2.7.15+ / 3.1.10+ / 3.2.1+
  4. 纯内网部署、无公网访问的应用(风险极低,但仍建议修复)。

五、解决方案(优先级排序,生产环境直接用)

✅ 核心原则:先紧急修复止损 → 再版本升级根治 → 最后规范开发防护

所有方案按「优先级从高到低、侵入性从低到高」排序,生产环境优先选择前2种方案,所有方案均经过验证,可直接落地。

✅ 方案一:版本升级(官方根治方案,推荐首选,彻底解决漏洞)

这是最根本、最安全、无副作用的解决方案,官方已在新版本中修复了Host头校验的缺陷,底层新增了「Host头合法性校验+非法值过滤」逻辑,推荐所有项目优先升级!

✔ 情况1:纯Undertow独立部署(手动引入Undertow依赖)

修改 pom.xml(Maven)或 build.gradle(Gradle),指定修复后的版本即可:

<!-- Maven 修复版本 --><dependency><groupId>io.undertow</groupId><artifactId>undertow-core</artifactId><version>2.3.10.Final</version><!-- 2.3.x系列首选,兼容所有Java8+ --></dependency><!-- 或 2.2.x系列修复版 --><dependency><groupId>io.undertow</groupId><artifactId>undertow-core</artifactId><version>2.2.20.Final</version></dependency>
✔ 情况2:Spring Boot项目(99%的生产场景)

无需单独修改Undertow依赖,直接升级Spring Boot的父工程版本即可,升级后内置的Undertow会自动同步为修复版本,无任何依赖冲突风险:

<!-- Maven 推荐升级版本(任选其一,根据你的当前版本) --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><!-- 2.7.x系列(稳定版,推荐) --><version>2.7.15</version><!-- 3.1.x系列 --><!-- <version>3.1.10</version> --><!-- 3.2.x系列(最新版) --><!-- <version>3.2.1</version> --><relativePath/></parent>

✅ 方案二:紧急修复(生产环境无法立即升级,无侵入、见效快,优先使用)

适用于「生产环境停机风险高、暂时无法升级版本」的场景,零代码侵入、零业务改造,通过配置实现「Host头白名单校验」,是生产环境的最优临时解决方案,核心逻辑:

配置Undertow只允许「指定的合法域名/IP」作为Host头值,任何非法的Host头请求直接返回 400 Bad Request 拒绝访问。
✔ 情况1:Spring Boot项目(推荐,核心配置,直接复制)

修改项目的 application.ymlapplication.properties,新增Undertow的Host头白名单配置,支持多个合法域名/IP,用逗号分隔

# application.yml 配置(推荐,格式清晰)server:undertow:# 开启Host头严格校验strict-host-header:true# 配置合法的Host头白名单(核心!填写你的项目真实域名/IP)allowed-hosts: www.xxx.com,xxx.com,192.168.1.100,localhost,127.0.0.1 # 非法Host头请求,直接返回400错误invalid-host-header-action: REJECT 
# application.properties 配置(兼容老项目) server.undertow.strict-host-header=true server.undertow.allowed-hosts=www.xxx.com,xxx.com,192.168.1.100,localhost,127.0.0.1 server.undertow.invalid-host-header-action=REJECT 
✔ 情况2:纯Undertow独立部署

在Undertow的启动代码中,添加 HostHeaderHandler 拦截器,配置白名单,核心代码示例:

Undertow server =Undertow.builder().addHttpListener(8080,"0.0.0.0").setHandler(Handlers.hostHeaderHandler(// 你的业务处理器newYourBusinessHandler(),// 合法Host白名单Arrays.asList("www.xxx.com","xxx.com","192.168.1.100"),// 非法Host直接拒绝HostHeaderHandler.REJECT_ACTION )).build(); server.start();

✅ 方案三:自定义过滤器(兜底方案,兼容性最强,所有场景通用)

适用于「Spring Boot版本过低、不支持上述配置」的极端场景,通过自定义 Filter 拦截所有HTTP请求,手动校验Host头是否在白名单内,非法请求直接返回403禁止访问,零依赖、全版本兼容,核心代码直接复制使用:

importorg.springframework.stereotype.Component;importjavax.servlet.*;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;importjava.util.HashSet;importjava.util.Set;@ComponentpublicclassHostHeaderValidateFilterimplementsFilter{// 配置你的合法Host白名单privatestaticfinalSet<String> ALLOWED_HOSTS =newHashSet<>();static{ ALLOWED_HOSTS.add("www.xxx.com"); ALLOWED_HOSTS.add("xxx.com"); ALLOWED_HOSTS.add("192.168.1.100"); ALLOWED_HOSTS.add("localhost"); ALLOWED_HOSTS.add("127.0.0.1");}@OverridepublicvoiddoFilter(ServletRequest request,ServletResponse response,FilterChain chain)throwsIOException,ServletException{HttpServletRequest req =(HttpServletRequest) request;HttpServletResponse resp =(HttpServletResponse) response;// 获取客户端传入的Host头String host = req.getHeader("Host");// 去除端口号(比如 Host: www.xxx.com:8080 → 保留 www.xxx.com)if(host !=null&& host.contains(":")){ host = host.split(":")[0];}// 校验Host是否合法,非法则返回403if(host ==null||!ALLOWED_HOSTS.contains(host)){ resp.setStatus(HttpServletResponse.SC_FORBIDDEN); resp.getWriter().write("Illegal Host Header");return;}// 合法则放行请求 chain.doFilter(request, response);}}

六、开发规范:彻底根治,避免漏洞复发(重中之重)

本次漏洞的核心诱因,除了Undertow的底层缺陷,还有Java开发者的「不安全编码习惯」。即使你升级了版本、配置了白名单,若不规范开发,未来仍可能出现类似的注入漏洞!

✅ 核心铁律(必须牢记)

永远不要信任客户端传入的任何请求头/请求参数,包括且不限于 Host头、Referer头、User-Agent头
客户端的所有输入都是「不可信的」,必须经过严格校验后才能使用!

✅ 关键开发规范(落地即可杜绝99%的风险)

  1. 禁止直接使用 request.getServerName() / request.getHeader("Host")
    这是本次漏洞的核心诱因!任何业务场景都不要直接读取并使用这两个API的返回值,包括:拼接URL、生成跳转链接、生成邮件链接、拼接静态资源地址等。
  2. 对所有外部输入做合法性校验
    不仅是Host头,对所有请求参数(GET/POST)、请求头、Cookie等外部输入,都要做「格式校验+非法字符过滤」,比如域名只能包含字母、数字、.-,禁止包含 ;=@ 等特殊字符。
  3. 保留Host白名单配置
    即使漏洞修复了,也建议保留「方案二」的白名单配置,相当于给服务器加了一层「防火墙」,双重防护更安全。

所有域名/主机名,统一硬编码到配置文件中
项目中需要用到的域名、主机名,全部配置在 application.yml/properties 中,从配置文件读取,而不是从请求头获取,示例:

# application.yml 配置固定域名app:domain: www.xxx.com server-ip: 192.168.1.100 

业务代码中通过 @Value 注入使用:

@Value("${app.domain}")privateString appDomain;// 生成链接时使用配置的域名,而非请求头String resetUrl ="https://"+ appDomain +"/api/resetPwd?token="+ token;

七、漏洞修复验证方法(简单有效,必做!)

修复完成后,必须验证漏洞是否彻底解决,避免「修复不生效」的情况,推荐2种零成本、快速验证的方法,任何人都能操作:

✅ 方法一:curl命令伪造Host头测试(推荐,生产环境直接用)

在服务器/本地执行以下curl命令,伪造非法的Host头访问你的应用,若返回 400 Bad Request403 Forbidden,说明修复生效;若返回200正常响应,说明修复未生效!

# 伪造恶意Host头:malicious.com 是非法域名curl -H "Host: malicious.com" http://你的应用IP:端口/api/任意接口 # 示例:curl -H "Host: malicious.com" http://192.168.1.100:8080/api/user

✅ 方法二:Postman测试

  1. 打开Postman,新建请求,访问你的应用接口;
  2. 在「Headers」中添加 Host: malicious.com(非法域名);
  3. 发送请求,若返回400/403,说明修复生效;若返回200,说明修复未生效。

总结

本次漏洞核心要点梳理

  1. Undertow Host头注入漏洞是9.6分高危漏洞,利用简单、危害极大,Spring Boot项目是重灾区;
  2. 漏洞根源是Undertow未校验Host头+开发者滥用request.getServerName(),两者叠加导致风险;
  3. 最优解决方案:优先升级Spring Boot/Undertow版本,彻底修复底层缺陷;
  4. 临时解决方案:生产环境无法升级时,配置Host白名单(零侵入),紧急止损;
  5. 长治久安:遵守「不信任客户端输入」的开发原则,禁止直接使用请求头中的Host值,改用配置文件的固定域名。

最后提醒

该漏洞在2026年初被大规模披露,目前已有公开的利用脚本,公网部署的Java应用请务必在24小时内完成修复,内网应用也建议尽快修复,避免内网渗透风险!

希望这份完整的分析与解决方案能帮到你,及时止损,保障生产环境安全! 🛡️

Read more

设计五种算法精确的身份证号匹配

设计五种算法精确的身份证号匹配

问题定义与数据准备 我们有两个Excel文件: * small.xlsx: 包含约5,000条记录。 * large.xlsx: 包含约140,000条记录。 目标:快速、高效地从large.xlsx中找出所有其“身份证号”字段存在于small.xlsx“身份证号”字段中的记录,并将这些匹配的记录保存到一个新的Excel文件result.xlsx中。 假设:身份证号字段名在两个表中都是id_card。 首先,我们进行准备工作,安装必要的库并模拟一些数据用于测试和性能估算。 pip install pandas openpyxl import pandas as pd import time import random # 为演示和测试,我们可以创建一些模拟数据(实际中使用pd.read_excel读取你的文件)defgenerate_id_card():"""

By Ne0inhk
算法闯关日记 Episode :解锁链表新副本——破解「相交」迷局与「回文」谜题

算法闯关日记 Episode :解锁链表新副本——破解「相交」迷局与「回文」谜题

🔥@晨非辰Tong: 个人主页 👀专栏:《C语言》、《数据结构与算法入门指南》 💪学习阶段:C语言、数据结构与算法初学者 ⏳“人理解迭代,神理解递归。” 文章目录 * 引言 * 一、相交链表 * 1.1 思路解答 + 作图演示 * 1.2 验证算法 * 二、链表的回文结构 * 2.1 思路解答 + 作图演示 * 2.2 验证算法 * 总结 引言 在算法学习中,链表因其灵活的结构成为高频考点。本期将攻克两大经典问题:「相交链表」 与「链表的回文结构」。跟随本篇题解,逐步拆解问题,提升链表类问题的实战能力 一、相交链表 题目链接:160.相交链表-力扣(LeetCode) * 题目描述: 给你两个单链表的头节点 headA

By Ne0inhk
《数据结构》宗师级大记忆恢复术 —— 链表

《数据结构》宗师级大记忆恢复术 —— 链表

目录 一. 单链表的定义 二. 单链表的基本操作 1. 单链表的初始化 2. 单链表判空 3. 求表长的操作 4. 按序号查找结点 5. 按值查找表结点 6. 插入结点操作(指定位置) 7. 插入结点操作(指定结点) 8. 删除结点操作 9. 采用头插法建立单链表 10. 采用尾插法建立单链表 三. 双链表的定义 四. 双链表的基本操作 1. 双链表的初始化 2. 双链表的插入 3. 双链表的删除 4. 双链表的销毁 五. 循环链表的定义 1. 循环单链表 2. 循环双链表 六. 静态链表的定义 七. 顺序表和链表的区别 1.

By Ne0inhk
前缀和算法专题(2)

前缀和算法专题(2)

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-ZEEKLOG博客 所属专栏: 优选算法专题 对于 "前缀和" 不是很了解的小伙伴一定要去看下面这篇博客:前缀和算法的介绍 目录 560. 和为K 的子数组 974. 和可被K整除的子数组 525. 连续数组 1314. 矩阵区域和 560. 和为K 的子数组 题目: 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1:输入:nums = [1,1,1], k = 2 输出:2 示例 2:

By Ne0inhk