java - 使登录容易受到 SQL 注入(inject)登录绕过攻击

标签 java mysql netbeans sql-injection

我正在开展一个有关 SQL 注入(inject)的学校项目。我创建了自己的 Netbeans 登录表单来显示通过 SQL 注入(inject)绕过登录。我用这个youtube视频作为引用https://www.youtube.com/watch?v=3vauM7axnRs因为这是我第一次使用 Netbeans 或任何数据库构建。该表单有效,我制作了虚假的登录凭据,但我尚未成功绕过该表单。我相信这是因为我正在使用prepareStatement来防止攻击。

import java.awt.Color;
*import java.sql.PreparedStatement;*
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

private void jButton_LoginActionPerformed(java.awt.event.ActionEvent evt) {                                              

    PreparedStatement st;
    ResultSet rs;

    //get username & password

    String username = jTextField1.getText();
    String password = String.valueOf(jPasswordField1.getPassword());

    //make sure username and passord are from query
    String query = "SELECT * FROM `users` WHERE `username` = ? AND `password` = ?";

   // show a message if the username or the password fields are empty
    if(username.trim().equals("username"))
    {
        JOptionPane.showMessageDialog(null, "Enter Your Username", "Empty 
    Username", 2);
    }
    else if(password.trim().equals("password"))
    {
        JOptionPane.showMessageDialog(null, "Enter Your Password", "Empty 
    Password", 2);
    }
    else{
    try {
        st = My_CNX.getConnection().prepareStatement(query);

        st.setString(1, username);
        st.setString(2, password);
        rs = st.executeQuery();

        if(rs.next())
        {
            //show new form
            Main_Menu form  = new Main_Menu();
            form.setVisible(true);
            form.pack();
            form.setLocationRelativeTo(null);
            //close the current form (login_form)

            this.dispose();

        }
        else{
            // error message
            JOptionPane.showMessageDialog(null, "Invalid Username / 
    Password","Login Error",2);
        }

    }


     catch (SQLException ex) {
        Logger.getLogger(Login_Form.class.getName()).log(Level.SEVERE, null, ex);
    }
    }

我在网上查看了一些示例,其中使用了常规的 Statement 和 createStatement,这很容易受到 SQL 注入(inject)攻击。我更改了prepareStatement,但出现了SQL 语法错误。我得到的错误是:

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '? AND password = ?' at line 1

import java.awt.Color;
*import java.sql.Statement;*
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

private void jButton_LoginActionPerformed(java.awt.event.ActionEvent evt) {                                              

    Statement st;
    ResultSet rs;

    //get username & password

    String username = jTextField1.getText();
    String password = String.valueOf(jPasswordField1.getPassword());

    //make sure username and passord are from query
    String query = "SELECT * FROM `users` WHERE `username` = ? AND `password` = ?";

    // show a message if the username or the password fields are empty
    if(username.trim().equals("username"))
    {
        JOptionPane.showMessageDialog(null, "Enter Your Username", "Empty 
    Username", 2);
    }
    else if(password.trim().equals("password"))
    {
        JOptionPane.showMessageDialog(null, "Enter Your Password", "Empty 
    Password", 2);
    }
    else{
    try {
        st = My_CNX.getConnection().createStatement();


        rs = st.executeQuery(query);

        if(rs.next())
        {
            //show new form
            Main_Menu form  = new Main_Menu();
            form.setVisible(true);
            form.pack();
            form.setLocationRelativeTo(null);
            //close the current form (login_form)

            this.dispose();

        }
        else{
            // error message
            JOptionPane.showMessageDialog(null, "Invalid Username / 
    Password","Login Error",2);
        }

    }


     catch (SQLException ex) {
        Logger.getLogger(Login_Form.class.getName()).log(Level.SEVERE, null, ex);
    }
    }

我正在使用MySQL。如果有一种方法可以使登录表单容易受到攻击,或者我什至可以使用prepareStatement进行查询,或者我只是出了问题,我将不胜感激。

最佳答案

我对 NetBeans 或 Java 不太熟悉,但应该能够帮助您。

当您使用createStatement时,您并没有替换问号。您需要使用表单中的值填充查询。这就是 MySQL 错误所说的内容。它正在发送字面上的问号。

我认为你是对的,prepareStatement 给你带来了问题。 According to the documentation ,问号是占位符,您可以在其中使用 setInt、setString、setFloat 等来清理用户输入。

SQL注入(inject)攻击

SQL 攻击的目的是诱骗应用程序执行不应该执行的操作。

因此,根据您的代码,由于您没有清理用户输入,因此输入以下密码应该会删除该表:

hunter2; DROP TABLE USERS;

完成变量替换后,MySQL 的查询将如下所示(为了清晰起见,添加了新行):

SELECT * FORM `users` WHERE `username` = q13 AND `password` = hunter2; 
DROP TABLE USERS;

关于java - 使登录容易受到 SQL 注入(inject)登录绕过攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59130075/

相关文章:

java - 如何在 Java 中比较字符串?

java - 为什么 android.util.Base64 返回不同的字符串?

MySQl 在插入和更新同一个表时触发错误(错误代码 : 1064)

php - 将 scandic 字母插入数据库时​​出错

java - Netbeans 中的 clean 和 build 错误

css - 我刚刚将 NetBeans 8 更新到 8.0.2。当我打开我的旧元素时,我得到 'The provided LESS compiler is not valid'

java - 使用 docx4java 将字段代码插入文档

java - 如何在java类中打开Assets文件夹中的文件

php - 如何使用 PHP 和 MySQL 显示按归档分组的报告?

java - 应用程序启动时在 jDateChooser 处获取空指针异常