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 分析。