简单聊一聊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 22 MySQL
MySQL时间盲注的五种延时方法实现
May 18 MySQL
MySQL完整性约束的定义与实例教程
May 30 MySQL
Mysql文件存储图文详解
Jun 01 MySQL
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
Aug 02 MySQL
SQL实现LeetCode(178.分数排行)
Aug 04 MySQL
MySQL图形化管理工具Navicat安装步骤
Dec 04 MySQL
MySQL 表锁定 LOCK和UNLOCK TABLES的 SQL语法
Apr 18 MySQL
提高系统的吞吐量解决数据库重复写入问题
Apr 23 MySQL
sql查询语句之平均分、最高最低分及排序语句
May 30 MySQL
MySQL新手入门进阶语句汇总
Sep 23 MySQL
Mysql的Table doesn't exist问题及解决
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
php实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
PHP中的替代语法简介
2014/08/22 PHP
PHP遍历XML文档所有节点的方法
2015/03/12 PHP
yii添删改查实例
2015/11/16 PHP
在Yii2中使用Pjax导致Yii2内联脚本载入失败的原因分析
2016/03/06 PHP
php封装的page分页类完整实例
2016/10/18 PHP
接收键盘指令的脚本
2006/06/26 Javascript
用XMLDOM和ADODB.Stream实现base64编码解码实现代码
2010/11/28 Javascript
原生JS可拖动弹窗效果实例代码
2013/11/09 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
2016/09/01 Javascript
微信小程序 form组件详解
2016/10/25 Javascript
nodejs中使用HTTP分块响应和定时器示例代码
2017/03/19 NodeJs
浅谈Angular4中常用管道
2017/09/27 Javascript
Vue.js实现的表格增加删除demo示例
2018/05/22 Javascript
Angular父子组件通过服务传参的示例方法
2018/10/31 Javascript
vue组件中iview的modal组件爬坑问题之modal的显示与否应该是使用v-show
2019/04/12 Javascript
vue的列表交错过渡实现代码示例
2019/05/05 Javascript
基于javascript实现碰撞检测
2020/03/12 Javascript
解决Vue 移动端点击出现300毫秒延迟的问题
2020/07/21 Javascript
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
2020/09/21 Javascript
如何利用vue实现波谱拟合详解
2020/11/05 Javascript
[01:04:06]DOTA2上海特级锦标赛A组资格赛#2 Secret VS EHOME第一局
2016/02/26 DOTA
CentOS中使用virtualenv搭建python3环境
2015/06/08 Python
Python 单元测试(unittest)的使用小结
2018/11/14 Python
python爬虫 批量下载zabbix文档代码实例
2019/08/21 Python
Python使用qrcode二维码库生成二维码方法详解
2020/02/17 Python
css3的图形3d翻转效果应用示例
2014/04/08 HTML / CSS
美国最大最全的亚洲购物网站:美国亚米网(Yamibuy)
2020/05/05 全球购物
事业单位个人应聘自荐信
2013/09/21 职场文书
高一生物教学反思
2014/01/17 职场文书
党员个人年度总结
2015/02/14 职场文书
拉贝日记观后感
2015/06/05 职场文书
公务员廉洁从政心得体会
2016/01/19 职场文书
小型企业的绩效考核制度模板
2019/11/21 职场文书
《家世》读后感:看家训的力量
2019/12/30 职场文书
使用Django实现商城验证码模块的方法
2021/06/01 Python