-1

I'm trying to write a login() and connection() function for a library management system connected to MYSQL. When I try to retrieve "personnummer" and "password" from the database it returns rs.Next() == false. The table is populated and the query is returning "database connected". Can anyone help me figure out what I've done wrong? Thanks

  public class main {

    public static void login() {                    

         //UI layer has been removed 

        loginButton.addActionListener(new ActionListener(){  

            public void actionPerformed(ActionEvent e){ 
                String personnummer = F_personnummer.getText();                      
                char[] password = F_password.getPassword();                         

                if(personnummer.equals("")){                                                             
                   JOptionPane.showMessageDialog(null,"Please enter personnummer (YYMMDDXXXX)");    
                } else if (password.equals("")){                                        
                    JOptionPane.showMessageDialog(null,"Please enter password"); 
                } else {                                             
                    try {                                                                                    
                        Connection connection=connect(); 
                        Statement stmt = connection.createStatement();  
                        stmt.executeUpdate("USE library");              

                        PreparedStatement loginQuery = connection.prepareStatement("SELECT * FROM library.users WHERE personnummer = " + "'" + personnummer + "'" + " AND password ='" + password + "'", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

                        ResultSet rs = loginQuery.executeQuery();

                        if(rs.next()==false) {
                              JOptionPane.showMessageDialog(null,                                                       
                        } else {
                              jframe.dispose();
                              rs.beforeFirst();
                              while(rs.next()) {                                                                                                                     
                                    if(personnummer.equals("admin") & password.equals("admin")) {
                                         adminMenu();                                                               
                                    } else {
                                         userMenu(personnummer);                                                                                     
                                    } 
                              }     // end while ()
                        }           // end else ()
                    }               // end try ()                               

                    catch (Exception exception) { 
                         exception.printStackTrace();
                    }       
                }       
            }               
        });                 

          // UI layer has been removed 
    }   

    public static Connection connect() throws Exception{
        try{
            String driver = "com.mysql.cj.jdbc.Driver";
            String url = "jdbc:mysql://localhost:3306/library?useTimezone=true&serverTimezone=UTC";
            String username = "root";
            String password = "root";
            Class.forName(driver);

            Connection connection = DriverManager.getConnection(url,username,password);
            System.out.println("Connected to database");
            return connection;
        }
            catch (Exception exception) {
                    System.out.println(exception);
            }

        return null;
    }
Ananas
  • 17
  • 3
  • 2
    You should post a [mre]. – khelwood May 20 '20 at 13:35
  • 1
    If your are sure that your question is about `JDBC` please isolate this part of your code (remove UI layer). – PM 77-1 May 20 '20 at 13:37
  • I'm not sure what the problem is, I am a complete beginner so I wasn't sure how much you guys would need to see. – Ananas May 20 '20 at 13:56
  • It is general bad practice to directly input any user input into an SQL statement. It can be abused using "SQL Injection". Please use the `setString` method as shown [here](https://stackoverflow.com/questions/4333015/does-the-preparedstatement-avoid-sql-injection) – BurningKarl May 20 '20 at 23:28

1 Answers1

1

insecure code

This code is a security leak; I could, for example, enter this for a password: whatever'; DROP TABLE library.users; -- - and upon entering that in the password box on your login form, your database table would go up in smoke. The solution is to use PreparedStatement; SQL queries must always be a single long string constant, you can NEVER mix user input into it. You already have PreparedStatement in there - just replace all those strings with question marks:

PreparedStatement loginQuery = connection.prepareStatement("SELECT * FROM library.users WHERE personnummer = ? AND password = ?", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
loginQuery.setString(1, personnummer);
loginQuery.setString(2, password);

insecure code - reprise

You should use bcrypt, scrypt, pbkdf2, or some other password hash algorithm; this is insecure to your users (your laptop with a clone of the db ends up on the street, and now all your user's passwords are on the street. Users tend to reuse passwords. In general industry as a whole, and various laws such as the GDPR in particular, lay the blame squarely on your feet. Including with hefty fines. Don't break with industry standards - use a password hasher.

your actual bug

you are concatening the 'password' variable into a string. This calls toString on the variable. The variable is a char array, which doesn't toString the way you think it does. Your query ends up as: SELECT * FROM whatever WHERE password = '[C@1234567' - try it. Print that string.

Combining the fixes

ps.setString(2, new String(password)).

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72