<img src="https://img.php.cn/upload/article/000/000/052/5ffcf9b492b47340.jpg" alt="SQL インジェクションの問題のトラブルシューティング" >
#推奨 (無料):SQL チュートリアル<a href="https://www.php.cn/sql/" target="_blank"></a>
SQL注射とは何ですか?
ああ、とても長い段落です。読みたくないです。例を使って
の意味を説明しましょう。 SQL インジェクションとは、 :
use db1;create table user( id int primary key auto_increment, username varchar(32), password varchar(32));insert into user values(null,'zhangsan','123');insert into user values(null,'lisi','234');
気軽に使ってみよう
JDBCログイン操作を書く:
package com.wzq.jdbc;import com.wzq.util.JDBCUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Scanner;/* * 需求: * 1、通过键盘录入用户名和密码 * 2、判断用户是否登陆成功 * */public class JDBCDemo05 { public static void main(String[] args) { Scanner cin = new Scanner(System.in); System.out.println("请输入用户名:"); String username = cin.nextLine(); System.out.println("请输入密码:"); String password = cin.nextLine(); boolean res = new JDBCDemo05().login(username, password); if (res) System.out.println("登陆成功!"); else System.out.println("登陆失败!"); } public boolean login(String username, String password) { if (username == null || password == null) { return false; } Connection conn = null; Statement stmt = null; ResultSet rs = null; try { //1、获取数据库连接 conn = JDBCUtils.getConnection(); //JDBCUtils工具类 //2、定义sql String sql = "select * from user where username = '" + username + "' and password = '" + password + "'"; //3、获取执行sql的对象 stmt = conn.createStatement(); //4、执行sql rs = stmt.executeQuery(sql); return rs.next(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.close(rs, stmt, conn); } return false; }}
通常のテストでは問題ないことがわかります。次に、
SQL インジェクション:
a' または 'a'='a
ログインが成功したことに驚きました。
sql を出力して見てみましょう:
select * from user where username = 'askjdhjksahd' and password = 'a' or 'a' = 'a'
where の後の条件がわかります。どのような結果が true であっても、テーブル全体が出力されます:
つまり、要約すると、
sql を結合するときに、一部の
sql 特別なキーワードが文字列の結合に関与し、セキュリティ上の問題が発生します。これが理由です。上記でログインは成功しました。
Statement オブジェクトの代わりに
PreparedStatement オブジェクトを使用します。
PreparedStatement オブジェクトは
Statement オブジェクトのサブクラスです。プリコンパイルされた
sql であるため、
Statemnet よりも高速に実行されます。もっと早く。
PerpaerdStatement?
をプレースホルダーとして使用し、
setXxx(index, value) を使用して値##を
?# に割り当てます。 それでは、
を置き換えてコードを書きましょう: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> public boolean login(String username, String password) { if (username == null || password == null) { return false;
}
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try { //1、获取数据库连接
conn = JDBCUtils.getConnection(); //JDBCUtils类
//2、定义sql
String sql = "select * from user where username = ? and password = ?";
//3、获取执行sql的对象
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,username);
pstmt.setString(2,password);
//4、执行sql
rs = pstmt.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, pstmt, conn);
} return false;
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
テストしてみましょう:
正常に解決されました。
以上がSQL インジェクションの問題のトラブルシューティングの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。