如何有效防止sql注入的方法


Posted in SQL Server onMay 25, 2021

SQL注入攻击是黑客对数据库进行攻击常用的手段之一,随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多。但是由于程序员的水平及经验参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想获取的数据,这就是所谓的SQL Injection,即SQL注入。

一 背景

假如某高校开发了一个网课系统,要求学生选课后完成学习,数据库中有一张表course,这张表存放着每个学生的选课信息及完成情况,具体设计如下:

如何有效防止sql注入的方法

数据如下:

如何有效防止sql注入的方法

本系统采用mysql做为数据库,使用Jdbc来进行数据库的相关操作。系统提供了一个功能查询该学生的课程完成情况,代码如下。

@RestController
public class Controller {
    
    @Autowired
    SqlInject sqlInject;
    
    @GetMapping("list")
    public List<Course> courseList(@RequestParam("studentId") String studentId){
        List<Course> orders = sqlInject.orderList(studentId);
        return orders;
    }
}
@Service
public class SqlInject {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public List<Course> orderList(String studentId){
        String sql = "select id,course_id,student_id,status from course where student_id = "+ studentId;
        return jdbcTemplate.query(sql,new BeanPropertyRowMapper(Course.class));
    }
}

二 注入攻击演示

1. 正常情况下查询一个学生所选课程及完成情况只需要传入student_id,便可以查到相关数据。

如何有效防止sql注入的方法

根据响应结果,我们很快便能写出对应的sql,如下:

select id,course_id,student_id,status 
from course 
where student_id = 4

2. 如果我们想要获取这张表的所有数据,只需要保证上面这个sql的where条件恒真就可以了。

select id,course_id,student_id,status 
from course 
where student_id = 4 or 1 = 1

请求接口的时候将studendId 设置为4 or 1 = 1,这样这条sql的where条件就恒真了。sql也就等同于下面这样

select id,course_id,student_id,status 
from course

请求结果如下,我们拿到了这张表的所有数据

如何有效防止sql注入的方法

3. 查询mysql版本号,使用union拼接sql

union select 1,1,version(),1

如何有效防止sql注入的方法

4. 查询数据库名

union select 1,1,database(),1

如何有效防止sql注入的方法

5. 查询mysql当前用户的所有库

union select 1,1, (SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata) schemaName,1

如何有效防止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 Server 相关文章推荐
SQL Server连接查询的实用教程
Apr 07 SQL Server
SQLServer 日期函数大全(小结)
Apr 08 SQL Server
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
Jun 30 SQL Server
SQL写法--行行比较
Aug 23 SQL Server
Windows环境下实现批量执行Sql文件
Oct 05 SQL Server
SQL SERVER存储过程用法详解
Feb 24 SQL Server
通过T-SQL语句创建游标与实现数据库加解密功能
Mar 16 SQL Server
SQL Server中使用表变量和临时表
May 20 SQL Server
SQL Server使用T-SQL语句批处理
May 20 SQL Server
SQL Server中的逻辑函数介绍
May 25 SQL Server
SQL Server数据库备份和恢复数据库的全过程
Jun 14 SQL Server
SqlServer常用函数及时间处理小结
May 08 SQL Server
SQL 窗口函数实现高效分页查询的案例分析
mybatis调用sqlserver存储过程返回结果集的方法
SQL Server2019数据库之简单子查询的具有方法
Apr 27 #SQL Server
SQL Server中交叉联接的用法详解
SqlServer 垂直分表(减少程序改动)
Apr 16 #SQL Server
sqlserver2017共享功能目录路径不可改的解决方法
SQLServer2008提示评估期已过解决方案
You might like
php防止站外远程提交表单的方法
2014/10/20 PHP
Thinkphp3.2实用篇之计算型验证码示例
2017/02/09 PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
2017/10/22 PHP
php获取微信共享收货地址的方法
2017/12/21 PHP
javascript 动态修改样式和层叠样式表代码
2010/04/27 Javascript
基于jquery的回到页面顶部按钮
2011/06/27 Javascript
js Select下拉列表框进行多选、移除、交换内容的具体实现方法
2013/08/13 Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
2016/02/21 Javascript
基于jQuery实现淡入淡出效果轮播图
2020/07/31 Javascript
Javascript 6里的4个新语法
2016/08/25 Javascript
微信小程序实现图片轮播及文件上传
2017/04/07 Javascript
微信小程序商品详情页规格属性选择示例代码
2017/10/30 Javascript
Vuex持久化插件(vuex-persistedstate)解决刷新数据消失的问题
2019/04/16 Javascript
Node.js 获取微信JS-SDK CONFIG的方法示例
2019/05/21 Javascript
微信小程序复选框实现多选一功能过程解析
2020/02/14 Javascript
基于javascript实现放大镜特效
2020/12/03 Javascript
[50:12]EG vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
python中的不可变数据类型与可变数据类型详解
2018/09/16 Python
python与C、C++混编的四种方式(小结)
2019/07/15 Python
Django中提供的6种缓存方式详解
2019/08/05 Python
Django权限设置及验证方式
2020/05/13 Python
django 解决扩展自带User表遇到的问题
2020/05/14 Python
Python rabbitMQ如何实现生产消费者模式
2020/08/24 Python
CSS3对图片照片进行边缘模糊处理的实现
2018/08/08 HTML / CSS
阿迪达斯法国官方网站:adidas法国
2018/03/20 全球购物
美国排名第一的葡萄酒俱乐部:Firstleaf Wine Club
2020/01/02 全球购物
Linux如何修改文件和文件夹的权限
2013/09/05 面试题
建筑专业自我鉴定
2013/10/22 职场文书
寒假思想汇报
2014/01/10 职场文书
军校大学生个人的自我评价
2014/02/17 职场文书
公司合作意向书
2014/04/01 职场文书
双方协议书
2014/04/22 职场文书
给市场的环保建议书
2014/05/14 职场文书
大学感恩节活动策划方案
2014/10/11 职场文书
2015暑假社会调查报告
2015/07/13 职场文书
MongoDB修改oplog大小的四种方法
2022/04/11 MongoDB