简单聊一聊SQL注入及防止SQL注入


Posted in MySQL onMarch 23, 2022

SQL注入

SQL注入是通过操作输入来修改事先定义好的SQL语句,对用户输入的字符串进行过滤,转义,限制或处理不严谨,导致用户可以通过输入精心构造的字符串去非法获取到数据库中的数据,以达到执行代码对服务器进行攻击的方法。

现有一个数据库test中的表user,可以通过账号name,密码pass登录,查看id

简单聊一聊SQL注入及防止SQL注入

登录代码

package JDBCtest;

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

/*
 * 用户登录
 */
public class Demo4 {

    public static void main(String[] args) throws Exception {
        // 1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2.创建连接
        String url = "jdbc:mysql:///test";
        String username = "root";
        String password = "1234";
        Connection connection = DriverManager.getConnection(url, username, password);
        // 接收用户名密码
        Scanner sc = new Scanner(System.in);
        String name = sc.next();
        String pass = sc.next();// 3.sql语句
        String sql = "Select * from user where name='" + name + "' and pass ='" + pass + "'";
        // System.out.println(sql);
        // 4.获取sql对象statement
        Statement statement = connection.createStatement();
        // 5.执行sql语句
        ResultSet rs = statement.executeQuery(sql);
                // 6.登录
        if (rs.next()) {
            System.out.println("登录成功");
        } else {
            System.out.println("登录失败");
        }
        // 7.释放资源
        statement.close();
        connection.close();
    }
}

通过表中账号密码登录成功

简单聊一聊SQL注入及防止SQL注入简单聊一聊SQL注入及防止SQL注入

由于账号或密码错误登录失败

简单聊一聊SQL注入及防止SQL注入简单聊一聊SQL注入及防止SQL注入

以上可以正确登录成功或失败

注意!

如果此时我这样输入 【lihua 'or'1'='1】,也成功登录了,但是数据库没根本没有这条数据

简单聊一聊SQL注入及防止SQL注入

这是为什么呢?让我们从代码里找问题!

String sql = "Select * from user where name='" + name + "' and pass ='" + pass + "'";

为了调用数据库,使用字符串拼接SQL语句

让我们打印一下输入 【lihua 'or'1'='1】的sql语句一探究竟

简单聊一聊SQL注入及防止SQL注入

select语句中的where条件可以看做两组并列(注意and在前先执行,or后执行)

简单聊一聊SQL注入及防止SQL注入

由于'1'='1'为TRUE,所以以上语句等价于简单聊一聊SQL注入及防止SQL注入肯定会登录成功!

同理输入【'or'1'='1'# xxx】也能登陆成功

简单聊一聊SQL注入及防止SQL注入

这是由于#在SQL中是注释符号,以上语句等价于简单聊一聊SQL注入及防止SQL注入,于是就和上述情况一样了。

附防止sql注入的一些建议

1. 代码层防止sql注入攻击的最佳方案就是sql预编译

public List<Course> orderList(String studentId){
    String sql = "select id,course_id,student_id,status from course where student_id = ?";
    return jdbcTemplate.query(sql,new Object[]{studentId},new BeanPropertyRowMapper(Course.class));
}

这样我们传进来的参数 4 or 1 = 1就会被当作是一个student_id,所以就不会出现sql注入了。

2. 确认每种数据的类型,比如是数字,数据库则必须使用int类型来存储

3. 规定数据长度,能在一定程度上防止sql注入

4. 严格限制数据库权限,能最大程度减少sql注入的危害

5. 避免直接响应一些sql异常信息,sql发生异常后,自定义异常进行响应

6. 过滤参数中含有的一些数据库关键词

@Component
public class SqlInjectionFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req=(HttpServletRequest)servletRequest;
        HttpServletRequest res=(HttpServletRequest)servletResponse;
        //获得所有请求参数名
        Enumeration params = req.getParameterNames();
        String sql = "";
        while (params.hasMoreElements()) {
            // 得到参数名
            String name = params.nextElement().toString();
            // 得到参数对应值
            String[] value = req.getParameterValues(name);
            for (int i = 0; i < value.length; i++) {
                sql = sql + value[i];
            }
        }
        if (sqlValidate(sql)) {
            throw new IOException("您发送请求中的参数中含有非法字符");
        } else {
            chain.doFilter(servletRequest,servletResponse);
        }
    }

    /**
     * 关键词校验
     * @param str
     * @return
     */
    protected static boolean sqlValidate(String str) {
        // 统一转为小写
        str = str.toLowerCase();
        // 过滤掉的sql关键字,可以手动添加
        String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" +
                "char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +
                "table|from|grant|use|group_concat|column_name|" +
                "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" +
                "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";
        String[] badStrs = badStr.split("\\|");
        for (int i = 0; i < badStrs.length; i++) {
            if (str.indexOf(badStrs[i]) >= 0) {
                return true;
            }
        }
        return false;
    }
}

