SQL 注入

本章将学习如何避免常见的数据库漏洞。

什么是SQL注入?

SQL注入是一种攻击,当web服务器从浏览器接受用户输入时,如果web应用程序有漏洞,攻击者有可能注入恶意SQL代码。

SQL注入攻击可能引起敏感信息暴露,如用户的联系电话、电子邮件地址、信用卡信息等。利用它,攻击者甚至能绕过身份验证,访问整个数据库。

SQL注入的工作原理

考虑下面的SQL语句,当web应用程序中的用户登录时,验证用户名和密码。

SELECT * FROM users WHERE username='username_val' AND password='password_val';

这里,username_valpassword_val分别表示用户输入的用户名和密码。如果用户输入“john”作为用户名,“123”作为密码,那么结果语句将是:

SELECT * FROM users WHERE username='john' AND password='123';

但是假设用户是攻击者,输入了类似于' OR 'x'='x的值

在这种情况下,上面的SQL查询将被构造为:

SELECT * FROM users WHERE username='' OR 'x'='x' AND password='' OR 'x'='x';

这个语句是一个有效的SQL语句,因为'x'='x'总是成立,所以查询将返回users表中的所有行。可以看到攻击者使用一个小技巧,就可以轻松地访问数据库的所有敏感信息。

如果users表非常大,包含数百万行数据,这条语句还可能导致拒绝服务攻击(DDoS攻击),方法是消耗系统资源,使你的应用程序不能正常提供服务。

警告: 如果`DELETE`或`UPDATE`语句被注入了,后果更严重,这将导致数据被删除或修改。

防止SQL注入

始终验证用户输入。永远不要直接使用用户输入的内容来构建SQL语句。如果使用PHP和MySQL,可以使用mysqli_real_escape_string()函数创建一个合法的SQL字符串。

下面是一个使用PHP和MySQL进行用户身份验证的简单示例,演示了如何在获取用户输入的同时防止SQL注入。

<?php
// Starting session
session_start();

/* Attempt MySQL server connection. Assuming you are running MySQL
server with default setting (user 'root' with no password) */
$link = mysqli_connect("localhost", "root", "", "demo");

// Check connection
if($link === false){
    die("ERROR: Could not connect to database.");
}

// Escape user inputs for security
$username_val = mysqli_real_escape_string($link, $_POST['username']);
$password_val = mysqli_real_escape_string($link, $_POST['password']);

if(isset($username_val, $password_val)){
    // Attempt select query execution
    $sql = "SELECT * FROM users WHERE username='" . $username_val . "' AND password='" . $password_val . "'";
    if($result = mysqli_query($link, $sql)){
        if(mysqli_num_rows($result) == 1){
            // User is authenticated do your stuff here
            $row = mysqli_fetch_array($result);
            /* Holding values in session variable so that it can be
            accessed later within the same session reference */
            $_SESSION['user_id'] = $row['user_id'];
            $_SESSION['first_name'] = $row['first_name'];
            header('Location: welcome.php');
        } else{
            echo "ERROR: Invalid username or password.";
        }
    } else{
        echo "ERROR: Something went wrong. Please try again.";
    }
}

// Close connection
mysqli_close($link);
?>


浙ICP备17015664号 浙公网安备 33011002012336号 联系我们 网站地图  
@2019 qikegu.com 版权所有,禁止转载