SQL 注入是一种代码注入技术,用于攻击数据驱动的应用程序,其中将恶意 SQL 语句插入到条目字段中以供执行(例如将数据库内容转储给攻击者)。
- SQL 注入可以以多种方式使用以引起严重问题。
- 通过利用 SQL 注入,攻击者可以绕过身份验证、访问、修改和删除数据库中的数据。
暂时将自己置于攻击者的角色中。你的目标很简单。您希望获得数据库执行的任何意外 SQL 语句。您只是希望得到一些工作,因为这将揭示应用程序具有潜在漏洞的事实。例如,考虑图 1 中所示的简单身份验证表单。
图1
图 1 的代码
您已经可以对该应用程序可能用于验证访问凭证的 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 或 ‘1’=’1 的用户 ID,参数化查询将不会受到攻击,而是会查找字面上匹配整个字符串ABC 或 ‘1’=’1 的用户名。
在职的:
- 准备:创建 SQL 语句模板并将其发送到数据库。某些值未指定,称为参数(标记为“?”)。
例子:SELECT count(*)FROM users WHERE username = ? AND password = ?;
- Parse:数据库对SQL语句模板进行解析、编译、查询优化,结果不执行存储。
- 执行:稍后,应用程序将值绑定到参数,数据库执行语句。应用程序可以根据需要使用不同的值多次执行该语句。
执行:
prepare('SELECT count(*)FROM users WHERE username = ? AND password = ?');
$stmt->bind_param('ss', $username,$password);
$stmt->execute();
$result = $stmt->get_result();
echo $result;
?>
这只是绕过用户登录页面的一个简单示例,而 SQL 注入可以让攻击者未经授权访问敏感数据,包括客户数据、个人身份信息 (PII)、商业机密、知识产权和其他敏感信息。还有一个 SQL 注入自动化工具 sqlmap 用于执行所有类型的 SQL 注入。
因此,我们必须应用安全编码,以保护系统免遭入侵。
参考:
- 维基百科
- OWASP
相关文章:
使用准备好的语句(参数化查询)缓解 SQL 注入攻击