其他分享
首页 > 其他分享> > Mybatis下的SQL注入漏洞原理及防护方法

Mybatis下的SQL注入漏洞原理及防护方法

作者:互联网

一、前言

之前我一直认为 Mybatis 框架下已经实现预编译机制,很多东西都封装好了,应该基本上不会再有 SQL 注入问题了。近期在渗透中发现,在实际项目中,即使使用了 Mybatis 框架,但仍然有可能因为编码人员安全意识不足而导致 SQL 注入问题。出现情况还真不少,因此有了这篇文章。

二、SQL 注入漏洞原理

1、概述

SQL 注入(SQL Injection)是发生在 Web 程序中数据库层的安全漏洞,是网站存在最多也是最简单的漏洞。主要原因是程序对用户输入数据的合法性没有判断和处理,导致攻击者可以在 Web 应用程序中事先定义好的 SQL 语句中添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步获取到数据信息。

简单地说,就是通过在用户可控参数中注入 SQL 语法,破坏原有 SQL 结构,达到编写程序时意料之外结果的攻击行为。其成因可以归结为如下原因造成的:

  1. 程序编写者在处理应用程序和数据库交互时,使用字符串拼接的方式构造 SQL 语句。
  2. 且未对用户可控参数进行足够的过滤。

2、漏洞复现

下面使用DVWA靶场来进行演示,网站架构为PHP,我们重点关注漏洞原理即可。

该页面提供了一个简单的查询功能,可以根据前端输入的用户ID来查询对应的用户信息。如图,输入 1,返回了对应 admin 用户的信息。

<?php

if( isset( $_REQUEST[ 'Submit' ] ) ) {
    // Get input
    $id = $_REQUEST[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Get values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    }

    mysqli_close($GLOBALS["___mysqli_ston"]);
}

?>

进行代码审计可以发现,程序将前端输入的 id 参数未加任何处理,直接拼接在了 SQL 语句中,那么此时就导致了SQL注入漏洞。

若此时攻击者输入的用户ID为 1' or 1='1,则程序拼接后执行的 SQL 语句变成了

SELECT first_name, last_name FROM users WHERE user_id = '1' or 1='1';

可见,攻击者通过单引号 ' 闭合了数据库查询语句,并且在查询条件之后构造了“或 1=1”,即“或真”的逻辑,导致查询出了全部用户的数据。

标签:Mybatis,SQL,漏洞,框架,编译机制,安全漏洞,数据库
来源: