繁体   English   中英

我对如何使用 Java 和 Derby sql 服务器使用 PreparedStatements 感到困惑

[英]I am confused on how to use PreparedStatements using Java and Derby sql server

请注意,这是针对 class 的。 我会 go 到 class 材料,但它没有解决这个问题(学校有点垃圾)。 当我问老师时,他说用谷歌搜索。 我试过用谷歌搜索它,但遗憾的是我的理解还不够好。

我的设置如下。 它是一个 web 应用程序,它使用 DerbyDB、Glassfish 5、Java 和 javascript Z43468E1058EE6E0CED149Z。

我对使用准备好的语句有点迷茫。 我的身份验证 java 代码有一个 sql 注入漏洞,我正在尝试解决它。 每个人都说要使用 PreparedStatements,所以我正在尝试。 我的代码如下。 这就是它的工作原理。 它检查从 sdev_users 表输入到 user_id 的用户名(电子邮件)。 然后它获取 user_id 并将其在 user_info 表中检查到存储在 user_id 下的密码,以查看它是否匹配。

准备好的陈述在底部,但我想你们希望看到完整的东西,以防万一。 验证.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package SDEV425_HW4;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.derby.jdbc.ClientDataSource;

/**
 *
 * @author jim
 */
public class Authenticate extends HttpServlet {

    // variables    
    private String username;
    private String pword;
    private Boolean isValid;
    private int user_id;
    private HttpSession session;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet Authenticate</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet Authenticate at " + request.getContextPath() + "</h1>");
            out.println("<h1>Results are " + username + "," + isValid +"," +user_id +"," +this.username + "</h1>");
            out.println("</body>");
            out.println("</html>");
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // Get the post input 
        this.username = request.getParameter("emailAddress");
        this.pword = request.getParameter("pfield");
        this.isValid = validate(this.username, this.pword);
         response.setContentType("text/html;charset=UTF-8");
        // Set the session variable
        if (isValid) {
            // Create a session object if it is already not  created.
            session = request.getSession(true);
            session.setAttribute("UMUCUserEmail", username);         
            session.setAttribute("UMUCUserID", user_id);

            // Send to the Welcome JSP page              
            
            RequestDispatcher dispatcher = request.getRequestDispatcher("welcome.jsp");
            dispatcher.forward(request, response);

        } else {
            // Not a valid login
            // refer them back to the Login screen

            request.setAttribute("ErrorMessage", "Invalid Username or Password. Try again or contact Jim.");
            RequestDispatcher dispatcher = request.getRequestDispatcher("login.jsp");
            dispatcher.forward(request, response);
        }
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    // Method to Authenticate
    public boolean validate(String name, String pass) {
        boolean status = false;
        int hitcnt=0;

        try {
            ClientDataSource ds = new ClientDataSource();
            ds.setDatabaseName("SDEV425");
            ds.setServerName("localhost");
            ds.setPortNumber(1527);
            ds.setUser("sdev425");
            ds.setPassword("sdev425");
            ds.setDataSourceName("jdbc:derby");

            Connection conn = ds.getConnection();

            
            String sql = "select user_id from sdev_users  where email = '" + this.username + "'";
            PreparedStatement stmt = conn.prepareStatement(sql);
            stmt.setInt(user_id, 0);
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                user_id = rs.getInt(1);
            }
            if (user_id > 0) {                
                String sql2 = "select user_id from user_info where user_id = " + user_id + "and password = '" + this.pword + "'";
                PreparedStatement stmt2 = conn.prepareStatement(sql2);
                stmt2.setString(user_id, pword);
                ResultSet rs2 = stmt2.executeQuery(sql2);
                while (rs2.next()) {
                    hitcnt++;
                }   
                // Set to true if userid/password match
               if(hitcnt>0){
                   status=true;
               }
            }

        } catch (Exception e) {
            System.out.println(e);
        }
        return status;
    }

}

sdev_users

用户信息

任何用户输入都将被视为“污染”。 这可能是试图破解你的东西。

这意味着只要您将用户输入作为代码运行,您基本上就已经将您的服务器交给了任何想要的人。

你在这段代码中把这搞砸了两次

第一次是在您的 HTML 响应中:

out.println("<h1>Results are " + username + "," + isValid +"," +user_id +"," +this.username + "</h1>");
            out.println("</body>");

好的。 我将创建一个新的用户帐户,并设置我的用户名:

rzwitserloot <script>/* haha do evil things here */

我得到了你。

你需要逃避这些东西。 获取一个 HTML 转义器并通过它抛出所有不安全的输入。

下一个是 SQL 语句。

String sql = "select user_id from sdev_users  where email = '" + this.username + "'";

凉爽的。 我要让我的用户名whatever';-- DROP TABLE sdev_users; 毁了你的一天。

这是您使用preparedstatement转义字符串的方式:

String sql = "select user_id from sdev_users  where email = ?";
// Note: The string you feed to prepareStatement must ALWAYS be a constant.
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, email); // this replaces the first (1) ?. Safely.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM