javaのPreparedSttementとSttementについて詳しく説明します。


PreparedSttementの対象はsql注入を防ぐことができますが、Sttementはsql注入を防ぐことができないということを知っています。なぜPreparedSttementの対象はsql注入を防ぐことができますか?
私が使っているのはmysqlデータベースです。admin表を例にとって、次の図のようになります。
一番後ろに具体的なjavaコードとsqlコードの実例があります。




最終的に実行されるsql文のプリントアウトはSELECT*FROM admin WHERE username='韋小宝'AND password='222\'OR\'8\'8'です。
以上のスクリーンショットからもわかるように、preparestementのオブジェクトはsql注入を防止する方式で、ユーザーが不正に入力したシングル引用符を\反斜め棒で変換し、sql注入を防止する目的を達成しました。
Sttementの対象はそんなに親切ではありません。ユーザーが不法に入力したシングルの引用符を'反斜め棒で転義することはできません。
PreparedSttementはsql注入を効果的に防ぐことができますので、生産環境では必ずPreparedStatimentを使います。Sttementは使えません。
もちろんです。PreparedSttementの対象がどのようにsql注入を防止しているかを詳しく研究してください。自分で最終的に実行したsql文を印刷しました。プリントしたsql文を見て分かりました。元々はmysqlデータベースメーカーです。PreparedSttementインターフェースを実現するためのクラスのsetString(int parameIndex,String)でいくつかの関数を処理しました。シングル引用符を転送しました。(ユーザーが入力した文字列の中にシングル引用符がある限り、そのmysqlデータベースメーカーのset String()という関数は、シングル引用符を転送します。)
みんなは興味があったら、ネットに行って、mysqlデータベースのドライバのソースコードをダウンロードして、mysqlデータベースメーカーのドライバのソースコードを見てください。ソースコードの中にset String関数を見つけて、この関数の中でどうやって書いているかを見てください。mysqlデータベースメーカーのドライバのソースコードをダウンロードしていません。mysqlデータベースのドライバjarパッケージを解凍しました。PreparedSttement.classファイルを見つけました。逆コンパイルツールを使って、逆コンパイルしました。









これで皆さんはPreparedStatimentがどのようにsql注入を防止しているかご存知でしょう。
222'OR'8'='8のようなsql注入は优しくて、一部のもっと嫌なユーザーは、彼らが入力した不正な値はdelete from table Nameまたはtruncate table table Nameである。いくつかのデータベースはあなたを成功させませんが、多くのデータベースもこれらのステートメントを実行することができますので、生産環境では必ずPreparedSttementを使用してください。Sttementを使用することはできません。
いくつかの例を挙げて、スクリーンショットを見ます。

最終プリントSELECT*FROM admin WHERE username='韋小宝'AND password=''DROP TABLEテーブルName;

最終プリントSELECT*FROM admin WHERE username='韋小宝'AND password=''delete fromテーブルName;

最終プリントSELECT*FROM admin WHERE username='韋小宝'AND password=''truncate table table Name;

以下はjavaコードとsql文です。皆さんの参考になるように、PreparedSttementの対象をテストするためです。だから、javaコードは大雑把に書いてあります。

package com.test;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
 
/*
 *   PreparedStatement     sql   ,      ,   mysql     ,  
 *  PreparedStatement        setString(int parameterIndex, String x) 
 *         ,        (               , mysql      setString()   
 *  ,         )
 */
public class TestConnMySql2 {
 
	public static void main(String[] args) {
		String connStr = "jdbc:mysql://localhost:3306/girls";
//		String sql = "select * from admin";
		String sql = "SELECT * FROM admin WHERE username = ? AND password = ?";
		try {
			Class.forName("com.mysql.jdbc.Driver");
			Connection connection = DriverManager.getConnection(connStr, "root", "root");
			System.out.println("     =" + connection);
			//Statement    sql  
//			Statement stmt = connection.createStatement();
	//PreparedStatement      sql  ,            PreparedStatement,     Statement
			PreparedStatement prepareStatement = connection.prepareStatement(sql);
			prepareStatement.setString(1, "   ");
			//          
//			prepareStatement.setString(2, "222");
			//  sql  (          )
			prepareStatement.setString(2, "222' OR '8'='8");
			/*
			 *     sql       ,        ,      
			 *    delete from tableName truncate table tableName        ,
			 *       drop table tableName;             ,      
			 *             ,            PreparedStatement,     Statement
			 */
			//  sql  (          ) mysql #        (  mysql      ,      )
//			prepareStatement.setString(2, "'; DROP TABLE tableName;#");
			//  sql  (          )
//			prepareStatement.setString(2, "'; delete from tableName;#");
			//  sql  (          )
//			prepareStatement.setString(2, "'; truncate table tableName;#");
			
			ResultSet rs = prepareStatement.executeQuery();
			System.out.println("sql=" + prepareStatement.toString());
			int col = rs.getMetaData().getColumnCount();
			System.out.println("============================");
			while (rs.next()) {
				for (int i = 1; i <= col; i++) {
					System.out.print(rs.getString(i) + "\t");
					if ((i == 2) && (rs.getString(i).length() < 8)) {
						System.out.print("\t");
					}
				}
				System.out.println("");
			}
			System.out.println("============================");
			rs.close();
			prepareStatement.close();
			connection.close();
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		}
 
	}
 
}

#          
SELECT * FROM admin WHERE username = '   ' AND `password` = '222';
#          
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = '222';
 
#sql  (        )  Statement  ,    sql  (          )
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = '222' OR '8'='8'
#sql  (        )  PreparedStatement  ,      sql  
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = '222\' OR \'8\'=\'8'
 
#sql  (        )  Statement  ,    sql  (DROP     )
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = ''; DROP TABLE tableName;#'
#sql  (        )  PreparedStatement  ,      sql  
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = '\'; DROP TABLE tableName;#'
 
#sql  (        )  Statement  ,    sql  (TRUNCATE     )
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = ''; TRUNCATE TABLE tableName;#'
#sql  (        )  PreparedStatement  ,      sql  
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = '\'; truncate table tableName;#'
 
#sql  (        )  Statement  ,    sql  (DELETE     )
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = ''; DELETE FROM tableName;#'
#sql  (        )  PreparedStatement  ,      sql  
SELECT * FROM admin WHERE username = '   ' AND PASSWORD = '\'; delete from tableName;#'
 
#            PreparedStatement,     Statement
 
/*
      mysql  3   ,      
*/
 
#      
 
--        (  :--     ,          ,      )
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。