SQL注入漏洞的防范措施

2023-02-28 09:13董沛然
数字通信世界 2023年1期
关键词:字符串校验黑客

董沛然

(国家开发银行信息科技部,北京 100032)

1 注入类漏洞的原理

软件的注入类漏洞,是风险等级很高的一类漏洞,在CVE、OWASP等权威信息安全漏洞库中,注入类漏洞长期位居前10名之列。它可以导致系统运行错误、或泄露客户信息等严重事故。

在所有注入类漏洞中,尤以SQL注入最为常见,危害也最大。

1.1 SQL注入原理说明

SQL注入,简单地说就是利用程序代码漏洞,绕过程序权限,将SQL命令插入到用户请求的查询字符串或者输入域进行攻击,其结果轻则获得敏感信息和数据,重则控制服务器[1]。

攻击者(黑客)在利用SQL漏洞实施攻击时,通常会选择直接注入或二次注入两种方式。在直接SQL注入方式中,直接将代码插入到用户输入变量,该变量与SQL命令串联在一起;在二次SQL注入方式中,将恶意字符串通过报文植入数据库表中,未来在程序读取该库表字段时,被动态拼接为SQL命令,并执行。

下面以一个简单的直接注入SQL漏洞为例,说明SQL注入的原理。以下代码动态地构造并执行了一个SQL查询,该查询可以搜索与指定客户名称相匹配的交易记录。

假设有如下C语言代码段:

Receive_Input(&szCUSTOM_NAME); //接收用户输入的查询条件——注入点

上述代码的逻辑是:接收用户在界面输入的姓名,将其作为查询条件拼接到SQL语句中,再在数据库中完成查询操作。

正常情况下,当用户输入客户名称David时,拼接成的SQL语句为:

select * from TABLE_TRANSACTION where CUSTOM_NAME='David';

此时程序将产生正确的输出。

但是当这段代码被黑客攻击时,如果黑客输入的内容为:

这样一来,将会有两条SQL语句被执行,虽然其中前一条SQL语句是安全的,但后一条却可以查询出库表中的所有记录,造成严重的信息泄露。

这里涉及一些概念。在这个例子中,程序从用户输入获取了szCUSTOM_NAME字段,在未经过滤的情况下,将其值直接以字符串拼接的方式拼接到一个SQL语句里面,造成了SQL注入漏洞。

在这段程序中,直接从用户输入获取信息的代码行Receive_Input(&szCUSTOM_NAME)称为这个SQL注入漏洞的注入点。执行危险SQL语句的代码行Execute(szSQL)称为这个SQL注入漏洞的爆发点。从注入点到爆发点之间,所有涉及危险字符串szCUSTOM_NAME信息赋值的语句,称为这个SQL注入漏洞的传递链。

1.2 命令注入原理说明

命令注入漏洞,是指通过提交恶意构造的参数破坏命令语句的结构,达到非法执行命令的手段。命令注入漏洞常发生在具有执行系统命令的Web应用中。

下面举一个命令注入漏洞的例子。以下代码在服务器上动态地为用户建立专用目录,路径名是用户输入的客户名称。

假设有如下PHP语言代码段:

如此看来上述代码也是存在很大风险的。

在本例中,同样涉及注入点、爆发点、数据流的概念。从用户输入获取cu st om Na me的代码行$customName = $_POST["customName"]称为这个命令注入漏洞的注入点。执行这个危险命令的代码行system($command)称为这个命令注入漏洞的爆发点。从注入点到爆发点之间,所有涉及危险字符串customName信息赋值的语句,称为这个命令注入漏洞的传递链。

从上面两个例子可以看出,注入类漏洞的本质是,黑客通过引号、分号、斜杠、点号等特殊字符,闭合了原有的程序逻辑,使得用户提交的参数和程序本来的逻辑相互干扰。这样一来,黑客提交的参数就不仅仅只起到参数的作用,而且还进入到程序逻辑里来了。黑客就是通过这样的方式,把恶意代码嵌入到正常代码里来的。

1.3 漏洞分级

根据注入类漏洞的可利用性和危害性,目前业界一般将其分为三类。

(1)高危漏洞:可以直接被利用的漏洞,并且利用难度较低。利用之后可能对网站或服务器的正常运行造成严重影响、对用户财产及个人信息造成重大损失。

(2)中危漏洞:利用难度极高,或满足严格条件才能实现攻击的漏洞,或漏洞本身无法被直接攻击,但能为进一步攻击起较大帮助作用的漏洞。

(3)低危漏洞:无法直接实现攻击,但可能造成一些非重要信息的泄露,这些信息可能让攻击者更容易找到其他安全漏洞。

2 防范SQL注入漏洞的措施

从上节可见,注入漏洞的本质是利用程序代码缺陷,绕过程序的权限,将恶意代码插入到用户请求的查询字符串或者输入域进行攻击。

为了防范注入类漏洞,业界主流的做法是加强对用户输入内容的校验。通常在各种大型信息系统的界面中,诸如时间、日期等大多数输入框的格式是固定的,黑客无法通过这些输入框注入攻击信息。但是对于姓名、备注栏等较为开放的输入框,系统一般不对输入内容做过多校验,并且此类输入框的长度一般较长,足够黑客输入可运行的恶意内容。

有鉴于此,出于防范注入类型攻击的目的,笔者认为进行大型信息系统的开发时应做到以下5点。

2.1 以占位符形式给SQL语句传参

