简单聊一聊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知识点整理
Apr 05 MySQL
mysql多表查询-笔记七
Apr 05 MySQL
Windows10下安装MySQL8
Apr 06 MySQL
mysql联合索引的使用规则
Jun 23 MySQL
SQL实现LeetCode(197.上升温度)
Aug 07 MySQL
MySQL创建定时任务
Jan 22 MySQL
一次Mysql update sql不当引起的生产故障记录
Apr 01 MySQL
MySQL去除密码登录告警的方法
Apr 20 MySQL
Mysql 数据库中的 redo log 和 binlog 写入策略
Apr 26 MySQL
MySQL范围查询优化的场景实例详解
Jun 10 MySQL
MySQL数据库实验实现简单数据库应用系统设计
Jun 21 MySQL
SQLServer常见数学函数梳理总结
Aug 05 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
smarty模板引擎之内建函数用法
2015/03/30 PHP
YiiFramework入门知识点总结(图文教程)
2015/12/28 PHP
全面解析PHP验证码的实现原理 附php验证码小案例
2016/08/17 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
2017/12/26 PHP
Javascript中获取出错代码所在文件及行数的代码
2010/09/23 Javascript
ASP.NET jQuery 实例10 动态修改hyperlink的URL值
2012/02/03 Javascript
js 代码优化点滴记录
2012/02/19 Javascript
js实现使用鼠标拖拽切换图片的方法
2015/05/04 Javascript
.NET微信公众号开发之创建自定义菜单
2015/07/16 Javascript
原生JS实现垂直手风琴效果
2017/02/19 Javascript
AngularJS折叠菜单实现方法示例
2017/05/18 Javascript
js实现城市级联菜单的2种方法
2017/06/23 Javascript
给localStorage设置一个过期时间的方法分享
2018/11/06 Javascript
jQuery实现为table表格动态添加或删除tr功能示例
2019/02/19 jQuery
浅谈Vue.use到底是什么鬼
2020/01/21 Javascript
JS中FormData类实现文件上传
2020/03/27 Javascript
nodeJS与MySQL实现分页数据以及倒序数据
2020/06/05 NodeJs
python中利用队列asyncio.Queue进行通讯详解
2017/09/10 Python
django启动uwsgi报错的解决方法
2018/04/08 Python
python实现电脑自动关机
2018/06/20 Python
django2.0扩展用户字段示例
2019/02/13 Python
python3中eval函数用法使用简介
2019/08/02 Python
python 命令行传入参数实现解析
2019/08/30 Python
Django模板之基本的 for 循环 和 List内容的显示方式
2020/03/31 Python
python 实现波浪滤镜特效
2020/12/02 Python
携程英文网站:Trip.com
2017/02/07 全球购物
SQL Server 2000数据库的文件有哪些,分别进行描述。
2015/11/09 面试题
工商企业管理应届生求职信
2013/11/03 职场文书
中医临床专业自我鉴定范文
2014/01/15 职场文书
乔丹名人堂演讲稿
2014/05/24 职场文书
教育合作协议范本
2014/10/17 职场文书
本科毕业论文答辩稿
2015/06/23 职场文书
vue完美实现el-table列宽自适应
2021/05/08 Vue.js
Python数据可视化之绘制柱状图和条形图
2021/05/25 Python
python 批量压缩图片的脚本
2021/06/02 Python
React列表栏及购物车组件使用详解
2021/06/28 Javascript