SQL注入现象_实例总结
Posted 葡萄籽-June
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL注入现象_实例总结相关的知识,希望对你有一定的参考价值。
SQL注入——了解🐎?
本文主要内容:在通过使用基础的JDBC驱动连接数据库时,遇到的代码注入安全性问题。在初学的过程中大家会忽略的、值得注意的安全性问题做一个了解,同时总结学习去如何解决、避免这个基础的安全问题。
前言
SQL注入主要的概念应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
由上述定义可知,其实是数据库安全有关的问题(SQL注入可以理解为通过SQL语言的修改以达到获取数据库存储信息的安全危机)。
那不禁要思考了:
——在代码中为什么会发生这种现象?
——编程人员如何规避这种风险?
下面,我们就通过一些实例讲解其发生的原因以及相对应的解决办法。
一、SQ注入过程
首先,我们先看一个SQL语句:
select * from employees where password=‘tim’ or '1'='1';
上述 SQL语句中【 or ‘1’=‘1’】只要在查询语句中,那么前面的 where 条件是没有用处的。
在数据库中,确实有这样的语句是可以进行查询的,但是如果操作数据库的是一名数据库管理人员,那么也没什么问题,如果只是有权限或无权限的访问数据库中相应的数据呢?
那么作为编程人员,我们不会直接与数据库打交道,我们最直接打交道的便是程序代码。那么我们进行操作数据库时,何时会发生这种现象呢?——在我们应用JDBC数据库驱动时,有创建数据库对象的相应操作。我们会通过数据库对象去执行相应的SQL语句以此来获取我们需要的数据。JDBC中有一个数据库操作对象 Statement 它在操作的时候就会出现SQL注入现象。
(使用JDBC驱动连接数据库的具体总结可以看这篇☞JDBC总结 )
那么, Statement 为何会发生SQL注入现象呢?
下面我们就通过一个例子来了解一下。
Class.forName("com.mysql.jdbc.Driver");
// 2、 连接数据库
String url = "jdbc:mysql://localhost:3306/myemployees?autoReconnect=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true";
String user = "root";
String password = "root";
conn = DriverManager.getConnection(url, user, password);
// 3、创建数据库对象
stmt = conn.createStatement();
// 4、执行sql语句
String sql = "select * from employees where employees_id = 1 or '"+1+"'='"+1+"' ";
rs = stmt.executeQuery(sql);
上述SQL注入过程:用户输入了 【or ‘1’=‘1’】,并且它被当作SQL语句编译成功了。当它执行完sql语句后,它会执行【rs = stmt.executeQuery(sql);】,把sql语句发送给DBMS,DBMS再编译它,此时编译已经晚了(安全性低),用户“非法拼接”的SQL语句已经拼接进去了。从而导致原SQL语句的含义被扭曲。
由上述举例可知,SQL注入的根本原因:用户输入的信息中含有SQL语句的关键字,并且这些关键字参与SQL语句的编译过程。导致了SQL语句的原意被扭曲,进而完成了SQL注入。
二、如何解决SQL注入
由上述可知,问题出现的原因主要是2方面。
- 第一方面,是由于Statement 对象时先把用户输入的sql语句发送给DBMS。此时用户非法拼接的sql语句已经被拼接进去,在编译,就会被窃取数据库中的信息。
- 第二方面,是由于SQL语句本身的关键字能够正常编译。(在数据库管理员角色是具有益处,在程序上会有安全性问题。)
PreparedStatement 不会直接把SQL语句发送给DBMS,它会先进行预编译,做安全性检查,检查通过后在执行相关操作。
解决SQL注入现象: 使用 PreparedStatement 数据库操作对象。
只要用户提供的信息不参与SQL语句的编译过程,就可以解决。
即使用户提供的信息中含有SQL语句的关键字,但是没有参与编译,那就不会起作用。
要想用户信息不参与SQL语句的编译,那么必须使用java.sql.PreparedStatement
PreparedStatement接口继承了java.sql.Statement
PreparedStatement属于预编译的数据库操作对象
PreparedStatement原理:预先对SQL语句的框架进行编译,然后再给SQL语句传“值”。
PreparedStatement 的作用刚好能够规避上述用户非法拼接的SQL注入现象。
具体操作:(此处只是部分代码块)
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2、连接数据库
String url = "jdbc:mysql://localhost:3306/myemployees?characterEncoding=utf8";
String user = "root";
String password = "root";
conn=DriverManager.getConnection(url,user,password);
// 3、获取预编译的数据库操作对象
//SQL语句的?,表示一个占位符。一个?接受一个值。【注】占位符不可使用单引号
String sql = "select * from employees where loginName= ? and loginPwd= ? ";
//程序执行到此,会发送sql语句给DBMS。然后DBMS进行sql语句的预先编译。
pstmt= conn.prepareStatement(sql);
//给占位符?传值,第一个问号下标是1,第二个?下标是2。【注】JDBC中,所有下标从1开始
pstmt.setString(1,loginName);
pstmt.setString(2,loginPwd);
// 4、执行sql语句
rs=pstmt.executeQuery();
// 5、处理查询结果集
if (rs.next()){
//登陆成功
}
总结
其实SQL注入的注入方式有很多种,在这里不一一详述。只是通过一个简单的栗子进行了解SQL注入的现象,以及如何规避简单的注入问题。
今天就先分享到这吧~欢迎三连o!
以上是关于SQL注入现象_实例总结的主要内容,如果未能解决你的问题,请参考以下文章
安全测试 web安全测试 常规安全漏洞 可能存在SQL和JS注入漏洞场景分析。为什么自己没有找到漏洞,哪么可能存在漏洞场景是?SQL注入漏洞修复 JS注入漏洞修复 漏洞存在场景分析和修复示例(代码片段