2025-1.11 实习学习日记 数据库-了解SQL注入

SQL 注入是一种常见的安全漏洞,它主要发生在应用程序与数据库交互的过程中。以下是对其详细的解释:

基本原理

  • 用户输入被误用作 SQL 代码:当应用程序在构建 SQL 语句时,如果直接将用户输入的数据嵌入到 SQL 语句中,而没有对用户输入进行适当的过滤和转义处理,攻击者就可以通过精心构造的输入,将恶意的 SQL 代码插入到正常的 SQL 语句中。例如,在一个登录页面,正常的 SQL 查询语句可能是SELECT * FROM users WHERE username = 'user' AND password = 'pass',如果应用程序直接将用户输入作为查询的一部分,攻击者可以输入' OR '1'='1作为密码,那么最终的 SQL 语句就变成了SELECT * FROM users WHERE username = 'user' AND password = '' OR '1'='1',这将导致查询结果不符合预期,并且可能会绕过登录验证。

攻击类型

  • 联合查询注入:攻击者通过在输入中插入UNION语句,将自己构造的查询结果添加到原查询结果中。例如,输入' UNION SELECT username, password FROM users--,可以将用户表中的用户名和密码信息作为结果返回,从而获取敏感信息。
  • 报错注入:攻击者通过构造会引发数据库报错的输入,从报错信息中获取数据库的信息。比如输入' AND 1=1--可能不会有什么问题,但输入' AND 1=2--会引发报错,攻击者可以根据报错信息来猜测数据库的结构和数据。
  • 盲注:当攻击者无法从页面的显示结果中获取信息时,就可以使用盲注。通过构造特定的输入,根据页面的响应时间、页面是否正常显示等情况,来猜测数据库中的信息。例如,输入' AND (SELECT CASE WHEN (SELECT COUNT(*) FROM users) > 0 THEN 1 ELSE SLEEP(5) END) = 1--,如果页面延迟 5 秒返回,说明用户表不为空。

危害

  • 数据泄露:攻击者可以通过 SQL 注入获取数据库中的敏感信息,如用户的用户名、密码、银行卡号、身份证号等。
  • 数据篡改:可以修改数据库中的数据,如修改用户的余额、修改订单状态等。
  • 数据删除:恶意用户可以删除数据库中的数据,造成严重的业务损失。
  • 权限提升:在某些情况下,攻击者可以通过 SQL 注入获取更高的权限,甚至完全控制数据库服务器。

