加入收藏 | 设为首页 | 会员中心 | 我要投稿 辽源站长网 (https://www.0437zz.com/)- 云专线、云连接、智能数据、边缘计算、数据安全!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

不同场景/框架下,如何干掉恶心的 SQL 注入?

发布时间:2020-02-21 23:41:06 所属栏目:资源 来源:站长网
导读:简介 文章 主要内容包括: 1、 Java 持久层技术/框架简单介绍 2、不同场景/框架下易导致 SQL 注入的写法 3、如何避免和修复 SQL 注入 JDBC 介绍 JDBC: 1、全称 Java Database Connectivity 2、是 Java 访问 数据库 的 API,不依赖于特定数据库 ( database
  简介  文章主要内容包括:  1、Java 持久层技术/框架简单介绍  2、不同场景/框架下易导致 SQL 注入的写法  3、如何避免和修复 SQL 注入  JDBC  介绍  JDBC:  1、全称 Java Database Connectivity  2、是 Java 访问数据库的 API,不依赖于特定数据库 ( database-independent )  3、所有 Java 持久层技术都基于 JDBC  说明  直接使用 JDBC 的场景,如果代码中存在拼接 SQL 语句,那么很有可能会产生注入,如  安全的写法是使用 参数化查询 ( parameterized queries ),即 SQL 语句中使用参数绑定( ? 占位符 ) 和 PreparedStatement,如  还有一些情况,比如 order by、column name,不能使用参数绑定,此时需要手工过滤,如通常 order by 的字段名是有限的,因此可以使用白名单的方式来限制参数值  这里需要注意的是,使用了 PreparedStatement 并不意味着不会产生注入,如果在使用 PreparedStatement 之前,存在拼接 sql 语句,那么仍然会导致注入,如  正常情况下,用户的输入是作为参数值的,而在 SQL 注入中,用户的输入是作为 SQL 指令的一部分,会被数据库进行编译/解释执行。当使用了 PreparedStatement,带占位符 ( ? ) 的 sql 语句只会被编译一次,之后执行只是将占位符替换为用户输入,并不会再次编译/解释,因此从根本上防止了 SQL 注入问题。  更详细和准确的回答,请参考:  https://stackoverflow.com/a/34126564/6467552  Mybatis  介绍  1、首个 class persistence framework  2、介于 JDBC (raw SQL) 和 Hibernate (ORM)  3、简化绝大部分 JDBC 代码、手工设置参数和获取结果  4、灵活,使用者能够完全控制 SQL,支持高级映射  更多请参考: http://www.mybatis.org  说明  在 MyBatis 中,使用 XML 文件 或 Annotation 来进行配置和映射,将 interfaces 和 Java POJOs (Plain Old Java Objects) 映射到 database records  XML 例子  Mapper Interface  XML 配置文件  Annotation 例子  可以看到,使用者需要自己编写 SQL 语句,因此当使用不当时,会导致注入问题  与使用 JDBC 不同的是,MyBatis 使用 #{} 和 ${} 来进行参数值替换  使用 #{} 语法时,MyBatis 会自动生成 PreparedStatement ,使用参数绑定 ( ?) 的方式来设置值,上述两个例子等价的 JDBC 查询代码如下:  因此 #{} 可以有效防止 SQL 注入,详细可参考 http://www.mybatis.org/mybatis-3/sqlmap-xml.html String Substitution 部分  而使用 ${} 语法时,MyBatis 会直接注入原始字符串,即相当于拼接字符串,因而会导致 SQL 注入,如  name 值为 ' or '1'='1,实际执行的语句为  因此建议尽量使用 #{},但有些时候,如 order by 语句,使用 #{} 会导致出错,如  sortBy 参数值为 name ,替换后会成为  即以字符串 “name” 来排序,而非按照 name 字段排序,详细可参考 https://stackoverflow.com/a/32996866/6467552  这种情况就需要使用 ${}  使用了 ${}后,使用者需要自行过滤输入,方法有:  代码层使用白名单的方式,限制 sortBy 允许的值,如只能为 name, email 字段,异常情况则设置为默认值 name在 XML 配置文件中,使用 if 标签来进行判断  Mapper 接口方法  xml 配置文件  因为 Mybatis 不支持 else,需要默认值的情况,可以使用 choose(when,otherwise)  更多场景  除了 orderby之外,还有一些可能会使用到 ${} 情况,可以使用其他方法避免,如  like 语句  如需要使用通配符 ( wildcard characters % 和 _) ,可以在代码层,在参数值两边加上 %,然后再使用 #{} 使用 bind 标签来构造新参数,然后再使用 #{}  Mapper 接口方法  xml 配置文件  <bind>语句内的 value 为 OGNL expression,具体可参考 http://www.mybatis.org/mybatis-3/dynamic-sql.htmlbind 部分  使用 SQL concat() 函数  除了注入问题之外,这里还需要对用户的输入进行过滤,不允许有通配符,否则在表中数据量较多的时候,假设用户输入为 %%,会进行全表模糊查询,严重情况下可导致 DOS  参考  http://www.tothenew.com/blog/sql-wildcards-is-your-application-safe  IN 条件  使用 和 #{}  Mapper 接口方法  xml 配置文件  具体可参考 http://www.mybatis.org/mybatis-3/dynamic-sql.html foreach 部分  limit 语句  1、直接使用 #{} 即可  2、Mapper 接口方法  xml 配置文件  JPA & Hibernate  介绍  JPA:  1、全称 Java Persistence API  2、ORM (object-relational mapping) 持久层 API,需要有具体的实现  更多请参考 https://en.wikipedia.org/wiki/JavaPersistenceAPI  Hibernate:  JPA ORM 实现  更多请参考 http://hibernate.org  说明  这里有一种错误的认识,使用了 ORM 框架,就不会有 SQL 注入。而实际上,在 Hibernate 中,支持 HQL (Hibernate Query Language) 和 native sql 查询,前者存在 HQL 注入,后者和之前 JDBC 存在相同的注入问题,来具体看一下  HQL  HQL 查询例子  这里的 User 为类名,和原生 SQL 类似,拼接会导致注入  正确的用法:  位置参数 (Positional parameter)  命名参数 (named parameter)  命名参数 list (named parameter list)  类实例 (JavaBean)  Native SQL  存在 SQL 注入  使用参数绑定来设置参数值  JPA  JPA 中使用 JPQL (Java Persistence Query Language),同时也支持 native sql,因此和 Hibernate 存在类似的问题,这里就不再细说

(编辑:辽源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读