SQL注入与防范

2018-06-18 02:53:52来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

首先给大家看个例子:

1)小编首先在数据库中建立了一张测试表logintable,表内有一条测试信息:

然后写了个测试程序:

package com.java.SqlInject;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SqlInject {

    private static String Driver="com.mysql.jdbc.Driver"; //数据库驱动
    //连接数据库的URL地址
    private static String url="jdbc:mysql://localhost:3306/hellojdbc?useUnicode=true&characterEncoding=UTF-8";
    private static String username="root";//数据库连接用户名
    private static String password="123456";//数据库连接密码
    
    private static Connection conn=null;//数据库连接对象
    private static Statement stat=null;//语句陈述对象
    private static ResultSet rs=null;//结果数据集
    private static PreparedStatement pst=null;//预编译语句
    
    
    //使用静态块的方式加载驱动
        static {
            try {
                //调用Class对象的静态forName()方法加载数据库驱动类
                Class.forName(Driver);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            
        }
        
        //使用单例模式返回数据库连接对象
        public static Connection getConnection() throws SQLException{
            if(conn==null){
                conn=DriverManager.getConnection(url, username, password);
                return conn;
            }
            return conn;

        } 
        
        
        
        public static void login(String name,String password){
            try {
                conn=getConnection();
                stat=conn.createStatement();
                //使用动态拼接的方式拼接sql语句
                rs=stat.executeQuery("select * from logintable where name='"+name+"' and password='"+password+"'");
                if(rs.next()){
                    System.out.println("用户已注册");
                }else
                    System.out.println("无记录");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        
        
        
    
    public static void main(String[] args) {
        login("zhangsan","123456");

    }

}

输出结果为:

2)然后我们修改main()方法中,login()方法调用时的参数,改为:

public static void main(String[] args) {
        login("zhangsan","123");

    }

执行结果:

3)似乎一切都天经地义,没什么问题。但是这时我们再对login()方法调用的参数做一下修改:

public static void main(String[] args) {
        //注意:第一个参数两个短杠后面有空格
        login("zhangsan';-- ","123");

    }

测试执行结果又变成了:

明明用户名和密码都不对,数据库中也没有这条记录,为什么会出现这种情况?

这就是SQL注入带来的漏洞问题

恶意用户通过伪装请求,来骗过我们的业务程序,达到获取数据库核心数据的目的。

通过上面的例子,我们可以看到我们最后一次改写参数来调用login()方法的时候,java业务程序中接收到的不是我们期望的那个sql语句。

由于分号的存在,使得我们的sql语句拼接后完变成了这样:

select * from logintable where name='zhangsan';
--  'password='123';

这样就由一条sql语句变成了两条sql语句。在第一条的sql语句中去掉了密码的检索条件,同时注释掉了第二条sql语句。

(两个横线为注释符)

总结一下:

SQL注入就是用户在输入表单或者URL参数中输入SQL命令,到达欺骗应用程序的目的,破坏原有SQL的语义,发送恶意的SQL到后端数据库,导致数据库信息出现泄露的漏洞。

发生这种漏洞的原因是:

我们的sql语句是通过动态拼接组成的,在拼接完成之前,sql语句是不完整的,所以当在拼接时新加入的参数中有sql命令的注入就有可能改变原有的sql语义。

比方像上面的例子中,密码被恶意地屏蔽注释掉了。

解决方法:

传入外部参数时,不使用动态拼接的方式拼接sql语句;使用参数化方式的sql实现方式(格式化,占位符),即使用预编译的statement。

然后传参:

所以上面例子中相关代码应修改为:

                conn=getConnection();
                //stat=conn.createStatement();
                //使用组合的方式拼接sql语句
                //rs=stat.executeQuery("select * from logintable where name='"+name+"' and password='"+password+"'");
                
                pst=conn.prepareStatement("select * from logintable where name= ? and password= ?");
                pst.setString(1, name);
                pst.setString(2, password);
                rs=pst.executeQuery();
                
                if(rs.next()){
                    System.out.println("用户已注册");
                }else
                    System.out.println("无记录");

其他注意事项:


 

使用严格的数据库管理权限:

1.仅给予Web应用访问数据库的最小权限;

2.避免Drop table等权限。

封装数据库错误:

1.禁止直接将后端数据库异常信息暴露给用户;

2.对后端异常信息进行必要的封装,避免用户直接查看到后端异常。

机密信息禁止明文存储:

1.涉密信息需要加密处理;

2.使用AES_ENCRYPT/AES_DECRYPT加密和解密。

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:activemq5.14.5单节点安装Demo

下一篇:java基础 UDP通信 user datagram protocol 用户数据豆协议 TCP t