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方面。

  1. 第一方面,是由于Statement 对象时先把用户输入的sql语句发送给DBMS。此时用户非法拼接的sql语句已经被拼接进去,在编译,就会被窃取数据库中的信息。
  2. 第二方面,是由于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注入现象_实例总结的主要内容,如果未能解决你的问题,请参考以下文章

sql注入

安全测试 web安全测试 常规安全漏洞 可能存在SQL和JS注入漏洞场景分析。为什么自己没有找到漏洞,哪么可能存在漏洞场景是?SQL注入漏洞修复 JS注入漏洞修复 漏洞存在场景分析和修复示例(代码片段

SQL注入漏洞总结

sql注入实例分析

谷歌搜索 PHP 教程一半以上含有 SQL 注入

Android 片段和依赖注入