首页 >> 网页技术 > SQL技术 >> 详细内容
SQL技术 >> 正文
Web应用安全 一 SQL注入
日期:2017/8/30 

注入攻击漏洞,例如SQL,OS以及LDAP注入。这些攻击发生在当不可信的数据作为命令或者查询语句的一部分,被发送给解释器的时候。攻击者发送的恶意数据可以欺骗解释器,以执行计划外的命令或者在未被恰当授权时访问数据。

SQL注入.png
SQL注入.png

我是否存在注入漏洞?

  • 检测应用程序是否存在注入漏洞的最好办法就是确认所有解释器的使用都明确地将不可信数据从命令语句或查询语句中区分出来。如果可能的话,在许多情况下,建议避免解释器,或禁用它(如,XXE)。对于SQL调用,这就意味着在所有准备语句(prepared statements)和存储过程(stored procedures)中使用绑定变量(bind variables),并避免使用动态查询语句。
  • 检查应用程序是否安全使用解释器的最快最有效的方法是代码审查。代码分析工具能帮助安全分析者找到使用解释器的代码并追踪应用的数据流。渗透测试者通过创建攻击的方法来确认这些漏洞。
    可以执行应用程序的自动动态扫描器能够提供一些信息,帮助确认一些可利用的注入漏洞是否存在。然而,扫描器并非总能达到解释器,所以不容易检测到一个攻击是否成功。不恰当的错误处理使得注入漏洞更容易被发现。

