加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

彻底干掉恶心的SQL注入裂痕, 一扫而空!

发布时间:2019-07-28 09:04:31 所属栏目:编程 来源:佚名
导读:简介 文章首要内容包罗: Java 耐久层技能/框架简朴先容 差异场景/框架下易导致 SQL 注入的写法 怎样停止和修复 SQL 注入 JDBC 先容 JDBC: 全称 Java Database Connectivity 是 Java 会见数据库的 API,不依靠于特定命据库 ( database-independent ) 全部
副问题[/!--empirenews.page--]

 彻底干掉恶心的SQL注入裂痕, 一扫而空!

简介

文章首要内容包罗:

  •     Java 耐久层技能/框架简朴先容
  •     差异场景/框架下易导致 SQL 注入的写法
  •     怎样停止和修复 SQL 注入

JDBC

先容

JDBC:

  •     全称 Java Database Connectivity
  •     是 Java 会见数据库的 API,不依靠于特定命据库 ( database-independent )
  •     全部 Java 耐久层技能都基于 JDBC

声名

直接行使 JDBC 的场景,假如代码中存在拼接 SQL 语句,那么很有也许会发生注入,如

  1. // concat sql  
  2.   String sql = "SELECT * FROM users WHERE name ='"+ name + "'";  
  3.   Statement stmt = connection.createStatement();  
  4.   ResultSet rs = stmt.executeQuery(sql); 

安详的写法是行使 参数化查询 ( parameterized queries ),即 SQL 语句中行使参数绑定( ? 占位符 ) 和 PreparedStatement,如 

  1. // use ? to bind variables  
  2.    String sql = "SELECT * FROM users WHERE name= ? ";  
  3.    PreparedStatement ps = connection.prepareStatement(sql);  
  4.    // 参数 index 从 1 开始  
  5.    ps.setString(1, name); 

尚有一些环境,好比 order by、column name,不能行使参数绑定,此时必要手工过滤,如凡是 order by 的字段名是有限的,因此可以行使白名单的方法来限定参数值

这里必要留意的是,行使了 PreparedStatement 并不料味着不会发生注入,假如在行使 PreparedStatement之前,存在拼接 sql 语句,那么如故会导致注入,如 

  1. // 拼接 sql  
  2.     String sql = "SELECT * FROM users WHERE name ='"+ name + "'";  
  3.     PreparedStatement ps = connection.prepareStatement(sql); 

看到这里,各人必定会好奇 PreparedStatement 是怎样防备 SQL 注入的,来相识一下

正常环境下,用户的输入是作为参数值的,而在 SQL 注入中,用户的输入是作为 SQL 指令的一部门,会被数据库举办编译/表明执行。

当行使了 PreparedStatement,带占位符 ( ? ) 的 sql 语句只会被编译一次,之后执行只是将占位符替代为用户输入,并不会再次编译/表明,因此从基础上防备了 SQL 注入题目。

Mybatis

先容

  •  首个 class persistence framework
  •  介于 JDBC (raw SQL) 和 Hibernate (ORM)
  •  简化绝大部门 JDBC 代码、手工配置参数和获取功效
  •  机动,行使者可以或许完全节制 SQL,支持高级映射

更多请参考: http://www.mybatis.org

声名

在 MyBatis 中,行使 XML 文件 或 Annotation 来举办设置和映射,将 interfaces 和 Java POJOs (Plain Old Java Objects) 映射到 database records。

XML 例子

Mapper Interface 

  1. @Mapper  
  2.    public interface UserMapper {  
  3.        User getById(int id);  
  4.    } 

XML 设置文件 

  1. <select id="getById" resultType="org.example.User">  
  2.        SELECT * FROM user WHERE id = #{id}  
  3.    </select> 

Annotation 例子 

  1. @Mapper  
  2.     public interface UserMapper {  
  3.         @Select("SELECT * FROM user WHERE id= #{id}")  
  4.         User getById(@Param("id") int id);  
  5.     } 

可以看到,行使者必要本身编写 SQL 语句,因此当行使不妥时,会导致注入题目与行使 JDBC 差异的是,MyBatis 行使 #{} 和 ${} 来举办参数值替代。保举:Mybatis转达多个参数的4种方法。

行使 #{} 语法时,MyBatis 会自动天生 PreparedStatement ,行使参数绑定 ( ?) 的方法来配置值,上述两个例子等价的 JDBC 查询代码如下:

  1. String sql = "SELECT * FROM users WHERE id = ?";  
  2.   PreparedStatement ps = connection.prepareStatement(sql);  
  3.   ps.setInt(1, id); 

因此 #{} 可以有用防备 SQL 注入,具体可参考 http://www.mybatis.org/mybatis-3/sqlmap-xml.html String Substitution 部门。

(编辑:湖南网)

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

热点阅读