sql注入攻击和PreparedStatement有效防止sql注入攻击

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/PacosonSWJTU/article/details/81407248

【1】sql注入攻击:

/**
	 * SQL 注入.
	 */
	@Test
	public void testSQLInjection() {
		String username = "a' OR PASSWORD = ";
		String password = " OR '1'='1";

		String sql = "SELECT * FROM user_tbl WHERE user_name = '" + username
				+ "' AND " + "password = '" + password + "'";
		// sql注入攻击使用的sql: SELECT * FROM user_tbl WHERE user_name = 'a' OR PASSWORD = ' AND password = ' OR '1'='1'
		System.out.println(sql);

		Connection connection = null;
		Statement statement = null;
		ResultSet resultSet = null;

		try {
			connection = JdbcUtils.getConnection();
			statement = connection.createStatement();
			resultSet = statement.executeQuery(sql);

			if (resultSet.next()) {
				System.out.println("登录成功!");
			} else {
				System.out.println("用户名和密码不匹配或用户名不存在. ");
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcUtils.closeStatAndConnAndResultSet(statement, connection, resultSet);
		}
	}
	

【2】PreparedStatement 有效防止sql注入攻击

/**
	 * 使用 PreparedStatement 将有效的解决 SQL 注入问题.
	 */
	@Test
	public void testSQLInjection2() {
		String username = "a' OR PASSWORD = ";
		String password = " OR '1'='1";

		String sql = "SELECT * FROM user_tbl WHERE user_name = ? "
				+ "AND password = ?";

		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;

		try {
			connection = JdbcUtils.getConnection();
			preparedStatement = connection.prepareStatement(sql);

			preparedStatement.setString(1, username);
			preparedStatement.setString(2, password);

			resultSet = preparedStatement.executeQuery(); // 这里查询失败
			
			if (resultSet.next()) {
				System.out.println("登录成功!");
			} else {
				System.out.println("用户名和密码不匹配或用户名不存在. ");
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcUtils.closeStatAndConnAndResultSet(preparedStatement, connection, resultSet);
		}
	}

【3】代码补充:jdbc工具类 

/**
 * 操作jdbc的工具类-封装了一些工具方法
 * @author pacoson
 */
public class JdbcUtils {
	
	
	
	/**
	 * 通用的更新方法:insert, update, delete
	 * 版本1
	 * @param sql
	 */
	public static void updateV2ByPreparedStatement(String sql, Object... objs) {
		Connection conn = null;
		PreparedStatement stat = null;
		try {
			// 1.获取数据库连接
			conn = JdbcUtils.getConnection();
			// 4.执行插入
			// 4.1 获取操作sql语句的statement对象; 
//			调用Connection的  createStatement() 方法来获取
			stat = conn.prepareStatement(sql);
			int i = 1;
			for (Object obj : objs) {
				stat.setObject(i++, obj);
			}
			System.out.println("连接=" + conn + ",语句 = " + stat);
			// 4.2 调用statement对象的 executeUpdate(sql) 执行sql语句进行插入
			int updateRows = stat.executeUpdate();
			System.out.println("更新记录行数:" + updateRows);
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			JdbcUtils.closeStatAndConn(stat, conn);
		}
	}
	
	/**
	 * 通用的更新方法:insert, update, delete
	 * 版本1
	 * @param sql
	 */
	public static void updateV1(String sql) {
		Connection conn = null;
		Statement stat = null;
		try {
			// 1.获取数据库连接
			conn = JdbcUtils.getConnection();
			// 4.执行插入
			// 4.1 获取操作sql语句的statement对象; 
//			调用Connection的  createStatement() 方法来获取
			stat = conn.createStatement();
			System.out.println("连接=" + conn + ",语句 = " + stat);
			// 4.2 调用statement对象的 executeUpdate(sql) 执行sql语句进行插入
			int updateRows = stat.executeUpdate(sql);
			System.out.println("更新记录行数:" + updateRows);
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			JdbcUtils.closeStatAndConn(stat, conn);
		}
	}
	
	/**
	 * 获取连接的方法。
	 * 通过读取配置文件从数据库服务器获取一个连接
	 * @return
	 * @throws Exception
	 */
	public static Connection getConnection() throws Exception {
		
		// 读取类路径下的 jdbc.properties 文件并将其封装到 Properties中:
		InputStream in = JdbcTest01.class.getClassLoader().getResourceAsStream("jdbc.properties");
		Properties props = new Properties();
		props.load(in);
		/* 通过反射获取驱动器Driver */
		Driver driver = (Driver) Class.forName(props.getProperty("driver")).newInstance();
		/* 获取数据库连接  */
		Connection conn = driver.connect(props.getProperty("url"), props);
		return conn;
	}
	
	/**
	 * 关闭数据库语句 statement 和 数据库连接 conn 和 结果集 ResultSet
	 * @param stat
	 * @param conn
	 */
	public static void closeStatAndConnAndResultSet(Statement stat, Connection conn, ResultSet rs) {
		if (null != rs) {
			try {
				rs.close(); // 关闭ResultSet对象
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
		if (null != stat) {
			try {
				stat.close(); // 关闭statement对象
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
		if (null != conn) {
			try {
				conn.close(); // 关闭连接
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * 关闭数据库语句 statement 和 数据库连接 conn 
	 * @param stat
	 * @param conn
	 */
	public static void closeStatAndConn(Statement stat, Connection conn) {
		if (null != stat) {
			try {
				stat.close(); // 关闭statement对象
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
		if (null != conn) {
			try {
				conn.close(); // 关闭连接
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
}

猜你喜欢

转载自blog.csdn.net/PacosonSWJTU/article/details/81407248