SQL 注入攻击

SQL 注入,也称为 SQL 隐码或 SQL 注码,是发生于应用程序与数据库层的安全漏洞。简而言之,是在输入的字符串之中注入 SQL 指令,在设计不良的程序单中忽略了字符检查,那么这些注入进去的恶意指令就会被数据库服务器误认为是正常的 SQL 指令而运行,因此遭到破坏或是入侵。

攻击方式

  1. SQL 命令可查询、插入、更新、删除等,命令的串接。而以分号字符为不同命令的区别。(原本的作用是用于 SubQuery 或作为查询、插入、更新、删除等的条件式)
  2. SQL 命令对于传入的字符串参数是用单引号字符所包起来。(但连续 2 个单引号字符,在 SQL 数据库中,则视为字符串中的一个单引号字符)
  3. SQL 命令中,可以注入注解(连续 2 个减号字符 -- 后的文字为注解,或 /**/ 所包起来的文字为注解)
  4. 因此,如果在组合 SQL 的命令字符串时,未针对单引号字符作跳脱处理的话,将导致该字符变量在填入命令字符串时,被恶意窜改原本的 SQL 语法的作用。

防御策略

数据校验

SQL 注入漏洞的主要原因还是没有对用户输入的数据进行过滤,所以对来自用户的数据(GET、POST、Cookie 等)最好做到以下两种过滤校验

  • 检查输入的数据是否具有所期望的数据格式。这种在参数是数字的时候特别有效,如果攻击者选择在参数中插入内容的话则会被转换成 NaN 导致攻击失败。
  • 使用数据库特定的敏感字符转义函数把用户提交上来的非数字数据进行转义。

权限限制

严格限制 Web 应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害。**请记住永远不要使用超级用户或所有者帐号去连接数据库!**当数据库被攻击时将损伤限制在当前表的范围是比较明智的选择。通过权限限制可以防止攻击者获取数据库其它信息,甚至利用数据库执行 Shell 命令等操作。

日志处理

当数据库操作失败的时候,尽量不要将原始错误日志返回,比如类型错误、字段不匹配等,把代码里的 SQL 语句暴露出来,以防止攻击者利用这些错误信息进行 SQL 注入。除此之外,在允许的情况下,使用代码或数据库系统保存查询日志也是一个好办法。显然,日志并不能防止任何攻击,但定期审计数据库执行日志可以跟踪是否存在应用程序正常逻辑之外的 SQL 语句执行。日志本身没用,要查阅其中包含的信息才行。毕竟,更多的信息总比没有要好。

参考资料