如果不使用mySQLi_MULTI_QUERY,SQL注入将无法工作

2022-04-16 00:00:00 php mysql sql-injection

我正在尝试创建一个SQL注入示例,但MySQL每次都会拒绝第二个查询,除非我将其更改为mySQLI_MULTI_QUERY。

<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" name="dummyDorm">
        <label>Name: </label>
        <input type="text" name="name"><br>
        <input type="submit" value="Submit">
    </form>

    <?php 
        if($_SERVER["REQUEST_METHOD"] == "POST")
        {
            $name = $_POST['name'];
            $conn = mysqli_connect("localhost", "root", "", "testDB");
            if (mysqli_connect_errno()){
                echo "failed to connect" . mysqli_connect_error();
                die();
            }
            else
            {

                $sql = "SELECT * FROM users WHERE name = '{$name}'";
                var_dump($sql);
                if (mysqli_query($conn, $sql))
                {
                    echo "Success";
                } 
                else {
                    echo "Error: " . $sql . "<br>" . mysqli_error($conn);
                }

                mysqli_close($conn);
            }

        }
    ?>

该表单实际上没有做任何事情,我只是想演示使用SQL注入可以编辑数据。我想在您输入"Drop TABLE TestTable"时执行一次注入。我的MySQL如下所示:

DROP DATABASE IF EXISTS testDB;
CREATE DATABASE testDB;
USE testDB;

CREATE TABLE users
(
    userID INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255)
)engine=innodb;

CREATE TABLE testTable
(
    test VARCHAR(10)
)engine=innodb;

INSERT INTO users VALUES(null, "user01");

输入注入时:‘;DROP TABLE TestTable--

输出如下: 错误:SELECT*FROM USERS WHERE NAME=‘’;DROP TABLE TESTABLE--‘ 您的SQL语法有错误;请查看与您的MySQL服务器版本对应的手册,以了解在第1行使用‘DROP TABLE TESTABLE--’时使用的正确语法

我一直在阅读教程,他们使用MySQLI_QUERY,它工作得很好,但我必须将其更改为MySQLI_MULTI_QUERY才能通过注入。

谢谢


解决方案

确实mysqli_query()不允许多查询。为此,您需要mysqli_multi_query(),如果您不使用该函数,您就不会受到依赖于运行多个查询的SQL注入攻击,就像您的DROP TABLE示例一样。

但是,除了DROP TABLE之外,SQL注入还可能导致其他类型的恶作剧。

我可以使用其他参数访问您的PHP页面的URL,这些参数允许我控制您的SQL查询的逻辑:

读取表中的所有行:

?name=x' OR 'x'='x

阅读其他表格:

?name=x' UNION ALL SELECT ... FROM othertable WHERE 'x'='x

执行拒绝服务攻击,用万亿行的临时表杀死您的数据库服务器:

?name IN (SELECT 1 FROM othertable CROSS JOIN othertable CROSS JOIN othertable CROSS JOIN othertable CROSS JOIN othertable CROSS JOIN othertable CROSS JOIN othertable) AND 'x'='x

SQL注入不一定是恶意攻击。这可能是对合法字符串的无意使用,导致意外的SQL语法:

?name=O'Reilly

针对SQL注入的修复是众所周知且简单的:使用参数化查询。

查看the manual for mysqli_prepare()或How can I prevent SQL injection in PHP?等常见堆栈溢出问题中的完整示例

相关文章