CVE-2014-125075 (Java, published 2023-01-11T19:15Z)
Description: value: A vulnerability was found in gmail-servlet and classified as critical. This issue affects the function search of the file src/Model.java. The manipulation leads to sql injection. The identifier of the patch is 5d72753c2e95bb373aa86824939397dc25f679ea. It is recommended to apply a patch to fix this issue. The identifier VDB-218021 was assigned to this vulnerability.
Severity: nan (CVSS v3 base score: 9.8)
Weakness: CWE-89 \u2014 Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
Repository: https://github.com/ChrisMcMStone/gmail-servlet
Files changed:
.gitignore
README.md
src/AddContact.java
src/Error.java
src/Login.java
src/Logout.java
src/Model.java
src/SearchContact.java
src/SendEmail.java
web/WEB-INF/web.xml
web/addcontact.jsp
web/contact.jsp
web/email.html
web/index.html
web/sent.jsp
web/styles.css
Commit message: Added validation for contact adding and changed use of prepared statements to avoid SQL injection.


Vulnerable code:

Fixed code:
*.zip
lib/*
*.iml
out/*
web/WEB-INF/lib/*
.idea/

gmail-servlet
=============

Final assignment for SSC uni module
import javax.mail.Session;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;

/**
 * Created by chris on 09/12/14.
 */

/**
 * Servlet for adding contacts
 */
@WebServlet("/addcontact")
public class AddContact extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Checks whether session has timed out
        if (System.currentTimeMillis() > (request.getSession().getLastAccessedTime() + 300000)) {
            RequestDispatcher dispatcher = request.getRequestDispatcher("Error");    //New Request Dispatcher
            request.setAttribute("error", "Login session timed out, please click retry to log back in");
            request.setAttribute("previous", "index.html");
            dispatcher.forward(request, response);    //Forwards to the page
        } else {

            HttpSession httpSession = request.getSession();     //Get Session details
            Session session = (Session) httpSession.getAttribute("session");
            String user = session.getProperties().getProperty("mail.user");

            String forename = request.getParameter("firstname");
            String surname = request.getParameter("secondname");
            String email = request.getParameter("email");

            Model m = new Model(user);      //Initialize model

            try {
                m.addContact(forename, surname, email, user);
                httpSession.setAttribute("success", "<p id=\"success\">Contact saved successfully</p>");
                request.getRequestDispatcher("addcontact.jsp").forward(request, response);
            } catch (SQLException e) {

                RequestDispatcher dispatcher = request.getRequestDispatcher("Error"); //New Request Dispatcher
                request.setAttribute("error", e.getMessage());
                request.setAttribute("previous", "addcontact.jsp");
                dispatcher.forward(request, response);
            }
        }
    }

}
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class Error extends HttpServlet {

    /**
     * Calls doPost
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    /**
     * Gets the PrintWriter from the response and prints the HTML to show the error page
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();    //Gets the PrintWriter
        String back = (String) request.getAttribute("previous");
        out.println(
                "<!DOCTYPE html>" +
                        "<html>" +
                        "<head lang=\"en\">" +
                        "<meta charset=\"UTF-8\">" +
                        "<title>Error Occured</title>" +
                        "</head>" +
                        "<body>" +
                        "<center>" +
                        "<h1>Error Occurred!</h1>" +
                        "<div>" +
                        "<br>" +
                        "Error: " + request.getAttribute("error") + "<br>" + "<br>" + "<br>" +//Gets the error message
                        "</div>" +
                        "<div class='error-actions'>" +
                        "<a href='" + back + "'>Retry</a>" +
                        "</div>" +
                        "</center>" +
                        "</body>" +
                        "</html>"
        );
    }
}
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Properties;

/**
 * Created by chris on 08/12/14.
 */

@WebServlet("/login")
public class Login extends HttpServlet {

    public Login() {
        super();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        String username = request.getParameter("username"); //Gets all the parameters
        String password = request.getParameter("password");
        Properties prop = System.getProperties();

        try {

            prop.put("mail.user", username);
            prop.put("mail.password", password);
            prop.put("mail.smtp.auth", "true");
            prop.put("mail.smtp.starttls.enable", "true");
            prop.put("mail.smtp.host", "smtp.gmail.com");
            prop.put("mail.smtp.port", "587");
            prop.put("mail.store.protocol", "imaps");

            Session session = Session.getDefaultInstance(prop);
            Store store = session.getStore("imaps");
            store.connect("imap.googlemail.com", username, password);

            request.getSession().setAttribute("session", session);

            RequestDispatcher dispatcher = request.getRequestDispatcher("email.html");
            dispatcher.forward(request, response);

        } catch (MessagingException e) {
            RequestDispatcher dispatcher = request.getRequestDispatcher("Error"); //New Request Dispatcher
            request.setAttribute("error", e.getMessage());
            request.setAttribute("previous", "index.html");
            dispatcher.forward(request, response);
        }
    }
}
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by chris on 09/12/14.
 */
@WebServlet("/logout")
public class Logout extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            request.getSession().invalidate();
        } catch (IllegalStateException e) {
        } finally {
            response.sendRedirect("index.html");
        }


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
import java.sql.*;

