MySQL之使用预处理对象PreparedStatement防止注入攻击

  • Post author:
  • Post category:mysql



防止注入攻击核心思想




通过预处理对象PreparedStatement,对SQL语句中


参数列表


进行


指定传参


,防止用户在SQL语句结尾上添加额外的SQL语句



SQL语句中参数列表

每条SQL语句中的参数全部采用

问号占位符

String sql = "insert into sort(sid,sname) values(?,?)";
PreparedStatement预处理对象代码:
PreparedStatement psmt = conn.prepareStatement(sql);


实际参数传递

将指定参数设置为给定Java的xx值。在将此值发送到数据库时,驱动程序将它转换成一个 SQL Xxx类型值
	void setXxx(int index, Xxx xx);
把SQL语句中第2个位置的占位符? 替换成实际参数 "mark"
        setString(2, "mark") 


案例

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;


public class JDBCAntiAttack {
	private static Scanner sc;
	public static void main(String[] args) {
		/*
		 * 获取用户输入的用户名和密码
		 */
		sc = new Scanner(System.in);
		System.out.println("请输入用户名:");
		String name = sc.next();
		System.out.println("请输入密码:");
		String pass = sc.next();
		
		/*
		 * 连接数据库进行注入攻击
		 */
		try {
			// 注册数据库
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		String url = "jdbc:mysql://localhost:3306/mybase";
		String username = "root";
		String password = "root";
		Connection conn = null;
		PreparedStatement pst = null;
		ResultSet rs = null;
		try {
			// 获取连接
			conn = DriverManager.getConnection(url, username, password);
			//sql语句,执行验证查询
			String sql = "SELECT * FROM USER WHERE uname=? AND upassword=?";
			//预处理
			pst = conn.prepareStatement(sql);
			pst.setObject(1, name);
			pst.setObject(2, pass);
			System.out.println(sql);
			//执行sql语句
			rs = pst.executeQuery();
			if(rs.next()){
				System.out.println("用户名和密码验证通过!");
			}
			else {
				System.out.println("用户名和密码验证不通过!");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			try {
				rs.close();
				pst.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}


测试结果



版权声明:本文为mmake1994原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。