CVE-2025-7962
Description
In Jakarta Mail 2.0.2 it is possible to preform a SMTP Injection by utilizing the \r and \n UTF-8 characters to separate different messages.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jakarta Mail 2.0.2 is vulnerable to SMTP injection via and UTF-8 characters, allowing an attacker to break out of a message and inject arbitrary SMTP commands.
Jakarta Mail 2.0.2 fails to properly sanitize CRLF characters (\r and \n) in email addresses or headers, leading to SMTP injection. An attacker can supply crafted UTF-8 encoded newlines in user-controlled input to break out of the intended message envelope and inject arbitrary SMTP commands [1][3]. This is a classic injection flaw in the SMTP protocol handling.
Exploitation
To exploit this vulnerability, an attacker typically needs the ability to specify email addresses or message headers that are then processed by Jakarta Mail's API. No special authentication is required beyond the ability to send email through the affected library. The injection occurs when the library transmits the raw SMTP commands, allowing the attacker to add extra commands such as DATA, MAIL FROM, or RCPT TO [1][2]. The attack is performed remotely over the network.
Impact
Successful exploitation allows an attacker to send arbitrary emails from the affected server, bypassing intended restrictions. This can lead to email spoofing, unauthorized sending of multiple messages, and potential further SMTP command injection attacks that could be used for phishing or spam campaigns [1][4].
Mitigation
The vulnerability exists in Jakarta Mail 2.0.2. The fix has been implemented in the Eclipse Angus Mail project (the implementation behind Jakarta Mail) in commit 269099b [2]. Users should upgrade to a patched version of Jakarta Mail API (e.g., version 2.1.3-3 as shipped by Jenkins) or apply the corresponding fix from the Angus Mail repository [1][2]. No workarounds are documented other than upgrading.
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.eclipse.angus:smtpMaven | < 2.0.4 | 2.0.4 |
com.sun.mail:jakarta.mailMaven | < 1.6.8 | 1.6.8 |
com.sun.mail:jakarta.mailMaven | >= 2.0.0, < 2.0.2 | 2.0.2 |
Affected products
2- Eclipse Foundation/Jakarta Mailv5Range: 1.6.8
Patches
1269099b652a0Fix issue299 (#166)
3 files changed · +208 −2
providers/angus-mail/src/test/java/org/eclipse/angus/mail/test/FakeSMTPServer.java+87 −0 added@@ -0,0 +1,87 @@ +/* + * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.eclipse.angus.mail.test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.ServerSocket; +import java.net.Socket; + +public class FakeSMTPServer { + + private volatile boolean running = true; + + public void start(int port) { + try (ServerSocket serverSocket = new ServerSocket(port)) { + System.out.println("Fake SMTP server is running on port " + port); + + while (running) { + // 等待客户端连接 + Socket clientSocket = serverSocket.accept(); + System.out.println("New client connected: " + clientSocket.getInetAddress()); + + // 获取客户端输入流,用于接收 SMTP 请求 + BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true); + + // 发送欢迎消息,模拟服务器响应 + writer.println("220 Fake SMTP Server Ready"); + + // 读取客户端的输入并打印 + String line; + while ((line = reader.readLine()) != null) { + // 打印收到的每一行 SMTP 报文 + System.out.println("Received: " + line); + + // 模拟 SMTP 交互 + if (line.startsWith("HELO") || line.startsWith("EHLO")) { + writer.println("250 Hello " + clientSocket.getInetAddress().getHostName()); + } else if (line.startsWith("MAIL FROM")) { + writer.println("250 OK"); + } else if (line.startsWith("RCPT TO")) { + writer.println("250 OK"); + } else if (line.equals("DATA")) { + writer.println("354 Start mail input; end with <CRLF>.<CRLF>"); + } else if (line.equals(".")) { + writer.println("250 OK: Message received"); + } else if (line.equals("QUIT")) { + writer.println("221 Bye"); + break; + } + + // 如果客户端发送了 "QUIT",则退出当前会话 + if (line.equals("QUIT")) { + break; + } + } + + // 关闭当前客户端连接 + clientSocket.close(); + System.out.println("Client disconnected"); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void stop() { + running = false; + System.out.println("Fake SMTP server is stopping..."); + } +} \ No newline at end of file
providers/angus-mail/src/test/java/org/eclipse/angus/mail/test/Issue299Test.java+108 −0 added@@ -0,0 +1,108 @@ +/* + * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.eclipse.angus.mail.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.Properties; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import jakarta.mail.Authenticator; +import jakarta.mail.MessagingException; +import jakarta.mail.PasswordAuthentication; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeMessage; + +import org.eclipse.angus.mail.util.ASCIIUtility; +import org.junit.Test; + + +public class Issue299Test { + + static final int PORT = 18465; + static final String USER = "xxxunj******@163.com"; + static final String PASSWD = "EY**************"; + static final String toMail = "甲申申甶甴甸电甹甸甸畀畱畱瘮畣畯畭甾瘍瘊畄畁畔畁瘍瘊畓畵畢番略畣畴町畐畗畎畅畄瘍瘊瘍瘊畉瘠界畏畖畅瘠留畏畕瘡瘍瘊瘮瘍瘊畑畕畉畔瘍瘊@qq.com"; + static String TEXT = "Hello world"; + static String SUBJECT = "Test"; + + static Properties properties = new Properties(); + static Authenticator authenticator = null; + + public static void initProp(){ + properties.setProperty("mail.host","127.0.0.1"); + properties.put("mail.debug", "true"); + properties.setProperty("mail.transport.protocol","smtp"); + properties.setProperty("mail.smtp.auth","true"); + properties.setProperty("mail.smtp.timeout", "1000"); + properties.setProperty("mail.smtp.port", Integer.toString(PORT)); + authenticator = new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(USER, PASSWD); + } + }; + } + public static Session getSession(){ + return Session.getInstance(properties, authenticator); + } + + @Test + public void test() throws Exception { + FakeSMTPServer server = new FakeSMTPServer(); + ExecutorService service = Executors.newFixedThreadPool(1); + try { + service.execute(() -> { + try { + server.start(PORT); + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + initProp(); + + Session session = getSession(); + MimeMessage msg = new MimeMessage(session); + msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toMail)); + msg.setSubject(SUBJECT); + msg.setContent(TEXT, "text/html;charset=utf-8"); + msg.saveChanges(); + Transport.send(msg); + fail("It is expected an IllegalArgumentException because there are illegal characters in the command"); + } catch (Exception e) { + if (e.getCause() == null || e.getCause().getClass() != IllegalArgumentException.class) { + fail("It is expected an IllegalArgumentException because there are illegal characters in the command. Exception was: " + e); + } + } finally { + server.stop(); + service.shutdown(); + service.awaitTermination(5, TimeUnit.SECONDS); + } + } + +} \ No newline at end of file
providers/smtp/src/main/java/org/eclipse/angus/mail/smtp/SMTPTransport.java+13 −2 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -2457,14 +2457,25 @@ private void sendCommand(byte[] cmdBytes) throws MessagingException { //logger.fine("SENT: " + new String(cmdBytes, 0)); try { + validateCommand(cmdBytes); serverOutput.write(cmdBytes); serverOutput.write(CRLF); serverOutput.flush(); - } catch (IOException ex) { + } catch (IOException | RuntimeException ex) { throw new MessagingException("Can't send command to SMTP host", ex); } } + private void validateCommand(byte[] cmdBytes) throws MessagingException { + final byte CR = '\r'; + final byte LF = '\n'; + for (byte b : cmdBytes) { + if (b == LF || b == CR) { + throw new IllegalArgumentException("Command contains illegal character: " + String.format("0x%02x",b)); + } + } + } + /** * Reads server reponse returning the <code>returnCode</code> * as the number. Returns -1 on failure. Sets
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/advisories/GHSA-9342-92gg-6v29ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-7962ghsaADVISORY
- www.openwall.com/lists/oss-security/2025/09/03/4ghsaWEB
- github.com/eclipse-ee4j/angus-mail/commit/269099b652a0a5c2fa140f1296a18f0fbbea0d44ghsaWEB
- github.com/jakartaee/mail-api/issues/765ghsaWEB
- github.com/jakartaee/mail-api/pull/760ghsaWEB
- gitlab.eclipse.org/security/cve-assignement/-/issues/67ghsaWEB
- gitlab.eclipse.org/security/vulnerability-reports/-/issues/290ghsaWEB
- gitlab.eclipse.org/security/vulnerability-reports/-/issues/290ghsaWEB
News mentions
1- Jenkins Security Advisory 2025-09-03Jenkins Security Advisories · Sep 3, 2025