让你彻底明白sql注入攻击

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

一、背景

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

数据如下:

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

@RestControllerpublic class Controller {        @Autowired    SqlInject sqlInject;        @GetMapping('list')    public List<Course> courseList(@RequestParam('studentId') String studentId){        List<Course> orders = sqlInject.orderList(studentId);        return orders;    }}
@Servicepublic 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,如下:

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 

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

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

union select 1,1,version(),1

4. 查询数据库名

union select 1,1,database(),1

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

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

看完上面这些演示后,你害怕了吗?你所有的数据配置都完全暴露出来了,除此之外,还可以完成很多操作,更新数据、删库、删表等等。

三、如何防止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. 过滤参数中含有的一些数据库关键词

@Componentpublic 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;    }}
(0)

相关推荐

  • MySQL复杂查询:连接查询+取某个类型的最大值

    本文链接:https://www.cnblogs.com/alanabc/p/10167926.html 需求 假设有一个考试,比如CET(包括CET-4和CET-6),学生可以多次报考刷分.现在某教 ...

  • sql server 表连接

    数据库操作中,我们需要的结果可能在两张表甚至多张表中,这时候就需要表连接操作,多表查询中的各个表之间的字段会存在连接,比如主外键关联,可以使用主外键来关联每张表.表连接方式有以下几种: JOIN: 如 ...

  • C# ORM学习笔记:Dapper基本用法

    一.基础知识 1.1.Dapper简介 Dapper是.NET下的一个micro ORM,它和Entity Framework或NHibnate不同,属于轻量级并且是半自动的(实体类都要自己写).假如 ...

  • 【数据库】数据库入门(四): SQL查询 - SELETE的进阶使用

    集合操作 常用的集合操作主要有三种:UNION(联合集).INTERSECT(交叉集).EXCEPT(求差集).以上三种集合的操作都是直接作用在两个或者多个 SQL 查询语句之间,将所有的元组按照特定 ...

  • jdbc预编译对象,事务,数据库连接池

    jdbc预编译对象 原始的jdbc使用声明对象进行sql的执行,对于执行的sql参数使用字符串拼接的形式进行添加 Class.forName("com.mysql.jdbc.Driver&q ...

  • Spring MVC防御CSRF、XSS和SQL注入攻击

    本文说一下SpringMVC如何防御CSRF(Cross-site request forgery跨站请求伪造)和XSS(Cross site script跨站脚本攻击). 说说CSRF 对CSRF来 ...

  • 如何防御SQL注入攻击?

    SQL注入攻击是比较常见的网络攻击方式之一,具有很大的危害性,那么如何防止SQL注入攻击呢?接下来我们来看看详细的介绍. 1,避免将用户提供的输入直接放入SQL语句中,最好使用准备好的语句和参数化查询 ...

  • SQL注入攻击的类型有哪些?网络安全教程

    网络安全攻击方式有很多种,其中包括SQL注入.XSS等,今天主要为大家介绍一下SQL注入攻击.那么什么是SQL注入?SQL注入攻击的类型有哪些? 什么是SQL注入? SQL注入是一种注入攻击,可以执行 ...

  • SQL注入攻击类型有几种?网络安全基础教程

    SQL注入攻击是黑客对数据库进行攻击的常用手段之一,具有很大的危害性,那么SQL注入攻击类型分为几种?以下为大家作了详细的介绍. SQL注入攻击类型分为几种? 1.基于布尔的盲注 因为Web的页面返回 ...

  • SQL注入方式分为哪几类?SQL注入攻击有什么特点?

    说起网络安全攻击方式,大家肯定都会想到SQL注入,它是非常常见的攻击方式之一,属于注入式攻击,有着严重的危害.那么你知道SQL注入方式分为哪几类吗?SQL注入攻击有什么特点?关于以上问题,小编为大家整 ...

  • 如何防范SQL注入攻击?网络安全入门教程

    SQL注入攻击是最危险的Web漏洞之一,危害性极大,造成的后果不堪设想,因此受到了大家的高度重视.那么你知道SQL注入攻击防范方法有哪些吗?我们来看看详细的内容介绍. SQL注入攻击的危害很大,而且防 ...

  • 彻底干掉恶心的 SQL 注入漏洞, 一网打尽!

    来源: b1ngz b1ngz.github.io/java-sql-injection-note/ 简介 文章主要内容包括: Java 持久层技术/框架简单介绍 不同场景/框架下易导致 SQL 注入 ...

  • 某学院系统sql注入到服务器沦陷(bypss)

    前言 前一段时间都在挖edu src,为了混几个证书,中间陆陆续续也挖到好几枚系统的通杀吧,不过资产都不多,都是黑盒测试出来的,没啥技术含量.只有这次挖到的这枚通杀稍微有那么一点点价值,从外网web一 ...

  • 渗透测试之SQL注入基础

    渗透测试之SQL注入基础 SQL注入类型 按照数据类型类型来分类 按照执行效果来分类(页面回显效果) 按照数据提交的方式来分类 判断注入类型的方法 MySQL注入基础 联合查询注入 布尔注入 时间盲注 ...