防御措施

  • 参数化查询(Prepared Statements):在开发中使用参数化查询,将用户输入作为参数传递给 SQL 语句,而不是直接将其嵌入到 SQL 语句中。这样可以确保用户输入只作为数据处理,而不会被解释为 SQL 代码。以下是 Java 中使用 JDBC 进行参数化查询的示例:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class SQLInjectionPrevention {
    public static void main(String[] args) {
        String username = "testUser";
        String password = "testPass";
        try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", "root", "root");
             PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM users WHERE username =? AND password =?");) {
            // 设置参数,将用户输入作为参数传递
            preparedStatement.setString(1, username);
            preparedStatement.setString(2, password);
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                System.out.println(resultSet.getString("username"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,使用PreparedStatement对象来执行查询,通过setString方法将用户输入的用户名和密码作为参数传递,而不是直接拼接在 SQL 语句中。这样可以避免用户输入被当作 SQL 代码执行,因为数据库会将这些输入仅作为数据,而不是可执行的 SQL 代码。

  • 输入验证与过滤:对用户输入进行验证,确保输入的数据符合预期的格式和范围。例如,对于只允许输入数字的字段,要检查输入是否为数字。
  • 最小权限原则:确保应用程序使用的数据库用户只具有必要的权限,避免使用具有高权限的数据库用户,这样即使发生 SQL 注入,也能限制攻击者的破坏范围。
  • 使用存储过程:将 SQL 逻辑封装在存储过程中,在存储过程中使用参数化输入,可以避免直接将用户输入嵌入 SQL 语句中。

通过以上这些方法,可以有效地防范 SQL 注入攻击,提高应用程序和数据库的安全性。

以下是一些实际的 SQL 注入漏洞案例:

电商平台搜索栏 SQL 注入漏洞

  • 漏洞场景:某电商平台的搜索功能存在 SQL 注入漏洞。其搜索接口为https://example.com/api/product/search,参数为search
  • 攻击过程:攻击者发现该平台对搜索参数未进行充分过滤,于是尝试向search参数注入test' and 1=1--,服务器正常响应并返回了与test相关的商品信息。接着注入test' and 1=2--,服务器返回空数据。通过布尔盲注,攻击者确认了漏洞的存在。攻击者进一步注入test' union select @@version, null, null--,成功获取了数据库版本信息。
  • 危害:攻击者可利用此漏洞获取数据库中的商品信息、用户信息等,甚至可能篡改商品价格、库存等数据,对平台的运营和用户权益造成严重损害。

招聘平台登录漏洞腾讯云

  • 漏洞场景:一个互联网招聘平台的登录页面,在用户输入用户名和密码后,后台将输入直接拼接到 SQL 语句中进行验证。
  • 攻击过程:攻击者在密码输入框中输入'or'1'='1'--,构造的 SQL 语句变为SELECT * FROM users WHERE username = 'user' AND password = '' or '1'='1'--。由于'1'='1'恒为真,查询会绕过密码验证,使攻击者以任意用户身份登录系统。
  • 危害:攻击者能够登录其他用户账号,查看求职者简历、企业招聘信息等敏感数据,甚至可能篡改用户简历、发布虚假招聘信息,扰乱平台正常秩序。

ResumeLooters 黑客团伙攻击事件CSDN博客

  • 漏洞场景:多个国家的近百个网站系统,包括流行的互联网招聘平台和电子商务网站存在安全漏洞,被 ResumeLooters 黑客团伙利用。
  • 攻击过程:黑客团伙通过在招聘网站上创建虚假的雇主简介和简历,以注入 XSS 脚本,收集管理凭据。还利用跨站脚本(XSS)发起攻击,将恶意脚本注入到求职或电商网站,获取管理访问权限。
  • 危害:该攻击影响范围广泛,包括印度、泰国、越南等国家,我国大陆和台湾地区的多个网站也受到影响。攻击者累计窃取了超过 200 万个电子邮件地址及用户个人隐私信息,包括姓名、电话号码、生日和工作经历,这些信息可能被用于后续的身份盗窃、网络钓鱼活动或社会工程攻击。

代码层面 SQL 注入漏洞腾讯云

  • 漏洞场景:在一段 Java 代码中,通过如下方式构造 SQL 查询语句:

protected AttackResult injectableQuery(String accountName) {
    String query = "";
    try (Connection connection = dataSource.getConnection()) {
        query = "SELECT * FROM user_data WHERE first_name = 'John' and last_name = '" + accountName + "'";
        try (Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
            ResultSet results = statement.executeQuery(query);
            // Do something...
        }
    }
}

  • 攻击过程:攻击者将accountName设置为Doe' OR '1' = '1,构造的 SQL 查询语句变为SELECT * FROM user_data WHERE first_name = 'John' and last_name = 'Doe' OR '1' = '1',该语句会返回user_data表中的所有记录。
  • 危害:可能导致数据泄露,攻击者能获取到本不应获取的大量用户数据,对用户隐私和系统安全造成严重威胁。

 三、如何检测SQL注入漏洞

检测 SQL 注入漏洞可以从代码审查、工具检测、漏洞扫描以及人工测试等多方面入手,以下是具体的方法:

1.代码审查

  • 查看输入处理逻辑:仔细检查代码中对用户输入的处理部分,查看是否对输入进行了充分的验证和过滤。例如,是否对输入的长度、格式、数据类型进行了限制,是否使用了正则表达式来验证输入的合法性。如果存在直接将用户输入拼接到 SQL 语句中的情况,就可能存在 SQL 注入漏洞。
  • 检查数据库操作代码:审查与数据库交互的代码,查看是否使用了参数化查询或存储过程来执行 SQL 语句。如果发现使用了字符串拼接的方式构建 SQL 语句,且没有对用户输入进行适当的转义处理,这是非常危险的信号,可能存在 SQL 注入风险。
  • 查看错误处理机制:检查应用程序的错误处理代码,看是否在错误信息中泄露了过多的数据库信息。如果攻击者能够从错误信息中获取数据库结构、表名、列名等信息,就更容易实施 SQL 注入攻击。

2.工具检测

  • 静态代码分析工具:使用专门的静态代码分析工具,如 Checkmarx、Fortify 等,这些工具可以对源代码进行扫描,检测出可能存在 SQL 注入漏洞的代码片段。它们通过分析代码的语法、语义和控制流,识别出存在风险的数据库操作和用户输入处理逻辑。
  • 动态应用安全测试(DAST)工具:像 Burp Suite、OWASP ZAP 等工具,可以在应用程序运行时对其进行扫描。它们通过发送各种恶意的输入请求,模拟攻击者的行为,检测应用程序是否对这些恶意输入存在漏洞。例如,工具会尝试在输入框中输入包含 SQL 注入语句的内容,观察应用程序的响应,判断是否存在 SQL 注入漏洞。
  • 数据库审计工具:一些数据库审计工具,如 IBM Guardium、Oracle Audit Vault 等,可以监控数据库的活动,记录所有的 SQL 语句执行情况。通过分析这些记录,能够发现异常的 SQL 语句,从而判断是否存在 SQL 注入攻击或潜在的漏洞。

3.漏洞扫描

  • 网络漏洞扫描器:使用网络漏洞扫描器,如 Nessus、OpenVAS 等,对整个网络环境进行扫描。这些工具可以检测出网络中存在的各种安全漏洞,包括 Web 应用程序中的 SQL 注入漏洞。它们会对目标服务器上的所有 Web 应用进行全面的扫描,检查是否存在可被利用的 SQL 注入点。
  • Web 漏洞扫描器:专门针对 Web 应用的漏洞扫描器,如 Acunetix、AppScan 等,能够深入检测 Web 应用中的各种漏洞,特别是 SQL 注入漏洞。它们会模拟用户的操作,对 Web 应用的各个页面和功能进行测试,查找可能存在的 SQL 注入风险点。

4.人工测试

  • 手动输入测试:测试人员可以手动在应用程序的输入框、搜索框等位置输入各种可能的 SQL 注入语句,观察应用程序的反应。例如,输入' OR '1'='1' AND 1=1--等常见的注入语句,看是否能够绕过验证或获取到敏感信息。
  • 边界值测试:对输入的边界值进行测试,比如输入超长的字符串、特殊字符、空值等,检查应用程序是否能够正确处理,是否存在因输入异常而导致的 SQL 注入漏洞。
  • 业务逻辑测试:结合应用程序的业务逻辑,构造针对性的测试用例。例如,在一个订单查询功能中,尝试输入恶意的 SQL 语句,看是否能够篡改查询条件,获取到不属于自己的订单信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值