SV.EMAIL
未检查的电子邮件
将未检查的用户输入用于电子邮件地址或电子邮件的其他部分时,会检测到该错误。
从 2023.2 版本开始,此检查器将支持 Jakarta EE。
漏洞与风险
电子邮件地址是 Web 应用程序中很常用的输入字段。在某些情况下,应用程序使用这些电子邮件地址向用户发送电子邮件,或者在网站上显示电子邮件地址。就像所有其他用户输入一样,电子邮件地址容易受到通过恶意内容发起的攻击。例如,应用程序可以使用为用户存储的电子邮件字符串,通过直接调用 sendmail 命令向用户发送电子邮件。如果未检查便使用该字符串,则它可能包含任意命令,这些命令可以在应用程序主机上与 sendmail 一起运行(因此导致命令注入漏洞)。恶意用户还可以使用 Web 服务器发送“垃圾”电子邮件,或者含有不良内容的电子邮件。
Klocwork 安全漏洞 (SV) 检查器可识别可能创建危险数据的调用;这些调用被视为不安全的来源。用户所提供的任何数据都可能是不安全的来源,因为用户可能是攻击者,或者可能引入人为错误。
缓解与预防
可以通过验证所有来自应用程序外部的输入(例如用户输入、文件输入、系统参数等)防止来自用户输入的电子邮件注入攻击。验证应包括长度和内容。通常仅需要字母数字字符(即 A-Z、a-z、0-9),但对于电子邮件地址而言,字符“@”和下划线字符应该也可以接受。应对任何其他接受的字符进行转义。在每个数据源处(例如从 HTTP 请求读取每个参数时)执行验证。
漏洞代码示例 1
import javax.servlet.http.*;
import javax.mail.internet.*;
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
try {
// Get system properties
Properties props = System.getProperties();
// Setup mail server
props.put("mail.smtp.host", "my.company.com");
// Get session
Session session = Session.getDefaultInstance(props, null);
// Define message
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("admin@my.company.com"));
final String email = req.getParameter("email");
Address addr = new InternetAddress(email);
message.setRecipient(Message.RecipientType.TO, addr);
message.setSubject(subject);
message.setText(text);
// Send message
Transport.send(message);
} catch (AddressException e) {
throw new ServletException(e);
} catch (MessagingException e) {
throw new ServletException(e);
}
}
Klocwork 在第 16 行报告 SV.EMAIL 缺陷,指出:未验证的用户输入存储在 email(第 14 行)中,该输入用于创建地址对象 addr (第 15 行),此对象在第 16 行中用作收件人的地址。
漏洞代码示例 2
import jakarta.servlet.http.*;
import jakarta.mail.internet.*;
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
try {
// Get system properties
Properties props = System.getProperties();
// Setup mail server
props.put("mail.smtp.host", "my.company.com");
// Get session
Session session = Session.getDefaultInstance(props, null);
// Define message
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("admin@my.company.com"));
final String email = req.getParameter("email");
Address addr = new InternetAddress(email);
message.setRecipient(Message.RecipientType.TO, addr);
message.setSubject(subject);
message.setText(text);
// Send message
Transport.send(message);
} catch (AddressException e) {
throw new ServletException(e);
} catch (MessagingException e) {
throw new ServletException(e);
}
}
Klocwork 在第 16 行报告 SV.EMAIL 缺陷,指出:未验证的用户输入存储在 email(第 14 行)中,该输入用于创建地址对象 addr (第 15 行),此对象在第 16 行中用作收件人的地址。
外部指导
扩展
此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 Java 分析。