Yukang's Page

SQL Injection attack

2018-03-10

注入原理

SQL注入一直是 Web 应用的一大安全隐患,注入的基本原理是通过修改输入的参数来操作后台执行的 SQL,注入可能会导致数据库被恶意修改、数据被恶意读取等严重行为。所以如果一个参数有漏洞,通过小心的构造注入点即可利用,这里的渗透攻防Web篇-SQL注入攻击初级有一些编写注入点的教程。

最初的时候我在一个用 C 写后台的项目里待过,现在回想起来我们当时根本没注意SQL 注入,C 拼接处 SQL 的字符串很常见。不过现在大多数 Web 框架都已经有 ORM 了,ORM 可以在很大程度上避免注入的产生,因为程序员通常来说不用写纯的 SQL 了, 在最佳实践的前提下 ORM 会生成安全的 SQL。当然什么工具最终还是依赖程序员,比如下面的 Ruby 代码即会有问题:

User.where("email = #{params[:email]}").first

更多作死的办法可以参考: https://rails-sqli.org/

WAF

通常我们会使用一些 WAF 来阻挡 一些SQL 注入,但是 WAF 也有其局限性。WAF 一般是通用的,不会局限于某个特定的框架。我们可以实现在 Nginx 上,或者使用一些商用的 WAF,通常来说对于应用也不用修改其代码。不过 WAF 的问题在于其实基于规则的,而 SQL 本省是比较复杂的,可以看看2003 SQL BNF 的描述有多么的长。所以 WAF 的规则大多数是一大堆较难维护的正则表达式,比如: Nginx Waf示例,注意这个项目用不太成熟,初步看会有比较严重的性能问题。正因为规则是固定的,会导致存在很多误拦截的情况,所以我在 Kong 上实现的 WAF 就还不敢用起来。例如现实情况中出现过包含select的 uri被拦的情况,一脸忧伤。

静态代码扫描

静态代码扫描会发现一些 SQL 注入,比如 Brakeman 之类的。不过通常静态代码扫描的问题也是分析得不够精准,会漏报、也会出现误报比较多,扫描的结果需要进行人工审计。当然这些工具也在逐步改进。

RASP 工具

RASP 的意思是Runtime Application Self Protection,这个概念近些年才提出,目前已经有一些安全公司做出了对应的产品,比如Sqreen, 百度最近也新开一个开源项目叫做OpenRASP,目前来说只支持 Java,开发者可以自己使用 Javascript 编写自己的插件。RASP 除了自己的规则还会依据请求时候的上下文来进行分析,这篇文章里有一些描述,这样误报的问题会大大减少。