Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: s/last/email address/g;

...

This noncompliant code example creates a servlet that echos a parameter passed to it, as well as the previous parameter passed to it. The previous parameter is stored in the last lastAddrAddr variable, which is an instance field.

Code Block
bgColor#ffcccc
langjava
public class SampleServlet extends HttpServlet {

  private String lastlastAddr = "lastnobody@nowhere.com";

  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html>");

    String currentemailAddr = request.getParameter("currentemailAddr");

    if (currentemailAddr != null) {
      out.println("CurrentEmail ParameterAddress:");
      out.println(sanitize(currentemailAddr));
      out.println("<br>Last<br>Previous ParameterAddress:");
      out.println(sanitize(lastlastAddr));
    };

    out.println("<p>");
    out.print("<form action=\"");
    out.print("SampleServlet\" ");
    out.println("method=POST>");
    out.println("Parameter:");
    out.println("<input type=text size=20 name=current>emailAddr>");
    out.println("<br>");
    out.println("<input type=submit>");
    out.println("</form>");

    lastlastAddr = currentemailAddr;
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    doGet(request, response);
  }

  // Filter the specified message string for characters
  // that are sensitive in HTML.
  public static String sanitize(String message) {
    // ...
  }
}

Because the HttpServlet class is a singleton, there is only one last lastAddr field that is shared by every client who accesses the servlet. Therefore the contents of the last lastAddr field can be the previous setting of the field by a different client. Also, since there is no thread-safety, it is possible for the last lastAddr field to take on a stale value should two clients request the parameter simultaneously.

...

In this noncompliant code example, the last lastAddr field is static. This more accurately reflects the fact that there is never more than a single instance of the field. This code has the same behavior as the previous noncompliant code example.

Code Block
bgColor#ffcccc
langjava
public class SampleServlet extends HttpServlet {

  private static String lastlastAddr = "lastnobody@nowhere.com";

  // ... other methods unchanged
}

...

In this compliant solution, the lastlastAddr field is static, and is protected from concurrent conemailAddr access by a separate lock object, as is recommended by LCK00-J. Use private final lock objects to synchronize classes that may interact with untrusted code. This guarantees thread-safety in the servlet. The servlet can still return the last lastAddr parameter entered by a different session, however.

Code Block
bgColor#ccccff
langjava
public class SampleServlet extends HttpServlet {
 
  private static String lastlastAddr = "lastnobody@nowhere.com";
  private static final Object lastLocklastAddrLock = new Object();

  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html>");
 
    String currentemailAddr = request.getParameter("currentemailAddr");
 
    if (currentemailAddr != null) {
      out.println("CurrentEmail ParameterAddress::");
      out.println(sanitize(currentemailAddr));
      synchronized (lock) {
        out.println("<br>Last Parameter<br>Previous Email Address::");
        out.println(sanitize(lastlastAddr));
      }
    };
 
    out.println("<p>");
    out.print("<form action=\"");
    out.print("SampleServlet\" ");
    out.println("method=POST>");
    out.println("Parameter:");
    out.println("<input type=text size=20 name=current>emailAddr>");
    out.println("<br>");
    out.println("<input type=submit>");
    out.println("</form>");
 
    synchronized (lock) {
      lastlastAddr = currentemailAddr;
    }
  }
 
  public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    doGet(request, response);
  }

  // Filter the specified message string for characters
  // that are sensitive in HTML.
  public static String sanitize(String message) {
    // ...
  }
}

...

This compliant solution stores the last lastAddr parameter in the HttpSession object, which is provided as part of the HttpServletRequest. The servlet mechanism keeps track of the session, providing the client with the session's ID, which is stored as a cookie by the client's browser. The other information in the session, including the last lastAddr attribute, are stored by the server. Consequently, the servlet provides the last lastAddr value that was presented to the servlet in the same session (avoiding race conditions with requests from other sessions). The local variables, which temporarily hold data in this example, are not vulnerable to race conditions in the singleton.  

Code Block
bgColor#ccccff
langjava
public class SampleServlet extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html>");

    String currentemailAddr = request.getParameter("currentemailAddr");
    HttpSession session = request.getSession();
    Object attr = session.getAttribute("lastlastAddr");
    String lastlastAddr = (attr == null) ? "null" : attr.toString();

    if (currentemailAddr != null) {
      out.println("CurrentEmail ParameterAddress::");
      out.println(sanitize(currentemailAddr));
      out.println("<br>Last Parameter<br>Previous Email Address::");
      out.println(sanitize(lastlastAddr));
    };

    out.println("<p>");
    out.print("<form action=\"");
    out.print("SampleServlet\" ");
    out.println("method=POST>");
    out.println("Parameter:");
    out.println("<input type=text size=20 name=current>emailAddr>");
    out.println("<br>");
    out.println("<input type=submit>");
    out.println("</form>");

    session.setAttribute("lastlastAddr", currentemailAddr);
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    doGet(request, response);
  }

  // Filter the specified message string for characters
  // that are sensitive in HTML.
  public static String sanitize(String message) {
    // ...
  }
}

...