/**
  * Called to change the status of the utils.ModulePlan class. Once this has been called by a valid
  * administrator, the utils.ModulePlan will be changed.
  *
  * @param csrfToken
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
   ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
   log.debug("*** servlets.Admin.SetOpenFloor ***");
   PrintWriter out = response.getWriter();
   out.print(getServletInfo());
   HttpSession ses = request.getSession(true);
   Cookie tokenCookie = Validate.getToken(request.getCookies());
   Object tokenParmeter = request.getParameter("csrfToken");
   if (Validate.validateAdminSession(ses, tokenCookie, tokenParmeter)) {
     ShepherdLogManager.setRequestIp(
         request.getRemoteAddr(),
         request.getHeader("X-Forwarded-For"),
         ses.getAttribute("userName").toString());
     if (Validate.validateTokens(tokenCookie, tokenParmeter)) {
       ModulePlan.setOpenFloor();
       log.debug("Open Floor Plan enabled");
       out.write(
           "<h3 class='title'>Open Floor Plan Enabled</h3>"
               + "<p>Security Shepherd Users are now using an open floor plan. Refresh your browser to see these settings in effect.</p>");
     } else {
       out.write("Error Occurred!");
     }
   }
   log.debug("*** END servlets.Admin.SetOpenFloor ***");
 }
 /**
  * This method validates input and then attempts to update the cheat sheet for the specified
  * module
  *
  * @param newSolution The new solution to store as a cheat sheet
  * @param moduleId[] The identifier of the module to update.
  * @param csrfToken
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
   ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
   log.debug("*** servlets.Admin.CreateCheat ***");
   Encoder encoder = ESAPI.encoder();
   PrintWriter out = response.getWriter();
   out.print(getServletInfo());
   HttpSession ses = request.getSession(true);
   Cookie tokenCookie = Validate.getToken(request.getCookies());
   Object tokenParmeter = request.getParameter("csrfToken");
   if (Validate.validateAdminSession(ses, tokenCookie, tokenParmeter)) {
     ShepherdLogManager.setRequestIp(
         request.getRemoteAddr(),
         request.getHeader("X-Forwarded-For"),
         ses.getAttribute("userName").toString());
     log.debug("Current User: "******"userName").toString());
     if (Validate.validateTokens(tokenCookie, tokenParmeter)) {
       String errorMessage = null;
       String newSolution = request.getParameter("newSolution");
       log.debug("User submitted new solution - " + newSolution);
       String moduleId = request.getParameter("moduleId[]");
       log.debug("User submitted moduleId: " + moduleId);
       if (newSolution != null && !newSolution.isEmpty()) {
         String ApplicationRoot = getServletContext().getRealPath("");
         String moduleCheck = Getter.getModuleResult(ApplicationRoot, moduleId);
         if (moduleCheck != null) {
           if (!Setter.updateCheatSheet(
               ApplicationRoot, moduleId, encoder.encodeForHTML(newSolution)))
             errorMessage = "A database level error occurred. Please contact your administrator";
         } else {
           errorMessage = "Invalid Module submitted";
         }
       } else {
         errorMessage = "Invalid Module submitted";
       }
       String output = new String();
       if (errorMessage != null) {
         output =
             "<h2 class='title'>Create Cheat Sheet Failure</h2>"
                 + "<p>"
                 + encoder.encodeForHTML(errorMessage)
                 + "</p>";
       } else {
         output =
             "<h2 class='title'>Create Cheat Sheet Success</h2>"
                 + "<p>Cheat Sheet successfully created</p>";
       }
       out.write(output);
     }
   } else {
     out.write("<img src='css/images/loggedOutSheep.jpg'/>");
   }
   log.debug("*** END servlets.Admin.CreateCheat ***");
 }
 /**
  * Data is only validated on the client side. No Server Side Validation is Performed
  *
  * @param userdata data submitted by user
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
   ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
   // Attempting to recover username of session that made request
   HttpSession ses = request.getSession(true);
   if (Validate.validateSession(ses)) {
     ShepherdLogManager.setRequestIp(
         request.getRemoteAddr(),
         request.getHeader("X-Forwarded-For"),
         ses.getAttribute("userName").toString());
     log.debug(levelName + " servlet accessed by: " + ses.getAttribute("userName").toString());
     PrintWriter out = response.getWriter();
     out.print(getServletInfo());
     try {
       String userData = request.getParameter("userdata");
       log.debug("User Submitted - " + userData);
       String htmlOutput = new String();
       int userNumber = Integer.parseInt(userData);
       if (userNumber < 0) {
         // Get key and add it to the output
         String userKey =
             Hash.generateUserSolution(levelResult, (String) ses.getAttribute("userName"));
         log.debug("Negative Number Submitted");
         htmlOutput =
             "<h2 class='title'>Validation Bypassed</h2><p>You defeated the lesson validation. Result Key: <a>"
                 + userKey
                 + "</a></p>";
       } else {
         log.debug("Valid Number Submitted");
         htmlOutput =
             "<h2 class='title'>Valid Number Submitted</h2><p>The Number "
                 + userNumber
                 + " is a valid number.";
       }
       log.debug("Outputting HTML");
       out.write(htmlOutput);
     } catch (Exception e) {
       out.write("An Error Occurred! You must be getting funky!");
       log.fatal(levelName + " - " + e.toString());
     }
   } else {
     log.error(levelName + " servlet accessed with no session");
   }
 }
 /**
  * If this method is called by a valid administrator the FeebackStatus will be set to turn
  * feedback on for all modules
  *
  * @param csrfToken
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
   ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
   log.debug("*** servlets.Admin.config.EnableFeedback ***");
   PrintWriter out = response.getWriter();
   out.print(getServletInfo());
   HttpSession ses = request.getSession(true);
   if (Validate.validateAdminSession(ses)) {
     log.debug("Current User: "******"userName").toString());
     Cookie tokenCookie = Validate.getToken(request.getCookies());
     Object tokenParmeter = request.getParameter("csrfToken");
     if (Validate.validateTokens(tokenCookie, tokenParmeter)) {
       try {
         FeedbackStatus.setEnabled();
         out.print(
             "<h2 class=\"title\">Feedback Enabled</h2><br>"
                 + "<p>"
                 + "Users now have to submit a feedback form to complete a module."
                 + "<p>");
       } catch (Exception e) {
         log.error("Enable Feedback Error: " + e.toString());
         out.print(
             "<h2 class=\"title\">Enable Feedback Failure</h2><br>"
                 + "<p>"
                 + "<font color=\"red\">An error Occurred! Please try again.</font>"
                 + "<p>");
       }
     } else {
       log.debug("CSRF tokens did not match");
       out.print(
           "<h2 class=\"title\">Enable Feedback Failure</h2><br>"
               + "<p>"
               + "<font color=\"red\">An error Occurred! CSRF Tokens did not match.</font>"
               + "<p>");
     }
   } else {
     out.print(
         "<h2 class=\"title\">Enable Feedback Failure</h2><br>"
             + "<p>"
             + "<font color=\"red\">An error Occurred! Please log in or try non administrator functions!</font>"
             + "<p>");
   }
   log.debug("*** servlets.Admin.config.EnableFeedback END ***");
 }
 /**
  * Allows users to retrieve their CSRF token for the CSRF Challenge 6 module
  *
  * @param myMessage To Be stored as the users message for this module
  */
 public void doGet(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
   ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
   log.debug("Cross-SiteForegery Challenge Get Token Six Servlet");
   PrintWriter out = response.getWriter();
   out.print(getServletInfo());
   try {
     HttpSession ses = request.getSession(true);
     if (Validate.validateSession(ses)) {
       log.debug(levelName + " servlet accessed by: " + ses.getAttribute("userName").toString());
       String htmlOutput = new String("Your csrf Token for this Challenge is: ");
       String userId = request.getParameter("userId").toString();
       Encoder encoder = ESAPI.encoder();
       Connection conn =
           Database.getChallengeConnection(
               getServletContext().getRealPath(""), "csrfChallengeSix");
       try {
         log.debug("Preparing setCsrfChallengeSixToken call");
         PreparedStatement callstmnt =
             conn.prepareStatement(
                 "SELECT csrfTokenscol FROM csrfchallengesix.csrfTokens WHERE userId LIKE ?");
         callstmnt.setString(1, userId);
         log.debug("Executing setCsrfChallengeSixTokenQuery");
         ResultSet rs = callstmnt.executeQuery();
         int i = 0;
         while (rs.next()) {
           i++;
           htmlOutput += encoder.encodeForHTML("\"" + rs.getString(1) + "\"") + " <br/>";
         }
         log.debug("Returned " + i + " CSRF Tokens for ID: " + userId);
         conn.close();
       } catch (Exception e) {
         log.debug("Could not retrieve Challenge CSRF Tokens");
         htmlOutput = "Was unable to retrieve CSRF Token. Funky";
       }
       out.write(htmlOutput);
     }
   } catch (Exception e) {
     out.write("An Error Occurred! You must be getting funky!");
   }
 }
  /**
   * A user with the submitted email address is set a new random password, the password is also
   * returned from the database procedure and is forwards through to the HTTP response. This
   * response is not consumed by the client interface by default, and the user will have to discover
   * it.
   *
   * @param subEmail Sub schema user email address
   */
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
    ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
    HttpSession ses = request.getSession(true);

    // Translation Stuff
    Locale locale = new Locale(Validate.validateLanguage(request.getSession()));
    ResourceBundle errors = ResourceBundle.getBundle("i18n.servlets.errors", locale);
    ResourceBundle bundle =
        ResourceBundle.getBundle(
            "i18n.servlets.challenges.sessionManagement.sessionManagement2", locale);

    if (Validate.validateSession(ses)) {
      ShepherdLogManager.setRequestIp(
          request.getRemoteAddr(),
          request.getHeader("X-Forwarded-For"),
          ses.getAttribute("userName").toString());
      log.debug(levelName + " servlet accessed by: " + ses.getAttribute("userName").toString());
      PrintWriter out = response.getWriter();
      out.print(getServletInfo());
      Encoder encoder = ESAPI.encoder();
      String htmlOutput = new String();
      log.debug(levelName + " Servlet accessed");
      try {
        log.debug("Getting Challenge Parameter");
        Object emailObj = request.getParameter("subEmail");
        String subEmail = new String();
        if (emailObj != null) subEmail = (String) emailObj;
        log.debug("subEmail = " + subEmail);

        log.debug("Getting ApplicationRoot");
        String ApplicationRoot = getServletContext().getRealPath("");

        String newPassword = Hash.randomString();
        try {
          Connection conn =
              Database.getChallengeConnection(ApplicationRoot, "BrokenAuthAndSessMangChalTwo");
          log.debug("Checking credentials");
          PreparedStatement callstmt =
              conn.prepareStatement("UPDATE users SET userPassword = SHA(?) WHERE userAddress = ?");
          callstmt.setString(1, newPassword);
          callstmt.setString(2, subEmail);
          log.debug("Executing resetPassword");
          callstmt.execute();
          log.debug("Statement executed");

          log.debug("Committing changes made to database");
          callstmt = conn.prepareStatement("COMMIT");
          callstmt.execute();
          log.debug("Changes committed.");

          htmlOutput = encoder.encodeForHTML(newPassword);
          Database.closeConnection(conn);
        } catch (SQLException e) {
          log.error(levelName + " SQL Error: " + e.toString());
        }
        log.debug("Outputting HTML");
        out.write(bundle.getString("response.changedTo") + " " + htmlOutput);
      } catch (Exception e) {
        out.write(errors.getString("error.funky"));
        log.fatal(levelName + " - " + e.toString());
      }
    } else {
      log.error(levelName + " servlet accessed with no session");
    }
  }
  /**
   * System users are insecurely directed by their user name in a post request parameter. Users can
   * abuse this to retrieve an administrator's information.
   *
   * @param username User name of profile to retrieve
   */
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
    ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));

    // Translation Stuff
    Locale locale = new Locale(Validate.validateLanguage(request.getSession()));
    ResourceBundle errors = ResourceBundle.getBundle("i18n.servlets.errors", locale);
    ResourceBundle bundle = ResourceBundle.getBundle("i18n.servlets.lessons.directObject", locale);

    // Attempting to recover username of session that made request
    HttpSession ses = request.getSession(true);
    PrintWriter out = response.getWriter();
    out.print(getServletInfo());
    if (Validate.validateSession(ses)) {
      ShepherdLogManager.setRequestIp(
          request.getRemoteAddr(),
          request.getHeader("X-Forwarded-For"),
          ses.getAttribute("userName").toString());
      log.debug(levelName + " servlet accessed by: " + ses.getAttribute("userName").toString());
      try {
        String userName = request.getParameter("username");
        log.debug("User Submitted - " + userName);
        String ApplicationRoot = getServletContext().getRealPath("");
        log.debug("Servlet root = " + ApplicationRoot);
        String htmlOutput = new String();
        if (userName.equalsIgnoreCase("guest")) {
          log.debug("Guest Profile Found");
          htmlOutput = htmlGuest(bundle);
        } else if (userName.equalsIgnoreCase("admin")) {
          // Get key and add it to the output
          String userKey =
              Hash.generateUserSolution(levelResult, (String) ses.getAttribute("userName"));
          log.debug("Admin Profile Found");
          htmlOutput = htmlAdmin(bundle, userKey);
        } else {
          log.debug("No Profile Found");
          Encoder encoder = ESAPI.encoder();
          htmlOutput =
              "<h2 class='title'>"
                  + bundle.getString("response.user")
                  + ": "
                  + bundle.getString("response.notFound")
                  + "</h2><p>"
                  + bundle.getString("response.user")
                  + " '"
                  + encoder.encodeForHTML(userName)
                  + "' "
                  + bundle.getString("response.couldNotFind")
                  + ".</p>";
        }
        log.debug("Outputting HTML");
        out.write(htmlOutput);
      } catch (Exception e) {
        out.write(errors.getString("error.funky"));
        log.fatal("Insecure Direct Object Lesson Lesson - " + e.toString());
      }
    } else {
      out.write(errors.getString("error.noSession"));
      log.error(levelName + " servlet accessed with no session");
    }
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
    ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
    // Attempting to recover username of session that made request
    HttpSession ses = request.getSession(true);
    PrintWriter out = response.getWriter();
    out.print(getServletInfo());

    // Translation Stuff
    Locale locale = new Locale(Validate.validateLanguage(request.getSession()));
    ResourceBundle errors = ResourceBundle.getBundle("i18n.servlets.errors", locale);
    ResourceBundle bundle =
        ResourceBundle.getBundle("i18n.servlets.lessons.securityMisconfig", locale);

    if (Validate.validateSession(ses)) {
      ShepherdLogManager.setRequestIp(
          request.getRemoteAddr(),
          request.getHeader("X-Forwarded-For"),
          ses.getAttribute("userName").toString());
      log.debug(levelName + " servlet accessed by: " + ses.getAttribute("userName").toString());
      try {
        String userName = request.getParameter("userName");
        log.debug("User Name - " + userName);
        String userPass = request.getParameter("userPass");
        log.debug("User Pass - " + userName);
        boolean loggedIn = userName.contentEquals("admin") && userPass.contentEquals("password");
        String htmlOutput = new String();
        if (!loggedIn) {
          if (userName.contentEquals("admin"))
            htmlOutput = bundle.getString("response.incorrectPassword");
          else {
            Encoder encoder = ESAPI.encoder();
            htmlOutput =
                bundle.getString("response.noUserFound")
                    + " \""
                    + encoder.encodeForHTML(userName)
                    + "\"";
          }
          htmlOutput =
              "<h2 class='title'>"
                  + bundle.getString("response.authError")
                  + "</h2><p>"
                  + htmlOutput
                  + "</p>";
        } else {
          // Default username and password were used
          log.debug("User has signed in as admin");
          htmlOutput =
              "<h2 class='title'>"
                  + bundle.getString("response.authSuccess")
                  + "</h2><p>"
                  + bundle.getString("result.youDidIt")
                  + "<br><br>"
                  + bundle.getString("result.key")
                  + ": <a>"
                  + Hash.generateUserSolution(levelResult, ses.getAttribute("userName").toString())
                  + "</a>";
        }
        log.debug("Outputting HTML");
        out.write(htmlOutput);
      } catch (Exception e) {
        out.write(errors.getString("error.funky"));
        log.fatal(levelName + " - " + e.toString());
      }
    } else {
      log.error(levelName + " servlet accessed with no session");
      out.write(bundle.getString("error.noSession"));
    }
  }
  /**
   * Cross Site Request Forgery safe Reflected XSS vulnerability. cannot be remotely exploited, and
   * there fore only is executable against the person initiating the function.
   *
   * @param searchTerm To be spat back out at the user after been encoded for wrong HTML Context
   */
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
    ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
    log.debug("Cross-Site Scripting Challenge Four Servlet");
    PrintWriter out = response.getWriter();
    out.print(getServletInfo());

    // Translation Stuff
    Locale locale = new Locale(Validate.validateLanguage(request.getSession()));
    ResourceBundle errors = ResourceBundle.getBundle("i18n.servlets.errors", locale);
    ResourceBundle bundle = ResourceBundle.getBundle("i18n.servlets.challenges.xss.xss4", locale);

    try {
      HttpSession ses = request.getSession(true);
      if (Validate.validateSession(ses)) {
        ShepherdLogManager.setRequestIp(
            request.getRemoteAddr(),
            request.getHeader("X-Forwarded-For"),
            ses.getAttribute("userName").toString());
        log.debug(levelName + " servlet accessed by: " + ses.getAttribute("userName").toString());
        Cookie tokenCookie = Validate.getToken(request.getCookies());
        Object tokenParmeter = request.getParameter("csrfToken");
        if (Validate.validateTokens(tokenCookie, tokenParmeter)) {
          String htmlOutput = new String();
          String userPost = new String();
          String searchTerm = request.getParameter("searchTerm");
          log.debug("User Submitted - " + searchTerm);
          if (!searchTerm.startsWith("http")) {
            searchTerm = "https://www.owasp.org/index.php/OWASP_Security_Shepherd";
            userPost =
                "<a href=\""
                    + searchTerm
                    + "\" alt=\"OWASP Security Shepherd\">"
                    + searchTerm
                    + "</a>";
          } else {

            searchTerm = XssFilter.encodeForHtml(searchTerm);
            userPost =
                "<a href=\"" + searchTerm + "\" alt=\"" + searchTerm + "\">" + searchTerm + "</a>";
            log.debug("After Encoding - " + searchTerm);
            if (FindXSS.search(userPost)) {
              htmlOutput =
                  "<h2 class='title'>"
                      + bundle.getString("result.wellDone")
                      + "</h2>"
                      + "<p>"
                      + bundle.getString("result.youDidIt")
                      + "<br />"
                      + bundle.getString("result.resultKey")
                      + " <a>"
                      + Hash.generateUserSolution(
                          Getter.getModuleResultFromHash(
                              getServletContext().getRealPath(""), levelHash),
                          (String) ses.getAttribute("userName"))
                      + "</a>";
            }
          }
          log.debug("Adding searchTerm to Html: " + searchTerm);
          htmlOutput +=
              "<h2 class='title'>"
                  + bundle.getString("response.yourPost")
                  + "</h2>"
                  + "<p>"
                  + bundle.getString("response.linkPosted")
                  + "</p> "
                  + userPost
                  + "</p>";
          out.write(htmlOutput);
        }
      } else {
        log.error(levelName + " servlet was accessed without a valid session");
        out.write(errors.getString("error.noSession"));
      }
    } catch (Exception e) {
      out.write(errors.getString("error.funky"));
      log.fatal("Cross Site Scripting Challenge 4 - " + e.toString());
    }
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
    ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
    log.debug("&&& servlets.module.SolutionSubmit &&&");
    PrintWriter out = response.getWriter();
    out.print(getServletInfo());
    HttpSession ses = request.getSession(true);
    if (Validate.validateSession(ses)) {
      ShepherdLogManager.setRequestIp(
          request.getRemoteAddr(),
          request.getHeader("X-Forwarded-For"),
          ses.getAttribute("userName").toString());
      log.debug("Current User: "******"userName").toString());
      Cookie tokenCookie = Validate.getToken(request.getCookies());
      Object tokenParmeter = request.getParameter("csrfToken");
      if (Validate.validateTokens(tokenCookie, tokenParmeter)) {
        boolean notNull = false;
        String storedResult = null;
        try {
          log.debug("Getting ApplicationRoot");
          String ApplicationRoot = getServletContext().getRealPath("");
          log.debug("Servlet root = " + ApplicationRoot);

          log.debug("Getting Parameters");
          String moduleId = (String) request.getParameter("moduleId");
          ;
          log.debug("moduleId = " + moduleId.toString());
          String solutionKey = (String) request.getParameter("solutionKey");
          ;
          log.debug("solutionKey = " + solutionKey.toString());

          log.debug("Getting session parameters");
          String userId = (String) ses.getAttribute("userStamp");
          String userName = (String) ses.getAttribute("userName");
          log.debug("userId = " + userId);

          // Validation
          notNull = (moduleId != null && solutionKey != null);
          if (notNull) {
            storedResult = Getter.getModuleResult(ApplicationRoot, moduleId);
          }
          if (notNull && storedResult != null) {
            boolean validKey = false;
            // Identify if solution is a user Specific key (Does it need to be decrypted?)
            if (Getter.getModuleKeyType(ApplicationRoot, moduleId))
              validKey = storedResult.compareTo(solutionKey) == 0;
            else {
              String decryptedKey = new String();
              try {
                // Encrypted Solution key,  must be decrypted before compare
                decryptedKey =
                    Hash.decryptUserSpecificSolution(
                        Validate.validateEncryptionKey(userName), solutionKey);
              } catch (Exception e) {
                log.error("Could not decrypt result key: " + e.toString());
                // Key likely could not be decrypted because somebody submitted a string that could
                // not be decrypted.
                // This is a bad submission so they should be warned. String will continue from this
                // point as an empty value and will cause the function to run the Bad Submission
                // procedure
              }
              storedResult +=
                  Hash.getCurrentSalt(); // Add server solution salt to base key before compare with
              // decrypted key
              validKey = storedResult.compareTo(decryptedKey) == 0;
              log.debug("Decrypted Submitted Key: " + decryptedKey);
              log.debug("Stored Expected Key    : " + storedResult);
            }
            if (validKey) {
              log.debug("Correct key submitted, checking that module not already completed");
              String result = Getter.checkPlayerResult(ApplicationRoot, moduleId, userId);
              if (result != null) {
                // If Feedback is enabled, the user must complete another step. This step is
                // continued in FeedbackSubmit.java
                if (FeedbackStatus.isEnabled()) {
                  log.debug("Returning Feedback Form for module: " + result);
                  out.write(
                      "<h2 class=\"title\">Solution Submission Success</h2><br>"
                          + "<p> You are one step away from completing <a>"
                          + encoder.encodeForHTML(result)
                          + "</a>! To complete the level please submit your feedback!"
                          + "</p><br/>"
                          + generateFeedbackForm(moduleId, (String) tokenParmeter, solutionKey));
                } else // Feedback is disabled
                {
                  log.debug("Feedback is disabled, Marking as completed");
                  String htmlOutput = new String();
                  result =
                      Setter.updatePlayerResult(
                          ApplicationRoot, moduleId, userId, "Feedback is Disabled", 1, 1, 1);
                  if (result != null) {
                    ResourceBundle bundle =
                        ResourceBundle.getBundle(
                            "i18n.moduleGenerics.moduleNames",
                            new Locale(Validate.validateLanguage(request.getSession())));
                    String compltedModuleLocalName = bundle.getString(result);
                    log.debug(
                        "Solution Submission for module " + compltedModuleLocalName + " succeeded");
                    htmlOutput =
                        new String(
                            "<h2 class=\"title\">Solution Submission Success</h2><br>"
                                + "<p>"
                                + compltedModuleLocalName
                                + " completed! Congratulations.");
                    htmlOutput += "</p>";
                    // Refresh Side Menu
                    htmlOutput +=
                        FeedbackSubmit.refreshMenuScript(
                            encoder.encodeForHTML((String) tokenParmeter), "Refresh Error");
                    log.debug("Resetting user's Bad Submisison count to 0");
                    Setter.resetBadSubmission(ApplicationRoot, userId);
                    out.write(htmlOutput);
                  } else {
                    htmlOutput = new String("Could not update user result");
                    out.print(
                        "<h2 class=\"title\">Solution Submission Failure</h2><br>"
                            + "<p><font color=\"red\">"
                            + "Sorry but an error Occurred!"
                            + "</font></p>");
                  }
                }
              } else {
                log.error("User has completed this module before. Returning Error");
                out.write(
                    "<h2 class=\"title\">Haven't You Done This Already?</h2><br>"
                        + "<p>"
                        + "Our records say you have already completed this module! Go try another one!"
                        + "</p>");
              }
            } else {
              log.error("Incorrect key submitted, returning error");
              out.print(
                  "<h2 class=\"title\">Solution Submission Failure</h2><br>"
                      + "<p><font color=\"red\">"
                      + "Incorrect Solution Key Submitted.<br><br>You have limited amounts of incorrect key submissions before you will loose 10% of your points. Contact the OWASP Security Shepherd if you think you have found the correct key but it is failing you."
                      + "</font></p>");

              log.error("Invoking Bad Submission procedure...");
              Setter.incrementBadSubmission(ApplicationRoot, userId);
              log.error(userName + " has been warned and potentially has lost points");
            }
          } else {
            // Validation Error Responses
            String errorMessage = "An Error Occurred: ";
            if (!notNull) {
              log.error("Null values detected");
              errorMessage += "Invalid Request. Please try again";
            } else if (storedResult == null) {
              log.error("Module not found");
              errorMessage += "Module Not Found. Please try again";
            }
            out.print(
                "<h2 class=\"title\">Solution Submission Failure</h2><br>"
                    + "<p><font color=\"red\">"
                    + encoder.encodeForHTML(errorMessage)
                    + "</font><p>");
          }
        } catch (Exception e) {
          log.error("Solution Submission Error: " + e.toString());
          out.print(
              "<h2 class=\"title\">Solution Submission Failure</h2><br>"
                  + "<p>"
                  + "<font color=\"red\">An error Occurred! Please try again.</font>"
                  + "<p>");
        }
      } else {
        log.debug("CSRF Tokens did not match");
        out.print(
            "<h2 class=\"title\">Solution Submission Failure</h2><br>"
                + "<p>"
                + "<font color=\"red\">An error Occurred! Please try again.</font>"
                + "<p>");
      }
    } else {
      out.print(
          "<h2 class=\"title\">Solution Submission Failure</h2><br>"
              + "<p>"
              + "<font color=\"red\">An error Occurred! Please Log in!</font>"
              + "<p>");
    }
    log.debug("&&& END SolutionSubmit &&&");
  }
  /**
   * Shopping cart addition algorithm is vulnerable to integer overflow. If the cost is high enough,
   * the final value will go negative.
   */
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
    ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
    HttpSession ses = request.getSession(true);
    if (Validate.validateSession(ses)) {
      // Translation Stuff
      Locale locale = new Locale(Validate.validateLanguage(request.getSession()));
      ResourceBundle bundle =
          ResourceBundle.getBundle(
              "i18n.servlets.challenges.poorValidation.poorValidationStrings", locale);

      String currentUser = ses.getAttribute("userName").toString();
      ShepherdLogManager.setRequestIp(
          request.getRemoteAddr(), request.getHeader("X-Forwarded-For"), currentUser);
      log.debug(levelName + " servlet accessed by: " + ses.getAttribute("userName").toString());
      PrintWriter out = response.getWriter();
      out.print(getServletInfo());
      String htmlOutput = new String();
      try {
        int megustaAmount = validateAmount(Integer.parseInt(request.getParameter("megustaAmount")));
        log.debug("megustaAmount - " + megustaAmount);
        int trollAmount = validateAmount(Integer.parseInt(request.getParameter("trollAmount")));
        log.debug("trollAmount - " + trollAmount);
        int rageAmount = validateAmount(Integer.parseInt(request.getParameter("rageAmount")));
        log.debug("rageAmount - " + rageAmount);
        int notBadAmount = validateAmount(Integer.parseInt(request.getParameter("notBadAmount")));
        log.debug("notBadAmount - " + notBadAmount);

        // Working out costs
        int megustaCost = megustaAmount * 30;
        int trollCost = trollAmount * 3000;
        int rageCost = rageAmount * 45;
        int notBadCost = notBadAmount * 15;

        htmlOutput = new String();

        // Work Out Final Cost
        int finalCost = megustaCost + rageCost + notBadCost + trollCost;

        // Output Order
        htmlOutput =
            "<h3 class='title'>"
                + bundle.getString("poorValidation.orderComplete")
                + "</h3>"
                + "<p>"
                + bundle.getString("poorValidation.orderComplete.message")
                + "</p><br/>"
                + "<p>"
                + bundle.getString("poorValidation.orderTotal")
                + " <a><strong>$"
                + finalCost
                + "</strong></a></p>";
        if (finalCost <= 0 && trollAmount > 0) {
          htmlOutput +=
              "<br><p>"
                  + bundle.getString("poorValidation.freeTrolls")
                  + " - "
                  + Hash.generateUserSolution(levelSolution, currentUser)
                  + "</p>";
        }
      } catch (Exception e) {
        log.debug("Didn't complete order: " + e.toString());
        htmlOutput += "<p>" + bundle.getString("poorValidation.badOrder") + "</p>";
      }
      try {
        Thread.sleep(1000);
      } catch (Exception e) {
        log.error("Failed to Pause: " + e.toString());
      }
      out.write(htmlOutput);
    } else {
      log.error(levelName + " servlet accessed with no session");
    }
  }
  /**
   * Uses user input in an insecure fashion when executing queries in database. Vulnerable to SQL
   * injection.
   *
   * @param aUserName User submitted filter for database results
   */
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
    PrintWriter out = response.getWriter();
    out.print(getServletInfo());

    // Translation Stuff
    Locale locale = new Locale(Validate.validateLanguage(request.getSession()));
    ResourceBundle errors = ResourceBundle.getBundle("i18n.servlets.errors", locale);
    ResourceBundle bundle = ResourceBundle.getBundle("i18n.servlets.lessons.sqlInjection", locale);

    try {
      HttpSession ses = request.getSession(true);
      if (Validate.validateSession(ses)) {
        ShepherdLogManager.setRequestIp(
            request.getRemoteAddr(),
            request.getHeader("X-Forwarded-For"),
            ses.getAttribute("userName").toString());
        log.debug(levelName + " servlet accessed by: " + ses.getAttribute("userName").toString());
        String aUserName = request.getParameter("aUserName");
        log.debug("User Submitted - " + aUserName);
        String ApplicationRoot = getServletContext().getRealPath("");
        log.debug("Servlet root = " + ApplicationRoot);
        String[][] output = getSqlInjectionResult(ApplicationRoot, aUserName);
        log.debug("output returned. [0][0] is " + output[0][0]);
        String htmlOutput =
            "<h2 class='title'>" + bundle.getString("response.searchResults") + "</h2>";
        if (output[0][0] == null) {
          htmlOutput += "<p>" + bundle.getString("response.noResults") + "</p>";
        } else if (output[0][0].equalsIgnoreCase("error")) {
          log.debug("Setting Error Message");
          htmlOutput +=
              "<p>" + errors.getString("error.detected") + "</p>" + "<p>" + output[0][1] + "</p>";
        } else {
          log.debug("Adding table");
          int i = 0;
          log.debug("outputLength = " + output.length);
          htmlOutput +=
              "<table><tr><th>"
                  + bundle.getString("response.userId")
                  + "</th><th>"
                  + bundle.getString("response.userName")
                  + "</th><th>"
                  + bundle.getString("response.comment")
                  + "</th></tr>";
          do {
            log.debug("Adding User " + output[i][1]);
            htmlOutput +=
                "<tr><td>"
                    + output[i][0]
                    + "</td><td>"
                    + output[i][1]
                    + "</td><td>"
                    + output[i][2]
                    + "</td></tr>";
            i++;

          } while (i < output.length && output[i][0] != null);
          htmlOutput += "</table>";
        }
        log.debug("Outputting HTML");
        out.write(htmlOutput);
      } else {
        log.error(levelName + " accessed with no session");
        out.write(errors.getString("error.noSession"));
      }
    } catch (Exception e) {
      out.write(errors.getString("error.funky"));
      log.fatal(levelName + " - " + e.toString());
    }
  }
  /**
   * Initiated by index.jsp, getStarted.jsp. This changes a users password. If the user gets it
   * wrong 3 times in a row, they'll be locked out (This is handed by database)
   *
   * @param csrfToken
   * @param currentPassword User's current password
   * @param newPassword Submitted new password
   * @param passwordConfirmation Confirmation of the new password
   */
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Setting IpAddress To Log and taking header for original IP if forwarded from proxy
    ShepherdLogManager.setRequestIp(request.getRemoteAddr(), request.getHeader("X-Forwarded-For"));
    log.debug("*** servlets.ChangePassword ***");
    try {
      HttpSession ses = request.getSession(true);
      if (Validate.validateSession(ses)) {
        ShepherdLogManager.setRequestIp(
            request.getRemoteAddr(),
            request.getHeader("X-Forwarded-For"),
            ses.getAttribute("userName").toString());
        log.debug("Current User: "******"userName").toString());
        Cookie tokenCookie = Validate.getToken(request.getCookies());
        Object tokenParmeter = request.getParameter("csrfToken");
        if (Validate.validateTokens(tokenCookie, tokenParmeter)) {
          log.debug("Getting Parameters");
          String userName = (String) ses.getAttribute("userName");
          String currentPassword = (String) request.getParameter("currentPassword");
          String newPassword = (String) request.getParameter("newPassword");
          String passwordConfirm = (String) request.getParameter("passwordConfirmation");
          String ApplicationRoot = getServletContext().getRealPath("");

          boolean validData = false;
          boolean passwordChange = false;
          boolean validPassword = false;
          validData =
              newPassword.equalsIgnoreCase(passwordConfirm)
                  && !newPassword.isEmpty()
                  && newPassword != null;
          passwordChange = !currentPassword.equalsIgnoreCase(newPassword);
          validPassword = newPassword.length() > 4 && newPassword.length() <= 512;
          if (validData && passwordChange && validPassword) {
            log.debug("Validating Current Password");
            String user[] = Getter.authUser(ApplicationRoot, userName, currentPassword);
            if (user != null) {
              log.debug("User Credentials were good! Password Change gets the go ahead");
              Setter.updatePassword(ApplicationRoot, userName, currentPassword, newPassword);
              ses.setAttribute("ChangePassword", "false");
            } else {
              log.error("Incorrect Password");
              ses.setAttribute("errorMessage", "Incorrect Password... Don't lock yourself out!");
              response.sendRedirect("index.jsp");
            }
          } else {
            if (validData && passwordChange) {
              try {
                // User Account is Locked
                log.debug("The user account is locked. Logging the user out");
                Cookie cookieToken = Validate.getToken(request.getCookies());
                BigInteger temp = new BigInteger(cookieToken.getValue());
                response.sendRedirect("logout?csrfToken=" + temp);
              } catch (Exception e) {
                log.error(
                    "Cant Log the user out because they dont have a valid CSRF token : "
                        + e.toString());
                response.sendRedirect("login.jsp");
              }
            }
            // Return error message
            else if (!validData) {
              log.error("Bad Data Received");
              ses.setAttribute("errorMessage", "Invalid Request! Please try again.");
            } else if (!validPassword) {
              log.error("Invalid Password Submitted (Too Short/Long)");
              ses.setAttribute("errorMessage", "Invalid Password! Please try again.");
            } else {
              log.error("No password Change Detected");
              ses.setAttribute(
                  "errorMessage", "You have to CHANGE your password! Please try again.");
            }
          }
        } else {
          log.error("CSRF Attack Detected");
        }
      } else {
        log.error("Change Password Function Called with no valid session");
        response.sendRedirect("login.jsp");
      }
    } catch (Exception e) {
      log.fatal("ChangePassword Error: " + e.toString());
    }
    log.debug("*** END ChangePassword ***");
    response.sendRedirect("index.jsp");
  }