SQL 注入是一种常见的注入类型,攻击者向软件应用程序或站点界面发送 SQL 命令,以攻击可能为被黑客入侵的软件或服务提供服务的数据库服务器。
SQL 注入攻击尤其危险,因为它们可让攻击者未经授权访问数据库,检索、修改或删除数据,甚至可能危及整个服务器。此类攻击利用了 Web 应用程序的不当编码,这些应用程序没有充分验证用户输入。攻击者通过在输入字段(例如登录表单)中插入或“注入”SQL 命令来利用此漏洞,然后由数据库服务器执行这些命令。
SQL 注入攻击的严重性在于它们可用于操纵数据库命令,使攻击者能够绕过身份验证、访问敏感数据并对数据库执行管理操作。在某些情况下,攻击者可以使用 SQL 注入获得进入组织系统的持久后门,从而对数据安全构成长期威胁。
SQL 注入原因及示例
SQL注入漏洞的主要原因是数据交互过程中,数据从前端传递到后端时没有经过严格的校验,导致输入的数据被拼接到SQL语句中,并作为SQL查询的一部分执行,导致数据库被入侵,造成数据泄露、删除,甚至服务器完全被入侵。
Pikachu训练环境的SQL-Inject模块可以演示此漏洞,当在系统中注册的用户名被输入到如下应用程序的输入框中时,系统会返回相应的UID和邮箱。
该服务的PHP代码如下:后端代码对前端传过来的name参数不做任何过滤,直接拼接到数据库查询语句中,如下:
“选择会员的 ID、电子邮件,其中用户名 = '$name'”
这会导致 SQL 注入漏洞。攻击者可以通过 name 参数注入恶意 SQL 语句,以检索服务旨在提供的数据之外的数据,从而危及系统的机密性
如果(isset($_GET['提交'])&& $_GET['名称'] != null){
// 这里不做任何处理,直接连接进 select 语句中
$名称 = $_GET['名称'];
// 该变量是字符串类型,所以需要考虑转义。
$query = "选择成员的 id、电子邮件,其中用户名='$name'";
$result = 执行($link,$query);
如果 (mysqli_num_rows($result) >= 1) {
当($data = mysqli_fetch_assoc($result)){
$id = $数据['id'];
$email = $数据['电子邮件'];
$html .= "<p class='notice'>你的 uid:{$id} <br />您的电子邮箱是:{$email}</p>";
}
} 别的 {
$html .= "<p class='notice'>您输入的用户名不存在,请重新输入!</p>";
}
}
以上述查询服务为例,当我们输入恶意的SQL注入payload-test 'or 1=1#时,系统会返回所有注册用户的UID和email。这是一个很直观的数据泄露案例。黑客一旦意识到SQL注入漏洞,就可以随心所欲地对数据库进行增删改查等操作,甚至可能注入webshell,进一步控制整个服务器。
这一切是怎么发生的?如前所述,后端代码不进行任何过滤,直接将用户输入的名称参数连接到数据库查询语句中。因此,当输入恶意payload-test'or1=1#时,后端代码会生成查询:
$query = "选择成员的 ID、电子邮件,其中用户名='test' 或 1=1#'"
当在数据库中执行此语句时,结果很明显:数据库将表达式 1=1 评估为始终为真,从而返回成员表中的所有数据。
如何防止 SQL 注入
为了防止 SQL 注入,开发人员必须确保 Web 应用程序正确清理用户输入。这通常涉及使用准备好的语句和参数化查询,将 SQL 命令与数据输入分开,从而防止执行恶意注入的 SQL 代码。定期代码审查和安全测试还可以帮助识别和修复可通过 SQL 注入利用的漏洞。
此外,实施强大的 Web 应用程序防火墙 (WAF) 可以提供针对 SQL 注入攻击的额外防御层。 CDNetworks WAF 可以帮助在恶意请求到达数据库服务器之前检测并阻止它们。教育开发人员有关安全编码实践并提高对输入验证重要性的认识对于防止 SQL 注入攻击也至关重要。