MySQL的SQL注入问题

一、老生常谈的SQL注入如何实现

估计大部分都知道方法:任意内容 ’ or 永真语句 注释符,这种方式实现。通过or表示或,与永为真语句搭配保持前面部分永远真,然后用注释符屏蔽掉后面实现条件永为真的操作。

二、为什么通过占位符方式可以避免SQL注入

打Java操作数据库的例子来说。
Java通过PreparedStatement类执行SQL语句时,SQL语句中变量用?来代替,之后对SQL语句进行预编译。PreparedStatement再调用set方式传入下标和变量进行赋值,再执行SQL语句。这期间,SQL预编译后下次传进来的内容,直接针对这些内容操作就好。比如

select * from user where name = ? and pwd=?

这先把sql语句编译,之后执行。就算传入例如:name:abc‘ or 1=1 #,pwd:111,也会把“abc‘ or 1=1 #”单独当做一个name值进行匹配。结果就是匹配不到,防止了SQL注入。

三、MySQL中的注释符(#和–的区别)

MySQL中注释有两种方式:
①#注释内容
②-- 注释内容(注意–后面与注释内容之间要有空格)
下面用四张sql注入试验结果,表名两种注释加与不加空格结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从上面四幅图看出,sql注入时,#后面加与不加空格都成功了。而在使用–时,–后面必须加空格才生效,不加空格个则会被检查出语法错误。

四、附上此文章中用到的代码和数据库表

代码部分可到main函数去放掉对应方法的注释,另外代码开头部分的数据库也要根据个人数据库进行修改,我的数据库是5.5版本的MySQL,url中test是我存放之后数据库表对应的库名,user和password请根据个人连接数据库用到的名字和密码进行修改的。如果是普通Java项目,还需要到网上下载对应的数据库驱动jar包,并应用到当前项目。

package JdbcDemo;

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

public class jdbcdemo {
    static Connection connection;
    static Statement statement;
    static PreparedStatement preparedStatement;
    private static final String driver = "com.mysql.jdbc.Driver";
    private static final String url = "jdbc:mysql://localhost:3306/test";
    private static final String user = "root";
    private static final String password = "318523";
    //数据库操作练习
    public static void OperateDatabase() {
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user, password);
            if (!connection.isClosed()) {
                System.out.println("Database connection success.");
//                statement=connection.createStatement();
//                String name="xiaojun";
//                int age=40;
//                String sql = "insert into student(name,age) values('"+name+"','"+age+"') ";
//                int count = statement.executeUpdate(sql);


                String sql = "insert into student values(?,?) ";
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setString(1, "xiaohong");
                preparedStatement.setInt(2, 19);
                int count = preparedStatement.executeUpdate();
                if (count > 0) {
                    System.out.println("insert success.");
                }
            } else {
                System.out.println("Database connection failed.");
                return;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (preparedStatement != null) preparedStatement.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //sql注入,Statement类执行测试
    public static void SQLInjectStatement() {
        ResultSet resultSet=null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user, password);
            if (!connection.isClosed()) {
                System.out.println("Database connection success.");
                Statement statement = connection.createStatement();
                String name;
                String pwd;
                Scanner scanner = new Scanner(System.in);
                System.out.println("input name:");
                name = scanner.nextLine();
                System.out.println("input pwd");
                pwd = scanner.nextLine();
                String sql = "select * from user where name ='"+name+"'and pwd ='"+pwd+"'";
                 resultSet = statement.executeQuery(sql);
                if(resultSet.next()){
                    System.out.println("Login successfully!");
                }else {
                    System.out.println("Login failed.");
                }
            } else {
                System.out.println("Database connection failed.");
                return;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if(resultSet!=null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //sql注入,PrepareStatement执行测试
    public static void SQLInjectPrepareStatement() {
        ResultSet resultSet=null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user, password);
            if (!connection.isClosed()) {
                System.out.println("Database connection success.");
                String sql = "select * from user where name =? and pwd =?";
                preparedStatement = connection.prepareStatement(sql);
                String name;
                String pwd;
                Scanner scanner = new Scanner(System.in);
                System.out.println("input name:");
                name = scanner.nextLine();
                System.out.println("input pwd");
                pwd = scanner.nextLine();
                preparedStatement.setString(1,name);
                preparedStatement.setString(2,pwd);
                resultSet = preparedStatement.executeQuery();
                if(resultSet.next()){
                    System.out.println("Login successfully!");
                }else {
                    System.out.println("Login failed.");
                }
            } else {
                System.out.println("Database connection failed.");
                return;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if(resultSet!=null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        //OperateDatabase();
        //SQLInjectStatement();
        SQLInjectPrepareStatement();
        return;
    }
}

用到的数据库表,为了测试比较简单
student表

FieldTypeNullKeyDefaultExtra
namevarchar(10)YESNULL
agetinyint(4)YESNULL

user表

FieldTypeNullKeyDefaultExtra
namevarchar(10)YESNULL
pwdvarchar(10)YESNULL

最后,如果对文章有什么疑问或者问题,欢迎留言

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值