`

使用预编译语句是预防SQL注入的最佳方式

 
阅读更多

sql预编译

定义

sql 预编译指的是数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。

为什么需要预编译

JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译

  1. 预编译阶段可以优化 sql 的执行。

    预编译之后的 sql 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的sql,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。

  2. 预编译语句对象可以重复利用。

    把一个 sql 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个sql,可以直接使用这个缓存的 PreparedState 对象。

     

Mybatis中预编译:使用#{}语法,MyBatis会产生PreparedStatement语句中,并且安全的设置PreparedStatement参数,这个过程中MyBatis会进行必要的安全检查和转义。

示例1:
执行SQL:Select * from emp where name = #{employeeName}
参数:employeeName=>Smith
解析后执行的SQL:Select * from emp where name = ?
执行SQL:Select * from emp where name = ${employeeName}
参数:employeeName传入值为:Smith
解析后执行的SQL:Select * from emp where name =Smith

 

综上所述、${}方式会引发SQL注入的问题、同时也会影响SQL语句的预编译,所以从安全性和性能的角度出发,能使用#{}的情况下就不要使用${}。

用法 tips

1、能使用 #{ } 的地方就用 #{ }

首先这是为了性能考虑的,相同的预编译 sql 可以重复利用。

其次, ${ } 在预编译之前已经被变量替换了,这会存在 sql 注入问题 。例如,如下的 sql,

select * from ${tableName} where name = #{name} 

假如,我们的参数 tableName 为 user; delete user; -- ,那么 SQL 动态解析阶段之后,预编译之前的 sql 将变为

select * from user; delete user; -- where name = ?;

-- 之后的语句将作为注释,不起作用,因此本来的一条查询语句偷偷的包含了一个删除表数据的 SQL!

2、表名作为变量时,必须使用 ${ }

这是因为,表名是字符串,使用 sql 占位符替换字符串时会带上单引号 '' ,这会导致 sql 语法错误,例如:

select * from #{tableName} where name = #{name};

预编译之后的sql 变为:

select * from ? where name = ?;

假设我们传入的参数为 tableName = "user" , name = "ruhua",那么在占位符进行变量替换后,sql 语句变为

select * from 'user' where name='ruhua';

上述 sql 语句是存在语法错误的,表名不能加单引号 '' (注意,反引号 ``是可以的)。

分享到:
评论

相关推荐

    SQL.预编译.docx

    预编译语句通常在SQL语句需要重复执行或存在循环结构中使用,以提高性能并防止SQL注入。比如在遍历列表并根据其中的数据执行相同结构但参数不同的SQL时,PreparedStatement是非常合适的工具。 3. **为何使用预编译...

    防止sql注入解决方案

    预编译语句在执行前会先编译,然后多次执行时只需替换参数,这不仅提高了性能,还能有效防止SQL注入。使用预编译语句时,SQL语句的结构是固定的,只有参数是可以改变的。例如,在Java中,可以这样使用...

    DB2数据库SQL注入语句

    - 使用参数化查询或预编译语句,如PreparedStatement在Java中的使用。 - 对用户输入进行严格的验证和过滤,拒绝不符合预期格式的输入。 - 避免在SQL查询中直接拼接用户输入。 - 使用存储过程,并限制对数据库的直接...

    spring自带的jdbcTemplate查询、插入预编译使用

    预编译SQL可以有效防止SQL注入,提高代码的可读性和执行效率。在使用`jdbcTemplate`进行预编译查询时,我们通常会使用`query()`或`queryForList()`方法。例如: ```java String sql = "SELECT * FROM table WHERE ...

    如何防止sql注入【转载】

    为了防止 SQL 注入,需要从多方面入手,包括使用预编译语句、正则表达式、字符串过滤等。 首先,使用预编译语句可以极大地提高安全性。预编译语句可以将用户输入的数据与 SQL 语句分离,从而防止恶意代码的注入。...

    mybatis如何防止SQL注入

    使用预编译语句(PreparedStatement) MyBatis内部使用了JDBC的PreparedStatement来实现SQL语句的预编译。这种方式可以有效防止SQL注入。具体做法是在SQL语句中使用`#{}`来表示参数占位符,如: ```xml SELECT ...

    案例预防SQL注入漏洞函数

    1. **参数化查询**:使用参数化查询(也称为预编译语句),可以确保用户输入的数据不会与SQL命令混淆,从而消除SQL注入的风险。 2. **输入验证**:除了过滤特殊字符,还应检查输入的格式和范围,确保它们符合预期的...

    JAVA预编译示例代码

    本文提供了一个 JAVA 预编译示例代码,涵盖了预编译中使用 like、javaSQL 预编译异常、预编译语句支持 in 方式等多个方面的知识点。 1. 预编译中使用 like 在预编译中使用 like 时,需要在值的地方加 % 号,以便...

    防止sql注入demo

    - 使用预编译语句(PreparedStatement):这是防止SQL注入最常用的方法。预编译语句会将用户输入与SQL语句分离,确保即使输入含有恶意代码,也不会被执行。例如: ```java String query = "SELECT * FROM users ...

    SQL注入语句实例演示和解释.rar

    在这个"SQL注入语句实例演示和解释"的压缩包中,主要包含了一个名为"SQL注入语句.doc"的文档,我们可以通过这个文档深入理解SQL注入的工作原理、常见类型以及防范措施。 首先,SQL注入的基本原理是,当用户通过表单...

    SQL 注入天书.pdf

    此外,还将学习如何防御SQL注入,例如使用参数化查询、预编译语句和输入验证等方法。 总的来说,《SQL注入天书》及配套的sqli-labs提供了全面的SQL注入学习路径,从基础到高级,从理论到实践,有助于安全专业人士和...

    SQL注入原理以及Spring Boot如何防止SQL注入(含详细示例代码)

    1. 使用JdbcTemplate:JdbcTemplate提供了一种安全的方式来执行SQL查询,通过预编译的SQL语句和PreparedStatementCreator工厂类,将用户输入作为参数,而非直接拼接。例如,创建一个UserRepository接口,其中定义了...

    常用Sql注入语句.

    - 参数化查询(预编译语句):使用参数而不是直接拼接用户输入,例如使用PDO或SQL Server的sp_executesql。 - 输入验证:检查输入数据的格式和长度,拒绝不合规的输入。 - 最小权限原则:确保应用的数据库用户...

    SQL注入攻击实验报告

    - **参数化查询**:使用参数化查询或预编译语句,避免直接拼接SQL字符串。 - **最小权限原则**:为应用程序分配最小的数据库访问权限,限制其只能执行必要的操作。 - **错误信息处理**:不要直接显示详细的错误信息...

    Python中防止sql注入的方法详解

    防止SQL注入的最佳实践是多方面的,包括但不限于使用预编译SQL语句、采用ORM框架以及选择具有强大安全特性的第三方库。此外,开发者还需要时刻关注输入数据的有效性和安全性,定期审查代码以确保不存在潜在的安全...

    SQL注入全面讲解技术文档

    通过理解其原理,采取有效的预防措施,以及定期评估和更新防护策略,可以大大降低SQL注入攻击的风险。对于初学者和专业开发者来说,深入研究SQL注入的各个方面,包括入门、进阶和高级技巧,是提升系统安全性的关键...

    java_JDBC预编译相关知识点参照.pdf

    此外,由于预编译语句能有效防止SQL注入,所以涉及用户输入数据的查询操作也应首选PreparedStatement。 3. **为何使用预编译语句?** - **提高效率**:预编译语句通过提前编译减少了数据库的解析和语法检查工作,...

    sql注入网站源码

    2. **防止SQL注入**:最有效的防御方法是使用参数化查询或预编译的SQL语句。在ASP中,可以使用ADO(ActiveX Data Objects)的Command对象和参数,这样用户输入的数据不会影响SQL结构。此外,应避免使用动态SQL,尽...

Global site tag (gtag.js) - Google Analytics