51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1595|回复: 0
打印 上一主题 下一主题

SQL注入漏洞和SQL优化

[复制链接]
  • TA的每日心情
    无聊
    4 天前
  • 签到天数: 530 天

    连续签到: 2 天

    [LV.9]测试副司令

    跳转到指定楼层
    1#
    发表于 2018-12-21 14:54:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    本帖最后由 测试积点老人 于 2018-12-21 14:58 编辑

    1、SQL注入漏洞
    由于“’1′=’1′”这个表达式永远返回 true,而 true 与任何布尔值的 or 运算的结果都是 true,那么无论正确密码是什么“Password=’1′ or ’1′=’1′”的计算值永远是 true,这样恶意攻击者就可以使用任何帐户登录系统了。这样的漏洞就被称作“SQL 注入漏洞(SQL Injection)”。
    对付 SQL 注入漏洞有两种方式:过滤敏感字符和使用参数化 SQL。

    1) 过滤敏感字符
    过滤敏感字符的思路非常简单,由于恶意攻击者一般需要在输入框中输入的文本一般含有 or、and、select、delete 之类的字符串片段,所以在拼接 SQL 之前检查用户提交的文本中是否含有这些敏感字符串,如果含有则终止操作。

    2) 使用参数化SQL

    为运行时才能确定的用户名和密码设置了占位符,然后在运行时再设定占位符的值,在执行时 Java、C#会直接将参数化 SQL 以及对应的参数值传递给 DBMS,在 DBMS 中会将参数值当成一个普通的值来处理而不是将它们拼接到参数化 SQL 中,因此从根本上避免了 SQL 注入漏洞攻击。

    2、SQL 优化
    在使用 DBMS 时经常对系统的性能有非常高的要求:不能占用过多的系统内存和CPU 资源、要尽可能快的完成的数据库操作、要有尽可能高的系统吞吐量。如果系统开发出来不能满足要求的所有性能指标,则必须对系统进行调整,这个工作被称为优化。

    SQL 优化的基本原则

    “二八原理”是一个普遍的真理,特别是在计算机的世界中表现的更加明显,那就是 20%的代码的资源消耗占用了 80%的总资源消耗。SQL 语句也是一种代码,因此它也符合这个原理。在进行 SQL 优化的时候应该把主要精力放到这 20%的最消耗系统资源的 SQL 语句中,不要想把所有的 SQL 语句都调整到最优状态。索引是数据库优化的最根本的优化方法。

    常用的SQL优化方法:
    1) 创建必要的索引

    2) 使用预编译查询
    程序中通常是根据用户的输入来动态执行 SQL 语句,这时应该尽量使用参数化SQL,这样不仅可以避免 SQL 注入漏洞攻击,最重要数据库会对这些参数化 SQL 执行预编译。

    3) 调整 WHERE 子句中的连接顺序

    DBMS 一般采用自下而上的顺序解析 WHERE 子句,根据这个原理,表连接最好写在其他 WHERE 条件之前,那些可以过滤掉最大数量记录。
    比如下面的 SQL 语句性能较差:
    1. <font size="2" style="font-weight: normal;">SELECT * FROM T_Person WHERE FSalary > 50000 AND FPosition='MANAGER' AND 25 < (SELECT COUNT(*) FROM T_Manager WHERE FManagerId=2);</font>
    复制代码

    我们将子查询的条件放到最前面,下面的 SQL 语句性能比较好:
    1. <font size="2" style="font-weight: normal;">SELECT * FROM T_Person WHERE 25 < (SELECT COUNT(*) FROM T_Manager WHERE FManagerId=2) AND FSalary > 50000 AND FPosition='MANAGER';</font>
    复制代码

    4) SELECT 语句中避免使用’*’
    SELECT  *比较简单,但是除非确实需要检索所有的列,否则将会检索出不需要的列,这回增加网络的负载和服务器的资源消耗;即使确实需要检索所有列,也不要使用SELECT *,因为这是一个非常低效的方法,DBMS 在解析的过程中,会将*依次转换成所有的列名,这意味着将耗费更多的时间。5) 尽量将多条 SQL 语句压缩到一句 SQL 中
    每次执行 SQL 的时候都要建立网络连接、进行权限校验、进行 SQL 语句的查询优化、发送执行结果,这个过程是非常耗时的,因此应该尽量避免过多的执行 SQL 语句,能够压缩到一句 SQL 执行的语句就不要用多条来执行。

    6) 用 Where 子句替换 HAVING 子句避免使用 HAVING 子句,因为 HAVING  只会在检索出所有记录之后才对结果集进行过滤。如果能通过 WHERE 子句限制记录的数目,那就能减少这方面的开销。HAVING  中的条件一般用于聚合函数的过滤,除此而外,应该将条件写在 WHERE 子句中。

    7) 使用表的别名
    当在 SQL 语句中连接多个表时,请使用表的别名并把别名前缀于每个列名上。这样就可以减少解析的时间并减少那些由列名歧义引起的语法错误。

    8) 用 EXISTS 替代 IN
    在查询中,为了满足一个条件,往往需要对另一个表进行联接,在这种情况下,使用 EXISTS 而不是 IN 通常将提高查询的效率,因为 IN 子句将执行一个子查询内部的排序和合并。

    9) 用表连接替换 EXISTS
    通常来说,表连接的方式比 EXISTS 更有效率,因此如果可能的话尽量使用表连接替换 EXISTS。

    10) 避免在索引列上使用计算
    在 WHERE 子句中,如果索引列是计算或者函数的一部分,DBMS 的优化器将不会使用索引而使用全表扫描。

    11) 用 UNION ALL 替换 UNION
    当 SQL 语句需要 UNION 两个查询结果集合时,即使检索结果中不会有重复的记录,如果使用 UNION 这两个结果集同样会尝试进行合并,然后在输出最终结果前进行排序。 因此,如果检索结果中不会有重复的记录的话,应该用 UNION ALL 替代 UNION,这样效率就会因此得到提高。

    12) 避免隐式类型转换造成的全表扫描

    13) 防止检索范围过宽
    如果 DBMS 优化器认为检索范围过宽,那么它将放弃索引查找而使用全表扫描。下面是几种可能造成检索范围过宽的情况: 使用 IS NOT NULL 或者不等于判断,可能造成优化器假设匹配的记录数太多。 使用 LIKE 运算符的时候,”a%”将会使用索引,而”a%c”和”%c”则会使用全表扫描,因此”a%c”和”%c”不能被有效的评估匹配的数量。




    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏1
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-25 19:57 , Processed in 0.059563 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表