简单聊一聊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查询语句的执行过程
May 07 MySQL
MySQL中你可能忽略的COLLATION实例详解
May 12 MySQL
MYSQL(电话号码,身份证)数据脱敏的实现
May 28 MySQL
MySQL子查询中order by不生效问题的解决方法
Aug 02 MySQL
一次MySQL启动导致的事故实战记录
Sep 15 MySQL
教你使用VS Code的MySQL扩展管理数据库的方法
Jan 22 MySQL
一文了解MySQL二级索引的查询过程
Feb 24 MySQL
进阶篇之linux环境下安装MySQL数据库
Apr 09 MySQL
优化Mysql查询的示例
Apr 26 MySQL
解决Mysql中的innoDB幻读问题
Apr 29 MySQL
mysql5.5中文乱码问题解决的有用方法
May 30 MySQL
Mysql如何查看是否使用到索引
Dec 24 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
十大感人催泪爱情动漫 第一名至今不忍在看第二遍
2020/03/04 日漫
正则表达式语法
2006/10/09 Javascript
用来解析.htpasswd文件的PHP类
2012/09/05 PHP
用JQuery 实现的自定义对话框
2007/03/24 Javascript
javascript 导出数据到Excel(处理table中的元素)
2009/12/18 Javascript
jquery+javascript编写国籍控件
2015/02/12 Javascript
浏览器复制插件zeroclipboard使用指南
2016/03/26 Javascript
jQuery事件绑定on()与弹窗实现代码
2016/04/28 Javascript
通用无限极下拉菜单的实现代码
2016/05/31 Javascript
微信小程序 实现tabs选项卡效果实例代码
2016/10/31 Javascript
JQuery页面随滚动条动态加载效果的简单实现(推荐)
2017/02/08 Javascript
BootStrap实现带关闭按钮功能
2017/02/15 Javascript
jQuery实现仿京东防抖动菜单效果示例
2018/07/06 jQuery
JavaScript实现简单验证码
2020/08/24 Javascript
[01:52]深扒TI7聊天轮盘语音出处7
2017/05/11 DOTA
[01:07:20]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第二场 2月2日
2021/03/11 DOTA
让python同时兼容python2和python3的8个技巧分享
2014/07/11 Python
Python的collections模块中namedtuple结构使用示例
2016/07/07 Python
Python实现读取文件最后n行的方法
2017/02/23 Python
python下os模块强大的重命名方法renames详解
2017/03/07 Python
我喜欢你 抖音表白程序python版
2019/04/07 Python
浅谈selenium如何应对网页内容需要鼠标滚动加载的问题
2020/03/14 Python
Pycharm Git 设置方法
2020/09/15 Python
python GUI计算器的实现
2020/10/09 Python
python实现杨辉三角的几种方法代码实例
2021/03/02 Python
塑料制成的可水洗的编织平底鞋和鞋子:Rothy’s
2018/09/16 全球购物
eVitamins日本:在线购买折扣维生素、补品和草药
2019/04/04 全球购物
大学生职业生涯规划书的基本内容
2014/01/06 职场文书
电子银行营销方案
2014/02/22 职场文书
幼儿园亲子活动总结
2014/04/26 职场文书
领导班子三严三实对照检查材料
2014/09/25 职场文书
导游词之平津战役纪念馆
2019/11/04 职场文书
详解MySQL多版本并发控制机制(MVCC)源码
2021/06/23 MySQL
在HTML中引入CSS的几种方式介绍
2021/12/06 HTML / CSS
vue elementUI表格控制对应列
2022/04/13 Vue.js
Spring Boot项目如何优雅实现Excel导入与导出功能
2022/06/10 Java/Android