攻击案例场景

  • 场景#1:应用程序在下面存在漏洞的SQL语句的构造中使用不可信数据:
    String query = "SELECT * FROM accounts WHEREcustID='" + request.getParameter("id") +"'";
  • 场景#2:同样的,框架应用的盲目信任,仍然可能导致查询语句的漏洞。(例如:Hibernate查询语言(HQL)):
    Query HQLQuery= session.createQuery(“FROM accounts
    WHERE custID='“ + request.getParameter("id") + "'");
    在这两个案例中,攻击者在浏览器中将“id”参数的值修改成’ or’1’=’1。如:
    http://example.com/app/accountView?id=' or '1'='1
    这样查询语句的意义就变成了从accounts表中返回所有的记录。更危险的攻击可能导致数据被篡改甚至是存储过程被调用。

如何防止注入漏洞?

防止注入漏洞需要将不可信数据从命令及查询中区分开。

  1. 参数化语句:使用占位符或绑定常量来向SQL查询提供参数,可避免或解决很多在应用中经常见到的SQL注入问题,还有拥有相比现代数据库效率更高的优势(数据可以根据提供的预处理语句来优化查询,从而提高后续查询的性能)。
  2. 输入验证:测试应用接受的输入以保证其符合应用中定义标准的过程。可以简单到将参数限制成某种类型,也可以复杂到使用正则表达式或业务逻辑来验证输入
  • 白名单验证(包含验证或者正验证): 数据类型、 数据大小、 数据范围、 数据内容
  • 黑名单:常用方法为正则表达式(推荐使用白名单)
  1. 编码输出:对在应用的不同模块或部分间传递的内容进行编码(根据不同的数据编码进行替换后传输)
  2. 规范化:将输入简化成便准简单的形式(通常最容易实现的一种方法是拒绝所有不符合规范格式的输入)
  3. 通过设计来避免SQL注入的危险:
  • 使用存储过程:可以防止或减轻SQL注入影响的设计技术(几乎可以杜绝SQL注入);
    存储过程非常有助于减轻潜在SQL注入漏洞的严重影响,因为大多数数据库中使用存储过程时可以在数据库层配置访问控制;发现SQL注入时,可以通过正确的配置来保证攻击者无法访问数据的敏感信息。
  • 使用抽象层:常见做法是为表示、业务逻辑、和数据访问定义不同的层,从而将每一层的实现从总体设计中抽象出来。
    处理敏感数据:考虑数据库中敏感信息的存储和访问
  • 口令:存储每个用户的口令的salted单向哈希而不是口令本身,将salt(一种附加的少量随机数数据)与哈希口令分开保存;登录时不用比较用户口令和数据库保存的口令,而是通过用户提供的信息计算出salted哈希与数据库中保存的哈希值进行比较(如果用户忘记了口令,则生成一个新的口令给用户)。
  • 信用卡及其他财务信息:使用认可的(FIPS认证过)加密算法来对信用卡等信息进行加密,存储加密后的明细数据。
  • 存档:考虑每隔一段合理的时间就存档或清除这些不需要的信息。
  • 避免明显的对象名:为关键对象(加密函数、口令、信用卡列)选取名称是需要格外小心,eg:password
  • 创建数据库honeypot:有人在尝试从数据库中读取口令时接收警告,则可以创建一种带password(包含假数据)的附加honeypot(蜜罐),如果假数据被选中,那么发送邮件给应用管理员。
  • 附加安全的开发资源:借助资源向开发人员提供工具、资源、培训和知识,提高安全性。
  1. 平台层防御:
  1. 使用运行时保护(成本):检测、减轻或防止那些不需要重编译易受攻击的应用的源码,即可部署的SQL注入。
  • Web应用防火墙:(WAF:网络设备或将安全性加到Web应用中的一种解决方案)
  • 截断过滤器:在请求资源的核心处理之前或之后执行处理操作。
  • 不可编辑的输入保护和可编辑的输入保护
  • URL策略/页面层策略
    页面覆写:创建一个在运行时接受的替代页面或类
    URL重写:接收那些发送给易受攻击页面或URL请求,并将他们重定向该页面的替代版本
  • 资源代理/封装
  • 面向方面编程
  • 应用入侵检测系统
  • 数据库防火墙
  1. 确保数据库安全
  • 使用较低权限的数据库登录
  • 撤销PUBLIC许可
  • 使用存储过程
  • 使用强大的加密技术来保护存储的敏感数据
  • 维护一个审查跟踪
  1. 确保数据库安全
  • 额外的系统对象锁定
  • 约束即席查询
  • 增强对验证周边的控制
  • 在最低权限的操作系统账户语境中运行
  • 确保数据库服务器打了补丁
  1. 额外的部署考虑
  • 最小化不必要信息泄露
  • 隐藏错误信息
  • 使用空的默认Web站点
  • 为DNS反向查询使用虚拟主机名称
  • 使用通配符SSL证书
  • 限制通过搜索引擎hacking得到的发现
  1. 禁止WSDL信息
  • 提高Web服务器日志的冗余
  • 在独立主机上部署Web服务器和数据库服务器
  • 配置网络访问控制

防止LDAP注入

Function LDAPRequest(id)
    LDAPRequest = checkLDAP(Request(id))
end function

'防止LDAP的注入
Function checkLDAP(strHTML)
    If Isnull(strHTML) Then
        checkLDAP = ""
        Exit Function 
    End If
    
    strHTML=server.HTMLEncode(strHTML)
    
    Dim objRegExp,strOutput   
    Set objRegExp=New Regexp   
    objRegExp.IgnoreCase=true   
    objRegExp.Global=True  
 
    objRegExp.Pattern = Chr(0)
    strOutput = objRegExp.Replace(strHTML, "")
    objRegExp.Pattern = """"
    strOutput = objRegExp.Replace(strOutput, """)   
    objRegExp.Pattern = "\\"
    strOutput = objRegExp.Replace(strOutput, "\5c")
    objRegExp.Pattern = "NUL"
    strOutput = objRegExp.Replace(strOutput, "\0")
    objRegExp.Pattern = "/"
    strOutput = objRegExp.Replace(strOutput, "\2f") 
    objRegExp.Pattern = "\*"
    strOutput = objRegExp.Replace(strOutput, "\2a") 
    objRegExp.Pattern = "\("
    strOutput = objRegExp.Replace(strOutput, "\28") 
    objRegExp.Pattern = "\)"
    strOutput = objRegExp.Replace(strOutput, "\29") 
    Set objRegExp=Nothing
    
    checkLDAP = strOutput
end function