1. 程式人生 > 其它 >16-MySQL-JDBC-SQL注入問題及PreparedStatement物件

16-MySQL-JDBC-SQL注入問題及PreparedStatement物件

技術標籤:MySQLjavajdbcmysql

MySQL -> JDBC -> SQL注入問題、PreparedStatement物件

1. SQL注入問題
  • sql存在漏洞,會被攻擊導致資料洩露;
  • 本質:sql會被拼接 or
  • 例項:
import com.anobabe.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SQLIn
{ public static void main(String[] args) { //login("ano","123456"); login("'or '1=1","'or '123456"); } //登入業務 public static void login(String username,String password){ Connection conn = null; Statement st = null; ResultSet rs =
null; try { conn = JdbcUtils.getConnection(); st = conn.createStatement(); //SELECT * FROM users WHERE `name`='ano' AND `password`='123456'; String sql = "SELECT * FROM users WHERE `name` = '" + username + "' AND `password`='"
+ password + "'"; rs = st.executeQuery(sql); while (rs.next()){ System.out.println(rs.getString("name")); System.out.println(rs.getString("password")); } } catch (SQLException throwables) { throwables.printStackTrace(); } finally { JdbcUtils.release(conn,st,rs); } } }
SQL注入問題例項執行結果
2. PreparedStatement物件
  • 預編譯
  • 可以防止SQL注入
  • 效率更高

增:

import com.anobabe.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.util.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestInsert {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pst = null;


        try {
            conn = JdbcUtils.getConnection();
            // 與Statement的區別:使用?佔位符代表引數
            String sql = "INSERT INTO users(`id`,`name`,`password`,`email`,`birthday`) VALUES (?,?,?,?,?)";
            pst = conn.prepareStatement(sql);
            pst.setInt(1,5);
            pst.setString(2,"Jay");
            pst.setString(3,"111111");
            pst.setString(4,"[email protected]");
            //注意點:java.sql.Date  -- 資料庫
            //      java.util.Date -- Java  new Date().getTime()獲得時間戳
            pst.setDate(5,new java.sql.Date(new Date().getTime()));

            //執行:預編譯執行不用穿引數
            int i = pst.executeUpdate();
            if(i>0){
                System.out.println("插入成功!");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(conn,pst,null);
        }
    }
}

刪:

import com.anobabe.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestDelete {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pst = null;


        try {
            conn = JdbcUtils.getConnection();
            // 與Statement的區別:使用?佔位符代表引數
            String sql = "DELETE FROM users WHERE id=?";
            pst = conn.prepareStatement(sql);
            pst.setInt(1,5);


            //執行:預編譯執行不用穿引數
            int i = pst.executeUpdate();
            if(i>0){
                System.out.println("刪除成功!");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(conn,pst,null);
        }
    }
}

改:

import com.anobabe.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestUpdate {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pst = null;


        try {
            conn = JdbcUtils.getConnection();
            // 與Statement的區別:使用?佔位符代表引數
            String sql = "UPDATE users SET `name`=? WHERE id=?";
            pst = conn.prepareStatement(sql);
            pst.setString(1,"anobabe");
            pst.setInt(2,2);


            //執行:預編譯執行不用穿引數
            int i = pst.executeUpdate();
            if(i>0){
                System.out.println("更新成功!");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(conn,pst,null);
        }
    }
}

查:

import com.anobabe.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestSelect {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "SELECT * FROM users WHERE id=?";
            pst = conn.prepareStatement(sql);
            pst.setInt(1,2);
            rs = pst.executeQuery();
            while (rs.next()){
                System.out.println(rs.getInt("id"));
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("password"));
                System.out.println(rs.getString("email"));
                System.out.println(rs.getDate("birthday"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn,pst,rs);
        }
    }
}
  • PreparedStatement防止SQL注入
import com.anobabe.lesson02.utils.JdbcUtils;

import java.sql.*;

public class SQLIn {
    public static void main(String[] args) {
        //login("ano","123456");
        login("' ' or 1=1","123456");
    }
    //登入業務
    public static void login(String username,String password){
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();

            //SELECT * FROM users WHERE `name`='ano' AND `password`='123456';
            String sql = "SELECT * FROM users WHERE `name` = ? AND `password`=?";
            st = conn.prepareStatement(sql);
            st.setString(1,username);
            st.setString(2,password);
            rs = st.executeQuery();
            while (rs.next()){
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("password"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

執行結果:不報錯,但無結果

PreparedStatement防止SQL注入的本質:把傳遞進來的引數當作字元,假設其中存在轉義字元,就直接忽略