JAVA—可能的SQL注入

JAVA—可能的SQL注入,java,sql,jdbc,sql-injection,secure-coding,Java,Sql,Jdbc,Sql Injection,Secure Coding,我有一段代码: String username = props.getProperty("jdbc.username"); try { String username = parts[1]; // Check procedure System.out.println("Checking user"); // Check database user table for

我有一段代码:

String username = props.getProperty("jdbc.username");
try {
                String username = parts[1];

                // Check procedure
                System.out.println("Checking user");

                // Check database user table for username
                conn = getSQLConnection();
                Statement stat = conn.createStatement();
                ResultSet user = stat.executeQuery( "SELECT * FROM USER WHERE log_id='" + username + "';" );
                // Check given password against user entry
                if(user.next()){
                    System.out.println("User Exists: " + username);
                    sendMessage("true");
                    return;
                }
                else{

                    System.out.println("User Does Not Exist: " + username);
                    sendMessage("false user");
                    return;
                }
出于教育目的,即使我知道输入来自何处,SQL语句是否受到SQL注入的保护

ResultSet user = stat.executeQuery( "SELECT * FROM USER WHERE log_id='" + username + "';" );
这取决于SQL注入

想象一下,如果
username
具有以下值,会发生什么情况:

John'; delete from user where 'a' = 'a
是的,大量的Java JDBC SQL教程会弄错这一点。基本上,总是使用s

这不仅是因为即使
username
具有如上所述的恶意值,也可以安全使用,而且更重要的是,RDBMS引擎可以将同一查询重新用于所有后续调用

简而言之,没有理由不使用它们。演示使用字符串连接的SQL的教程应该会导致痛苦的SQL注入死亡。

如中所述,一个恶意攻击者可以对您的应用程序执行以下操作:

  • 调用sleep函数,使所有数据库连接都处于繁忙状态,从而使应用程序不可用
  • 从数据库中提取敏感数据
受影响的不仅仅是SQL。如果不使用绑定参数,甚至JPQL也会受到影响

总之,在构建SQL语句时,不应该使用字符串连接。为此,请使用专用API:


您始终可以100%控制系统中的用户名?不,它不受保护。只要您使用连接字符串创建查询,您就不会受到保护。您所说的“出于教育目的”是什么意思?我只理解为只使用准备好的语句。但是,在这种情况下,即使用户没有指定用户名,我仍然可以通过用户名进行SQL注入谢谢您的回答/评论。您向我解释了很多:)jdbc.username可以很容易地更改以进行SQL注入。