📜  基本的SQL注入和缓解与示例

📅  最后修改于: 2021-04-17 02:13:53             🧑  作者: Mango

SQL注入是一种代码注入技术,用于攻击数据驱动的应用程序,其中将恶意SQL语句插入到输入字段中以执行(例如,将数据库内容转储给攻击者)。

  • SQL注入可以多种方式引起严重问题。
  • 通过利用SQL注入,攻击者可以绕过身份验证,访问,修改和删除数据库中的数据。

暂时让自己扮演攻击者的角色。您的目标很简单。您想获取数据库执行的任何意外的SQL语句。您只想使某些事情起作用,因为这将揭示该应用程序具有潜在漏洞的事实。例如,考虑图1所示的简单身份验证表单。

捕获图1

图1的代码

Username:

Password:

您已经可以对此应用程序可能用来验证访问凭据的SQL语句类型进行有根据的猜测。这很可能是SELECT语句。您还可以猜测数据库表中使用的命名约定,因为它可能与HTML表单中使用的简单名称匹配。因为此表单用于身份验证,所以可能存在WHERE子句

$_POST['username'] and $_POST['password'].

从所有这些,您可能会预测以下内容:


假设这个猜测是正确的,您可以做什么来操纵该查询?想象一下发送以下用户名:

akash' /*
SELECT count(*)FROM users WHERE username = 'akash' /*'AND password = '...'";
In this example, /* is used to begin a multi-line comment,
effectively terminating the query at that point. This has
been tested successfully with MySQL. A standard comment 
in SQL begins with --, and it's trivial to try both.

该查询建议只要存在akash帐户即可成功进行身份验证,而不管密码是什么。这种特定的攻击经常被用来窃取帐户。当然,可以使用任何用户名(admin是受欢迎的目标)。因此,通过发送格式错误的用户名,您可以设法在没有有效帐户的情况下登录。

使用预准备语句(参数化查询)的缓解

有很多方法可以保护SQL注入。一种主要的防御技术是“预备语句(参数化查询)”。此技术迫使开发人员定义所有SQL代码,然后在以后将每个参数传递给查询。这种样式使数据库可以区分代码和数据,而不管提供了什么用户输入。
准备好的语句可确保即使攻击者插入了SQL命令,攻击者也无法更改查询的意图。例如,如果攻击者输入ABC的用户ID或’1’=’1,则参数化查询将不会受到攻击,而是将查找与整个字符串ABC或’1’=’1字面上匹配的用户名。
在职的:

  1. 准备:创建一个SQL语句模板并将其发送到数据库。某些未指定的值称为参数(标记为“?”)。
    例子:
    SELECT count(*)FROM users WHERE username = ? AND password = ?;
  2. 解析:数据库对SQL语句模板进行解析,编译和查询优化,并在不执行结果的情况下存储结果。
  3. 执行:稍后,应用程序将值绑定到参数,然后数据库执行该语句。应用程序可以使用不同的值多次执行该语句。

执行:

prepare('SELECT count(*)FROM users WHERE username = ? AND password = ?');
  
$stmt->bind_param('ss', $username,$password);
  
$stmt->execute();
  
$result = $stmt->get_result();
  
echo $result;
?>

这只是绕过用户登录页面的简单示例,而SQL Injection可以为攻击者提供对包括客户数据,个人身份信息(PII),商业秘密,知识产权和其他敏感信息在内的敏感数据的未经授权的访问。还有一个SQL注入自动化工具sqlmap,用于执行所有类型的SQL注入。
因此,我们必须应用安全编码,以便保护系统免遭破坏。

参考:

  • 维基百科
  • OWASP

相关文章:
使用准备好的语句(参数化查询)减轻SQL注入攻击