/**
 * Created by chris on 08/12/14.
 */
public class Model {

    private String DBNAME = "jdbc:postgresql://dbteach2.cs.bham.ac.uk/cxm373";
    private String USERNAME = "cxm373";
    private String PASSWORD = "computer2014";
    private String emailUser;
    private Connection conn;

    public Model(String username) {
        emailUser = username;
        conn = connect();
    }

    public Connection connect() {
        try {
            Class.forName("org.postgresql.Driver");
        } catch (ClassNotFoundException e) {
            System.out.println("Driver not found");
            System.exit(0);
        }

        System.out.println("PostgreSQL driver registered.");

        Connection dbConn = null;

        try {
            dbConn = DriverManager.getConnection(DBNAME, USERNAME, PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        if (dbConn != null) {
            System.out.println("Connected to database successfully.");
        } else {
            System.out.println("Database connection failed.");
        }
        return dbConn;

    }

    public String search(String forename, String surname, String contactemail) throws SQLException {

        String query;
        if (forename.isEmpty() && surname.isEmpty()) {
            query = "";
        } else if (forename.isEmpty()) {
            query = "familyname LIKE '%" + surname + "' and";
        } else if (surname.isEmpty()) {
            query = "forename LIKE '%" + forename + "' and ";
        } else {
            query = "forename LIKE '%" + forename + "' and familyname LIKE '%" + surname + "' and";
        }

        PreparedStatement ps = conn.prepareStatement("SELECT * FROM contactinfo WHERE ? contactemailaddress = ?");
        ps.setString(1, query);
        ps.setString(2, contactemail);
        ResultSet rs = ps.executeQuery();
        StringBuilder result = new StringBuilder("<h3>Search results...</h3><table class=\"result-table\">" +
                "<tr>" +
                "<th>Forename</th> <th>Surname</th> <th>Email</th>" +
                "</tr>");
        while (rs.next())
        {
            result.append("<tr><td>");
            result.append(rs.getString(2));
            result.append("</td><td>" + rs.getString(3));
            result.append("</td><td>" + rs.getString(4) + "</td></tr>");
        }

        result.append("</table");
        conn.close();
        return result.toString();
    }

    public void addContact(String firstname, String surname, String email, String user) throws SQLException {

        PreparedStatement checkDuplicate = conn.prepareStatement("SELECT * FROM contactinfo WHERE emailaddress = ?");
        checkDuplicate.setString(1, email);
        ResultSet rs = checkDuplicate.executeQuery();
        if (rs.next()) {
            throw new SQLException("Contact already exists");
        }
        PreparedStatement newStudent = conn.prepareStatement("INSERT INTO " +
                "contactinfo (forename, familyname, emailaddress, contactemailaddress) VALUES (?, ?, ?, ?)");
        newStudent.setString(1, firstname);
        newStudent.setString(2, surname);
        newStudent.setString(3, email);
        newStudent.setString(4, user);
        newStudent.execute();

        conn.close();
    }
}


//Todo sort out errors, when logging in unsuccessfully etc
//Todo format message sent successfully page
//Todo add some JS to allow user to click search results and send an email to that address
import javax.mail.Session;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;

/**
 * Created by chris on 09/12/14.
 */

/**
 * Servlet for searching for contacts
 */
@WebServlet("/searchcontact")
public class SearchContact extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Checks whether session has timed out
        if (System.currentTimeMillis() > (request.getSession().getLastAccessedTime() + 300000)) {
            RequestDispatcher dispatcher = request.getRequestDispatcher("Error");    //New Request Dispatcher
            request.setAttribute("error", "Login session timed out, please click retry to log back in");
            request.setAttribute("previous", "index.html");
            dispatcher.forward(request, response);    //Forwards to the page
        } else {
            HttpSession httpSession = request.getSession();
            Session session = (Session) httpSession.getAttribute("session");
            String user = session.getProperties().getProperty("mail.user");
            String searchQueryForeName = request.getParameter("forename");
            String searchQuerySurName = request.getParameter("surname");

            Model m = new Model(user);

            try {
                String resultTable = m.search(searchQueryForeName, searchQuerySurName, user);
                httpSession.setAttribute("results", resultTable);
                httpSession.setAttribute("success", "");
                request.getRequestDispatcher("contact.jsp").forward(request, response);
            } catch (SQLException e) {
                RequestDispatcher dispatcher = request.getRequestDispatcher("Error"); //New Request Dispatcher
                request.setAttribute("error", e.getMessage());
                request.setAttribute("previous", "contact.jsp");
                dispatcher.forward(request, response);
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

}

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by chris on 08/12/14.
 */

@WebServlet("/sendemail")
public class SendEmail extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (System.currentTimeMillis() > (request.getSession().getLastAccessedTime() + 300000)) {
            RequestDispatcher dispatcher = request.getRequestDispatcher("Error");    //New Request Dispatcher
            request.setAttribute("error", "Login session timed out, please click retry to log back in");
            request.setAttribute("previous", "index.html");
            dispatcher.forward(request, response);    //Forwards to the page
        } else {
            try {
                if (request.getParameter("search") != null) {
                    request.getSession().setAttribute("results", "");
                    request.getSession().setAttribute("success", "");
                    request.getRequestDispatcher("contact.jsp").forward(request, response);
                } else if (request.getParameter("add") != null) {
                    request.getSession().setAttribute("results", "");
                    request.getSession().setAttribute("success", "");
                    request.getRequestDispatcher("addcontact.jsp").forward(request, response);
                } else {
                    Session session = (Session) request.getSession().getAttribute("session");
                    String user = session.getProperties().getProperty("mail.user");
                    String password = session.getProperties().getProperty("mail.password");
                    String to = request.getParameter("recipient");
                    String subject = request.getParameter("subject");
                    String content = request.getParameter("message");

                    MimeMessage message = new MimeMessage(session);            //Creates new message
                    message.setFrom(new InternetAddress(user));            //Sets the sender
                    message.setRecipients(Message.RecipientType.TO, to);    //Sets the recipient
                    message.setSubject(subject);                            //Sets the subject
                    message.setText(content);                                //Sets the content

                    Transport tr = session.getTransport("smtp");
                    tr.connect("smtp.gmail.com", user, password);

                    tr.sendMessage(message, message.getAllRecipients());    //Sends the message

                    response.sendRedirect("sent.jsp");
                }

            } catch (Exception e) {

                RequestDispatcher dispatcher = request.getRequestDispatcher("Error");    //New Request Dispatcher

                request.setAttribute("error", e.getMessage());
                request.setAttribute("previous", "email.html");

                dispatcher.forward(request, response);    //Forwards to the page
            }
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>Error</servlet-name>
        <servlet-class>Error</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>SearchContactController</servlet-name>
        <servlet-class>SearchContact</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>AddContactController</servlet-name>
        <servlet-class>AddContact</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Error</servlet-name>
        <url-pattern>/Error</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>SearchContactController</servlet-name>
        <url-pattern>/SearchContactController</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>AddContactController</servlet-name>
        <url-pattern>/AddContactController</url-pattern>
    </servlet-mapping>
</web-app>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>Search for/Add contact</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
      $(document).ready( function() {
        $('#success').delay(1000).fadeOut();
      });
    </script>
</head>
<body>
<a id="back" href="email.html">Back</a>
<div class="logout-container">
    <form action="logout" method="post">
        <input id="logout" type="submit" value="Log Out"/>
    </form>
</div>
<section class="main">
    <h1>Add a contact</h1>
    <p>Enter a forename, surname and email and click add!</p>
    <form action="addcontact" method="post">
        <table class="form-table">
            <tr>
                <td>
                    <b>Forename: </b>
                </td>
                <td>
                    <input id="name" name="firstname" type="text" placeholder="..." required>
                </td>
            </tr>
            <tr>
                <td>
                    <b>Surname: </b>
                </td>
                <td>
                    <input id="surname" name="secondname" type="text" placeholder="...">
                </td>
            </tr>
            <tr>
                <td>
                    <b>Email Address: </b>
                </td>
                <td>
                    <input id="email" name="email" type="email" placeholder="..." required>
                </td>
            </tr>
            <tr>
                <td></td>
                <td>
                    <input type="submit" value="Submit">
                    <button type="reset" value="Reset">Reset</button>
                </td>
            </tr>
        </table>
    </form>
    <%=request.getSession().getAttribute("success")%>
</section>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>Search for/Add contact</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
    $( ".reset" ).click(function() {
    document.getElementByClassName("result-table").remove();
    </script>
</head>
<body>
<a id="back" href="email.html">Back</a>
<div class="logout-container">
    <form action="logout" method="post">
        <input id="logout" type="submit" value="Log Out"/>
    </form>
</div>
<section class="main">
    <h1>Search for a contact</h1>

    <p>Enter a forename and/or surname and click search!</p>

    <form action="searchcontact" method="post">
        <table class="form-table">
            <tr>
                <td>
                    <b>Forename: </b>
                </td>
                <td>
                    <input id="name" name="forename" type="text" placeholder="...">
                </td>
            </tr>
            <tr>
                <td>
                    <b>Surname: </b>
                </td>
                <td>
                    <input id="surname" name="surname" type="text" placeholder="...">
                </td>
            </tr>
            <tr>
                <td></td>
                <td>
                    <input type="submit" value="Submit">
                    <button class="reset" type="reset" value="Reset">Reset</button>
                </td>
            </tr>
        </table>
    </form>
    <%=request.getSession().getAttribute("results")%>
</section>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <title>Send an E-Mail</title>
</head>

<body>
<div class="logout-container">
    <form action="logout" method="post">
        <input id="logout" type="submit" value="Log Out"/>
    </form>
</div>
<section class="main">
    <h1>Send an E-Mail</h1>

    <p>Input the required fields below and click send!</p>

    <form action="sendemail" method="post">
        <table class="form-table">
            <tr>
                <td>
                    <b>To: </b>
                </td>
                <td>
                    <input class="input" name="recipient" type="email" placeholder="example@gmail.com">
                </td>
                <td>
                    <input id="find" name="search" type="submit" value="  ">
                </td>
                <td>
                    <input id="addcontact" name="add" type="submit" value="  ">
                </td>
                </td>
            </tr>
            <tr>
                <td>
                    <b>Subject: </b>
                </td>
                <td>
                    <input class="input" name="subject" type="text" placeholder="...">
                </td>
            </tr>
            <tr>
                <td>
                    <b>Message: </b>
                </td>
                <td>
                    <textarea class="input" name="message" placeholder="..."></textarea>
                </td>
            </tr>
            <tr>
                <td>
                </td>
                <td>
                    <input type="submit" value="Send">
                    <button type="reset" value="Reset">Reset</button>
                </td>
            </tr>
        </table>
    </form>
</section>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <title>Send an E-Mail</title>
</head>

<body>

<section class="main">
    <h1>Log into GMail</h1>

    <p>Input the required fields below to login.</p>

    <form action="login" method="post">
        <table class="form-table">
            <tr>
                <td>
                    <b>GMail Username: </b>
                </td>
                <td>
                    <input id="subject" name="username" type="email" placeholder="example@gmail.com">
                </td>
            </tr>
            <tr>
                <td>
                    <b>Password: </b>
                </td>
                <td>
                    <input id="password" name="password" type="password" placeholder="password">
                </td>
            </tr>
            <tr>
                <td>
                </td>
                <td>
                    <input type="submit" value="Submit">
                    <button type="reset" value="Reset">Reset</button>
                </td>
            </tr>
        </table>
    </form>
</section>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
<center>
    <b>Message sent successfully!</b>
    <br>
    <a href="email.html">Click here to send another email.</a>
</center>
</body>
</html>
body {
    background: black;
    font-family: "Lucida Console", Monaco, monospace;
    text-align: center;
    margin: 0px auto;
}

.main {
    text-align: center;
    color: cadetblue;
    display: inline-block;
}

.main h3 {
    text-align: left;
}

.form-table {
    margin-left: auto;
    margin-right: auto;
    text-align: right;
}

.input {
    width:90%;
}

.logout-container {
    position: absolute;
    right: 0px;
    display: inline-block;
    vertical-align: top;
}

#back {
    position: absolute;
    left: 0px;
    font-size: 13pt;
    color: cadetblue;
    text-align: left;
    display: inline-block;
    vertical-align: top;
}

#find {
    background:url(http://s21.postimg.org/t3qkwqsar/searchcontact.png);
    background-repeat: no-repeat;
    border: 0;
    cursor: pointer;
    cursor: hand;
}

#addcontact {
    background:url(http://s21.postimg.org/8v37b0szn/addcontact.png);
    background-repeat: no-repeat;
    border: 0;
    cursor: pointer;
    cursor: hand;
}

#logout {
    background:none!important;
    border:none;
    padding:0!important;
    color:cadetblue;
    text-decoration:underline;
    cursor:pointer;
    font-size: 12pt;
}

#success {
    color: seagreen;
}

.result-table{
    position: relative;
    width: 100%;;
    margin-left: auto;
    margin-right: auto;
    font-size:11px;
    color:#333333;
    border-width: 1px;
    border-color: #666666;
    border-collapse: collapse;
}
.result-table th {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: cadetblue;
}

.result-table td {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: #ffffff;
}