总结

到此这篇关于SQL注入及防止SQL注入的文章就介绍到这了,更多相关防止SQL注入内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL获取所有分类的前N条记录
May 07 MySQL
MySQL REVOKE实现删除用户权限
Jun 18 MySQL
MySQL系列之十三 MySQL的复制
Jul 02 MySQL
MySQL一些常用高级SQL语句
Jul 03 MySQL
mysql中varchar类型的日期进行比较、排序等操作的实现
Nov 17 MySQL
SQL注入详解及防范方法
Dec 06 MySQL
分享MySQL常用 内核 Debug 几种常见方法
Mar 17 MySQL
MySQL读取JSON转换的方式
Mar 18 MySQL
MySQL创建管理LIST分区
Apr 13 MySQL
Mysql索引失效 数据库表中有索引还是查询很慢
May 15 MySQL
MySQL普通表如何转换成分区表
May 30 MySQL
Mysql表数据比较大情况下修改添加字段的方法实例
Jun 28 MySQL
浅谈MySQL中的六种日志
Mar 23 #MySQL
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
实战 快速定位MySQL的慢SQL
关于MySQL临时表为什么可以重名的问题
将MySQL的表数据全量导入clichhouse库中
Mar 21 #MySQL
MySQL分区表管理命令汇总
Mar 21 #MySQL
Linux系统下MySQL配置主从分离的步骤
You might like
PHP中模拟链表和链表的基本操作示例
2016/02/27 PHP
Django 中 cookie的使用
2017/08/17 PHP
Laravel 实现添加多语言提示信息
2019/10/25 PHP
js本身的局限性 别让javascript做太多事
2010/03/23 Javascript
jQuery之自动完成组件的深入解析
2013/06/19 Javascript
Function.prototype.call.apply结合用法分析示例
2013/07/03 Javascript
javascript获取设置div的高度和宽度兼容任何浏览器
2013/09/22 Javascript
node.js WEB开发中图片验证码的实现方法
2014/06/03 Javascript
javascript相关事件的几个概念
2015/05/21 Javascript
jQuery实现打开页面渐现效果示例
2016/07/27 Javascript
微信小程序 封装http请求实例详解
2017/01/16 Javascript
JS控件bootstrap suggest plugin使用方法详解
2017/03/25 Javascript
javascript简单链式调用案例分析
2017/05/10 Javascript
Vue.extend构造器的详解
2017/07/17 Javascript
Windows下快速搭建NodeJS本地服务器的步骤
2017/08/09 NodeJs
详解在vue-cli中使用路由
2017/09/25 Javascript
完美解决linux下node.js全局模块找不到的情况
2018/05/16 Javascript
微信小程序自定义tab实现多层tab嵌套功能
2018/06/15 Javascript
vue router的基本使用和配置教程
2018/11/05 Javascript
原来JS还可以这样拆箱转换详解
2019/02/01 Javascript
详解vuejs2.0 select 动态绑定下拉框支持多选
2019/04/25 Javascript
nodejs如何在package.json中设置多条启动命令
2020/03/16 NodeJs
Javascript执行流程细节原理解析
2020/05/14 Javascript
[04:14]从西雅图到上海——玩家自制DOTA2主题歌曲应援TI9
2019/07/11 DOTA
python操作gmail实例
2015/01/14 Python
Python中解析JSON并同时进行自定义编码处理实例
2015/02/08 Python
python中requests小技巧
2017/05/10 Python
Python IDLE入门简介
2017/12/08 Python
python创建文件时去掉非法字符的方法
2018/10/31 Python
python 使用pdfminer3k 读取PDF文档的例子
2019/08/27 Python
美国领先的在线邮轮旅游公司:CruiseDirect
2018/06/07 全球购物
铁路工务反思材料
2014/02/07 职场文书
元旦文艺汇演主持词
2014/03/26 职场文书
普通员工辞职信范文
2015/05/12 职场文书
公司仓库管理制度
2015/08/04 职场文书
什么是Python装饰器?如何定义和使用?
2022/04/11 Python