简单聊一聊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 8.0 之不可见列的基本操作
May 20 MySQL
MySQL大小写敏感的注意事项
May 24 MySQL
MySQL GRANT用户授权的实现
Jun 18 MySQL
MySql 缓存查询原理与缓存监控和索引监控介绍
Jul 02 MySQL
MySQL系列之十一 日志记录
Jul 02 MySQL
sql注入教程之类型以及提交注入
Aug 02 MySQL
MySQL如何解决幻读问题
Aug 07 MySQL
MySQL 用 limit 为什么会影响性能
Sep 15 MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
Oct 16 MySQL
Mysql关于数据库是否应该使用外键约束详解说明
Oct 24 MySQL
mysql timestamp比较查询遇到的坑及解决
Nov 27 MySQL
详解MySQL的主键查询为什么这么快
Apr 03 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获取当前完整URL地址的函数
2014/12/21 PHP
PHP模板引擎Smarty内置变量调解器用法详解
2016/04/11 PHP
php中让人头疼的浮点数运算分析
2016/10/10 PHP
疯掉了,尽然有js写的操作系统
2007/04/23 Javascript
JavaScript实现网页上的浮动广告的简单方法
2013/06/14 Javascript
javascript感应鼠标图片透明度显示的方法
2015/02/24 Javascript
jquery实现简单的轮换出现效果实例
2015/07/23 Javascript
以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题
2015/11/13 Javascript
jQuery Easy UI中根据第一个下拉框选中的值设置第二个下拉框是否可以编辑
2016/11/29 Javascript
Vue.js使用v-show和v-if的注意事项
2016/12/13 Javascript
原生js实现节日时间倒计时功能
2017/01/18 Javascript
Bootstrap BootstrapDialog使用详解
2017/02/17 Javascript
Puppet的一些技巧
2018/09/17 Javascript
基于JS实现前端压缩上传图片的实例代码
2019/05/14 Javascript
JavaScript中使用Spread运算符的八种方法总结
2020/06/18 Javascript
uniapp微信小程序实现一个页面多个倒计时
2020/11/01 Javascript
django实现前后台交互实例
2017/08/07 Python
《Python学习手册》学习总结
2018/01/17 Python
浅谈python可视化包Bokeh
2018/02/07 Python
python修改list中所有元素类型的三种方法
2018/04/09 Python
在python中bool函数的取值方法
2018/11/01 Python
浅谈Python接口对json串的处理方法
2018/12/19 Python
python爬虫 模拟登录人人网过程解析
2019/07/31 Python
python框架Django实战商城项目之工程搭建过程图文详解
2020/03/09 Python
Python2 与Python3的版本区别实例分析
2020/03/30 Python
keras在构建LSTM模型时对变长序列的处理操作
2020/06/29 Python
HTML5+CSS3应用详解
2014/02/24 HTML / CSS
茵宝(Umbro)英国官方商店:英国足球服装生产商
2016/12/29 全球购物
ghd澳大利亚官方网站:英国最受欢迎的美发工具品牌
2018/05/21 全球购物
几个常见的软件测试问题
2016/09/07 面试题
房产分割协议书范文
2014/11/21 职场文书
出纳年终工作总结2014
2014/12/05 职场文书
学生会招新宣传语
2015/07/13 职场文书
2019商业计划书格式、范文
2019/04/24 职场文书
Python+Selenium实现抖音、快手、B站、小红书、微视、百度好看视频、西瓜视频、微信视频号、搜狐视频、一点号、大风号、趣头条等短视频自动发布
2022/04/13 Python
讲解Python实例练习逆序输出字符串
2022/05/06 Python