在编码层面,编写安全性高的源代码,避免SQL拼接,改用占位符方式实现SQL组装。重视源代码安全检查,因为源代码安全检查可以暴露一部分明显的安全隐患(如SQL拼接等)[2]。

在前面的案例中,造成SQL注入攻击的根本原因在于攻击者可以改变SQL查询的上下文,使本应作为数据解析的数值,被篡改为命令了。为避免这种问题,以占位符形式给SQL语句传参是一种十分有效的方法。

使用占位符生成SQL语句的示例代码段如下:

在上面的示例代码段中,问号表示占位符。在程序编译时将参数传入SQL语句,生成合法的SQL语句。如此一来,非程序自身的数据不参与SQL语句逻辑的构成,那么黑客精心设计的危险字符串也就不会奏效了。

2.2 严格进行恶意关键字的校验

对所有开放型输入框,进行恶意关键字的校验,如前面案例中的delete、rm、分号、斜杠等字符串应尽量过滤掉。危险字符串可用穷举或正则表达式的方式识别[3]。过滤时,可以考虑去掉这些可能隐藏恶意攻击意图的字符串,或用星号替换。

2.3 客户端的展示信息不宜过细

坚持最小展现原则,客户端的展示信息不宜过细。这是因为黑客在利用注入手段攻击系统时,往往免不了“猜”和“试”的过程。黑客通常通过反复试探,并借助系统的各种返回信息、消息、日志内容来猜测其开发语言、后台架构、甚至库表字段名称等细节信息[4]。因此,我们在软件开发中,要尽量避免给用户暴露系统细节(如应用程序信息、数据库信息、或其他容易暴露后台逻辑的信息)[5]。不但要避免在客户端上显式地展示这些信息,也不宜写在消息或日志里返回给客户端,因为黑客可以利用流量抓包软件抓取到这些消息或日志信息。

2.4 坚持最小权限原则

系统的每一个进程、每一次数据库操作,应该使用可以完成该任务的最小权限运行。任何需要提权的操作,都应尽可能只保持最短的时间,一旦任务完成,应该立即收回权限,这样可以减少攻击者在高权限的条件下执行恶意代码的机会。

2.5 遵循系统的整体安全架构模型

系统在进行恶意关键字的过滤时,不仅需要考虑本系统所用的开发语言,还应考虑有关联关系的其他下游系统。一个大型复杂系统,往往是由众多小型子系统构成的。如图1所示。

图1 大型复杂系统模型(无输入校验)

其中,接入渠道子系统A主要负责接收用户的输入信息,并做一些简单的处理。而后,根据一定的逻辑,A将数据流输入到后台处理子系统B和后台处理子系统C,进行一些更为复杂的处理。

如前所述,由于系统遭受的注入类攻击主要来自于用户输入,所以接入渠道系统一般拥有比较完善的校验规则,如下图所示,接入渠道子系统A的输入校验模块应该可以过滤针对本子系统A的恶意字符。而后台处理子系统B和C由于并不直接面向用户,所以在开发时,往往这类子系统的安全性校验就不那么完整和严谨了。如图2所示。

图2 大型复杂系统模型(在接入渠道子系统A中加入输入校验)

但是,经过接入渠道子系统A处理过的数据会流入后台处理子系统B和C中,并且B、C所用的开发语言、数据库、部署的操作系统可能与接入渠道系统完全不同,黑客的恶意内容完全有可能躲过了前面的校验,而待转入后面的系统后发起攻击。这就如同地铁线路中,一颗炸弹一旦从某站流入地铁,就可以畅通无阻地流窜到任意线路、任意站点。所以要想保证所有线路的安全,就要确保全市任一地铁站,与重要站点的安检同样严格。因此更好的做法是,在每个子系统中,都针对本子系统的技术特点,进行有针对性的校验。如图3所示。

图3 大型复杂系统模型(在每个子系统中都加入输入校验)

当然,这种各个子系统分别校验的方式容易形成“各自为政”,可能接入渠道子系统A中已经实现了的输入校验,在后台处理子系统B和C中又重复实现了,这必然会降低系统的开发效率和运行效率。

有鉴于此,最好的方式是在接入渠道子系统A的前面,建立专门的校验系统,涵盖针对所有子系统的潜在危险字符校验,供整个系统群使用。如图4所示。

图4 大型复杂系统模型(在接入渠道子系统A前加入专门的输入校验模块)

这样不仅达到了全面校验的效果,并且也避免了重复校验的危害,充分保证系统群的整体运行效率。不仅如此,从开发人员安排上,可以请专门的信息安全人员编写此安全模块(或子系统),在保证专业性的同时,也有利于其他子系统的开发人员将精力集中于业务处理上。

3 结束语

本文首先介绍了注入类安全缺陷的定义和原理,然后,从安全架构、安全编码的角度,提出了5点防范注入类缺陷的措施:以占位符形式给SQL语句传参、严格进行恶意关键字的校验、客户端的展示信息不宜过细、坚持最小权限原则、遵循系统的整体安全架构模型。最后,从安全测试的角度,提出了基于复合引擎的自动化代码安全检查平台的构建方法,并阐述了其优势、原理和具体算法。■

猜你喜欢
字符串校验黑客
欢乐英雄
多少个屁能把布克崩起来?
基于文本挖掘的语词典研究
网络黑客比核武器更可怕
炉温均匀性校验在铸锻企业的应用
结合抓包实例分析校验和的计算
分析校验和的错误原因
浅谈微电子故障校验
一种新的基于对称性的字符串相似性处理算法
高效的top-k相似字符串查询算法