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

huangapple go评论66阅读模式
英文:

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

问题

以下是您提供的内容的翻译:

"Just a note, this is for class. I would go to the class material, but it doesn't address this (the school is kinda garbage). And when I ask the teacher, he says to google it.
I've tried googling it, but my understanding is not good enough yet sadly.

My setup is as follows. It's a web application that uses DerbyDB, Glassfish 5, Java, and JavaScript servlets.

I am a bit lost on using Prepared Statements.
My Authentication Java code has an SQL injection vulnerability, and I am trying to solve it. Everyone says to use Prepared Statements, so I am trying.
My code is below. This is how it works though. It checks the usernames (an email) that was input to the user_id from the sdev_users table. Then it takes the user_id and checks it in the user_info table to the password stored under the user_id to see if it matches.

The prepared statements are at the bottom, but I figured y'all would like to see the full thing, just in case!
Authenticate.java"

请注意,上述内容已经翻译完成。

英文:

Just a note, this is for class. I would go to the class material, but it doesn't address this(the school is kinda garbage). And when i ask the teacher, he says to google it.
I've tried googling it, but my understanding is not good enough yet sadly.

My setup is as follows. Its a web application that uses DerbyDB, Glassfish 5, Java and javascript servlets.

I am a bit lost on using Prepared Statements.
My Authentication java code has an sql inject vulnerability and i am trying to solve it. Everyone says to use PreparedStatements, so i am trying.
My code is below. This is how it works though. It checks the usernames(an email)that was input to the user_id from thesdev_users table. then it takes the user_id and checks it in user_info table to the password stored under the user_id to see if it matches.

The prepared statements are at the bottom, but i figured yall would like to see the full thing, just in case!
Authenticate.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;
    }

}

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

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

答案1

得分: 2

任何用户输入都应视为“污染”。这可能是企图入侵您的尝试。

这意味着每当您将用户输入直接作为代码运行时,您实际上已经把您的服务器交给了任何想要的人。

您在此代码中已经“搞砸”了两次。

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

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

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

rzwitserloot <script>/* 哈哈,在这里做一些恶意操作 */

然后我就得手了。

您需要_转义_这些内容。获取一个HTML转义器,将所有不安全的输入都通过这个转义器处理一遍。

接下来是SQL语句。

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

很好。我将使我的用户名为whatever';-- DROP TABLE sdev_users;,然后毁掉你的一天。

这是您如何使用预处理语句来转义字符串:

String sql = "select user_id from sdev_users where email = ?";
// 注意:传递给prepareStatement的字符串必须始终是常量。
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, email); // 这会安全地替换第一个(1)个问号(?)。
英文:

Any user input is to be considered 'tainted'. It may be an attempt to hack your stuff.

That means anytime you just run user input as code, you've basically handed your server over to whomever wants.

You've messed this up TWICE in this code.

First time is in your HTML response:

out.println(&quot;&lt;h1&gt;Results are &quot; + username + &quot;,&quot; + isValid +&quot;,&quot; +user_id +&quot;,&quot; +this.username + &quot;&lt;/h1&gt;&quot;);
            out.println(&quot;&lt;/body&gt;&quot;);

okay. I shall make a new user account, and make my username:

rzwitserloot &lt;script&gt;/* haha do evil things here */

and I got you.

You need to escape these things. Get an HTML escaper and throw all unsafe input through this.

Next one is the SQL statement.

String sql = &quot;select user_id from sdev_users  where email = &#39;&quot; + this.username + &quot;&#39;&quot;;

Cool. I'm gonna make my username whatever&#39;;-- DROP TABLE sdev_users; and ruin your day.

This is how you use preparedstatement to escape strings:

String sql = &quot;select user_id from sdev_users  where email = ?&quot;;
// 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.

huangapple
  • 本文由 发表于 2020年8月10日 10:52:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/63333504.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定