欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 为什么预编译可以避免SQL注入?

为什么预编译可以避免SQL注入?

2025/5/3 6:07:03 来源:https://blog.csdn.net/winerpro/article/details/145099049  浏览:    关键词:为什么预编译可以避免SQL注入?

数据库的预编译(Prepared Statement)是一种数据库查询优化技术,在预编译中,可以先先提交带占位符的 SQL ,MySQL 先将其编译好,然后用户再拿着SQL中定义的占位符对应的参数让 MySQL 去执行。

当一个SQL被预编译之后,预编译的SQL模板中的占位符,比如问号(?),是作为参数的位置标记存在的,而不是作为SQL语句的一部分。无论用户输入什么样的参数,这些参数都会被视为数据,而不会被解释为SQL语句的一部分。

也就是说,用户输入的恶意代码会被当作普通的数据处理,而不会被解释为SQL语句的一部分。如果恶意注入的内容打破了SQL语句的语法结构,数据库可能会在执行阶段产生语法错误,导致查询无法成功执行。这实际上是数据库系统试图解析预编译模板时的结果,因为预编译模板本身的语法是固定的。

举一个简单的例子,加入我们有一个原始SQL:

// 原始查询模板
$sql = "SELECT * FROM users WHERE username = ?";

当用户输入恶意代码尝试进行SQL注入:

$userInput = "hollis'; DROP TABLE users; --";

用户期望最终这个SQL变成:

SELECT * FROM users WHERE username = 'hollis'; DROP TABLE users; --'

会导致数据表被删除。那么,如果用了预编译之后,就不会出现这种问题了。

预编译过程如下:

PREPARE stmt FROM 'SELECT * FROM users WHERE username = ?';EXECUTE stmt USING @userInput;DEALLOCATE PREPARE stmt;

在这种情况下,用户输入包含对SQL注入的尝试(hollis'; DROP TABLE users; --)。然而,由于预处理语句和参数绑定,这个输入被视为字符串而不是可执行的SQL代码。实际执行的查询是:

SELECT * FROM users WHERE username ='hollis\'; DROP TABLE users; --'

 那么也就是说,用户输入的整个部分,都作为字符串的一部分了,会去数据库中查询username为hollis\'; DROPTABLE users; --的用户,这有效的避免了SQL注入。

Java中使用预编译

在Java中,PreparedStatement是java.sql包中的一个接口,用于执行带有预编译参数的SQL语句。它是Statement接口的子接口,提供了更强大、更安全的SQL执行机制。

以下是使用PreparedStatement的简单用法,可以有效的避免SQL注入:

 

// 用户输入(可能是恶意输入)
String userInput = "hollis'; DROP TABLE users; --";// 原始查询模板
String sql = "SELECT * FROM users WHERE username = ?";// 使用PreparedStatement进行预编译
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {// 绑定参数preparedStatement.setString(1, userInput);// 执行查询try (ResultSet resultSet = preparedStatement.executeQuery()) {// 处理结果(简化起见,只是输出)while (resultSet.next()) {System.out.println(resultSet.getString("username"));}}
} catch (SQLException e) {e.printStackTrace();
}

 

 

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com