javaのPreparedSttementとSttementについて詳しく説明します。
8256 ワード
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コードは大雑把に書いてあります。
私が使っているのは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 ,
*/
#
-- ( :-- , , )
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。