zoukankan      html  css  js  c++  java
  • SQL注入

    SQL注入:明明设置了强密码,为什么还会被别人登录?

    XSS 是黑客通过篡改 HTML 代码,来插入并执行恶意脚本的一种攻击。SQL 注入和 XSS 攻击很类似,都是黑客通过篡改代码逻辑发起的攻击。

    我们会将应用的用户信息存储在数据库中。每次用户登录时,都会执行一个相应的 SQL 语句。这时,黑客会通过构造一些恶意的输入参数,在应用拼接 SQL 语句的时候,去篡改正常的 SQL 语意,从而执行黑客所控制的 SQL 查询功能。这个过程,就相当于黑客“注入”了一段 SQL 代码到应用中。

    1. 修改 WHERE 语句
    uName = getRequestString("username");
    uPass = getRequestString("password");
    
    sql = 'SELECT * FROM Users WHERE Username ="' + uName + '" AND Password ="' + uPass + '"'
    

    当用户提交一个表单(假设 Username 为 admin,Password 为 123456)时,Web 将执行下面这行代码:

    SELECT * FROM Users WHERE Username ="admin" AND Password ="123456"
    

    当用户正常地输入自己的用户名和密码时,自然就可以成功登录应用。那黑客想要在不知道密码的情况下登录应用,他会输入 " or ""="。这时,应用的数据库就会执行下面这行代码:

    SELECT * FROM Users WHERE Username ="" AND Password ="" or ""=""
    

    WHERE 语句后面的判断是通过 or 进行拼接的,其中""=""的结果是 true。那么,当有一个 or 是 true 的时候,最终结果就一定是 true 了。因此,这个 WHERE 语句是恒为真的,所以,数据库将返回全部的数据。

    1. 执行任意语句

    在原语句的后面,插入额外的 SQL 语句,来实现任意的增删改查操作。

    在 MySQL 中,实现任意语句执行最简单的方法,就是利用分号将原本的 SQL 语句进行分割。这样,我们就可以一次执行多个语句了。比如,下面这个语句在执行的时候会先插入一个行,然后再返回 Users 表中全部的数据。

    INSERT INTO Users (Username, Password) VALUES("test","000000");
     SELECT * FROM Users;
    

    在用户完成登录后,应用通常会通过 userId 来获取对应的用户信息。

    uid = getRequestString("userId");
    sql = "SELECT * FROM Users WHERE UserId = " + uid;
    

    在这种情况下,黑客只要在传入的 userId 参数中加入一个分号,就可以执行任意的 SQL 语句了。比如,黑客想“删库跑路”的话,就令 userId 为 1;DROP TABLE Users,那么,后台实际执行的 SQL 就会变成下面这行代码,而数据库中所有的用户信息就都会被删除。

    SELECT * FROM Users WHERE UserId = 1;DROP TABLE Users
    
    SELECT * FROM Users WHERE UserId = 1;DROP TABLE Users
    

    通过 SQL 注入攻击,黑客能做什么?

    1. 绕过验证

    " or ""=" 作为万能密码,可以让黑客在不知道密码的情况下,通过登录认证。因此,SQL 注入最直接的利用方式,就是绕过验证,也就相当于身份认证被破解了。

    1. 任意篡改数据

    通过插入 DML 类的 SQL 语句(INSERT、UPDATE、DELETE、TRUNCATE、DROP 等),黑客就可以对表数据甚至表结构进行更改,这样数据的完整性就会受到损害。黑客通过插入 DROP TABLE Users,删除数据库中全部的用户。

    1. 窃取数据

    黑客通过类似 SQL 注入的手段,获取到数据库中的全部数据(如用户名、密码、手机号等隐私数据)。最简单的,黑客利用 UNION 关键词,将 SQL 语句拼接成下面这行代码之后,就可以直接获取全部的用户信息了。

    SELECT * FROM Users WHERE UserId = 1 UNION SELECT * FROM Users
    
    1. 消耗资源

    在 Web 后台中,黑客可以利用 WHILE 打造死循环操作,或者定义存储过程,触发一个无限迭代等等。在这些情况下,数据库服务器因为 CPU 被迅速打满,持续 100%,而无法及时响应其他请求。

    总结来说,通过 SQL 注入攻击,黑客可以绕过验证登录后台,非法篡改数据库中的数据;还能执行任意的 SQL 语句,盗取用户的隐私数据影响公司业务等等。所以,SQL 注入相当于让黑客直接和服务端的数据库进行了交互。应用的本质是数据,黑客控制了数据库,也就相当于控制了整个应用。

    如何进行 SQL 注入防护 ?

    使用 PreparedStatement、使用存储过程和验证输入。

    1. 使用 PreparedStatement

    当数据库在处理一个 SQL 命令的时候,大致可以分为两个步骤:

    • 将 SQL 语句解析成数据库可使用的指令集。我们在使用 EXPLAIN 关键字分析 SQL 语句,就是干的这个事情;
    • 将变量代入指令集,开始实际执行。之所以在批量处理 SQL 的时候能够提升性能,就是因为这样做避免了重复解析 SQL 的过程。

    SQL 注入是在解析的过程中生效的,用户的输入会影响 SQL 解析的结果。因此,我们可以通过使用 PreparedStatement,将 SQL 语句的解析和实际执行过程分开,只在执行的过程中代入用户的操作。这样一来,无论黑客提交的参数怎么变化,数据库都不会去执行额外的逻辑,也就避免了 SQL 注入的发生。

    String sql = "SELECT * FROM Users WHERE UserId = ?";
    PreparedStatement statement = connection.prepareStatement(sql);
    statement.setInt(1, userId); 
    ResultSet results = statement.executeQuery();
    
    
    1. 使用存储过程

    它的原理和使用 PreparedStatement 类似,都是通过将 SQL 语句的解析和执行过程分开,来实现防护。区别在于,存储过程防注入是将解析 SQL 的过程,由数据库驱动转移到了数据库本身。

    delimiter $$  #将语句的结束符号从分号;临时改为两个$$(可以是自定义)
    CREATE PROCEDURE select_user(IN p_id INTEGER)
    BEGIN
      SELECT * FROM Users WHERE UserId = p_id;
    END$$ 
    delimiter;  #将语句的结束符号恢复为分号
    
    call select_user(1);
    
    1. 验证输入

    防护的核心原则是,一切用户输入皆不可信。

    对所有输入进行验证或者过滤操作,能够很大程度上避免 SQL 注入的出现。在通过 userId 获取 Users 相关信息的示例中,我们可以确认 userId 必然是一个整数。因此,我们只需要对 userId 参数,进行一个整型转化(比如,Java 中的 Integer.parseInt,PHP 的 intval),就可以实现防护了。

    总结

    SQL 注入就是黑客通过相关漏洞,篡改 SQL 语句的攻击。通过 SQL 注入,黑客既可以影响正常的 SQL 执行结果,从而绕过验证,也可以执行额外的 SQL 语句,对数据的机密性、完整性和可用性都产生影响。

    为了避免 SQL 注入的出现,我们需要正确地使用 PreparedStatement 方法或者存储过程,尽量避免在 SQL 语句中出现字符串拼接的操作。除此之外,SQL 注入的防护也可以和 XSS 一样,对用户的输入进行验证、检测并过滤 SQL 中的关键词,从而避免原有语句被篡改。

  • 相关阅读:
    csr_matrix参数解析
    SQL删除重复数据(根据多个字段),pandas的nan存入数据库报错
    XGBoost参数中文翻译以及参数调优
    pandas.DataFrame.quantile
    pandas.DataFrame.rank
    JOIN子句
    ORDER BY子句
    WHERE子句
    SELECT语句
    数据分析-基础
  • 原文地址:https://www.cnblogs.com/liugangjiayou/p/12689469.html
Copyright © 2011-2022 走看看