时间:2024-05-04
张甫华
(四川大学计算机学院,成都610065)
近年来,人机界面在各种系统中占比越来越大,在一些系统中用户界面设计甚至占据整个系统开发量的一半以上[1]。由此可见,对于用户来说用户界面就是整个软件系统[2],用户界面设计的质量会直接影响产品的用户体验。而在人机交互界面设计当中对输入数据进行验证占据着重要的一环。软件能够正常工作的关键就是要求数据的洁净[3],在处理数据的输入输出时,开发人员会依照一定的规则来杜绝被污染、不干净的数据进入到程序之中。如此,开发人员便会在交互界面中设置一定的门槛,以使得不符合规范的数据不能进入系统,也就不会破坏数据的完整性。
当前应用程序的开发为了符合“高内聚,低耦合”的思想,将各功能模块分为三层体系结构,包括客户端代码、服务器端代码和后端数据库。近年来,为提高应用的效率和可用性,Web 应用开始将许多的计算任务迁移到客户端进行处理。通过这样的方式来减少客户端向服务器发送请求并等待响应的时间,从而提高应用的响应性。因此,在客户端对数据输入进行验证也越来越普遍。
任何数据在进入软件系统之前,都需要对其进行必要的过滤。应用程序必须对不良数据保持高度的警惕,否则很容易受到来自外部系统的网络攻击,因此所有数据在输入时都要受到检查。只有在经过严格的验证之后,进入到程序中的数据才是纯净的。这样做的好处就是一旦数据持久化到数据库中,代码就无需反复检查数据是否有效或适当。因此无论是在前端页面进行输入验证,还是在服务器后端对输入验证。两者对输入验证的正确执行都提出了较高的要求。
输入验证器通常是保护Web 以及移动应用免受应用程序级攻击的第一道屏障,例如缓冲区溢出、SQL 注入和跨站点脚本[4]。当攻击者通过向应用发送恶意输入来发起此类攻击时,这些输入都将被输入验证器识别和过滤。如果验证器存在缺陷,势必会造成一些带有恶意的输入被漏掉使得应用底层容易受到攻击。因此需要对Web 应用的输入验证函数的正确性进行检查。
Offutt 等人提出了两种测试输入验证的技术,这两种技术都试图在设计测试用例时违反输入规则来检查输入验证函数。文献[5]中提出的技术是用于输入验证分析和系统测试。在文献[6]中提出的旁路测试方法为Web 应用程序创建客户端测试,并故意违反对用户输入的显式和隐式检查。虽然所提出的方法达到了用这些技术来验证和测试输入验证函数的目的,但它们解决问题的方法与所提出的方法存在着很大的不同。所提出的方法通过分析处理输入函数的CFG 来验证输入验证特性并生成测试用例来测试这些特,因而将其定义为一种自动化的方法。然而这两种技术是完全基于对输入结构和语法的分析,并不是完全自动化的。Nuo Li 等人则提出了一种基于扰动的交互式用户输入验证测试(PIUIVT)[7],它将每个输入字段与一个正则表达式进行关联,并且该正则表达式是有效的输入约束。PIUIVT 接下来扰动正则表达式来生成无效的测试输入,从而通过违反验证函数所指定的策略以达到测试验证函数的目的。
对于检测应用程序中输入验证漏洞的开发人员来说,还没有在源码级别找到一种合理的解决办法。对此Zhejun FANG 等人提出了一种新的方法来检测应用程序中的输入验证漏洞,并实现了名为EasyIVD 的原型[8],该原型提供了Java 源代码的静态分析。EsayIVD 利用后向程序切片的方式从Java 源代码中提取事务和约束切片。然后EasyIVD 用预定义的安全规则验证这些切片,以此来检测已知模式中的漏洞。为了检测未知模式中的漏洞,EasyIVD 从复制的切片中提取隐式安全规范作为频繁模式并验证它们。然后EasyIVD 会半自动地确认可疑的规则违反,并将确认的规则报告为漏洞。
M. Alkhalaf 等人[9]基于自动机的字符串分析来检查所提取验证函数的正确性。使用确定有限自动机(DFA)来表示字符串表达式可以接受的值。通过前向符号可达性分析,计算字符串变量在每个程序节点都可以取到所有的可能值。假设每个验证函数都以字符串作为输入,如果输入有效那么返回true(即验证策略通过了当前的输入),否则返回false。于是便可以利用这样的形式来自动地提取输入验证函数。也就是使用字符串分析计算所有可能的输入值,使得程序能够到达“return true”语句。然后检查这组值是否属于描述验证策略的正则表达式所定义的子集。如果是,便知道应用程序正确地实现了验证策略,从而达到对输入验证函数的正确性进行验证的目的。
Wassermann 和Su[10]使用Minamide[11]开发的字符串分析器来检查PHP 应用程序中的SQL 注入漏洞。通过计算得到可能到达SQL 热点的CFG 语言,利用从污点分析中得到的污点值来注释CFG 中的非终端。然后对每个非终端进行两个检查。首先检查它是否在SQL 查询中的文字字符串句法位置。如果在,那么检查它是否与表示字符串的规则语言存在交集,如果该规则语言具有奇数个未转义的引号,那么就认为是存在漏洞的。在文献[12]中,Wassermann 和Su 使用了类似的方法来检查XSS 漏洞。
差异分析技术[13]通常在找出不同代码的差异之后就会停止,而不会试图去修复这些差异。在NoTamper中[14]作者使用动态符号执行方法分析客户端脚本代码,以生成测试用例,随后将这些测试用例作为服务器端的输入。由于该方法依赖于动态(黑盒)测试,所以其测试覆盖率相当有限。在其最近的一篇后续论文[15]中,作者又提出了WAPTEC,它使用服务器端代码的符号执行方法来指导测试用例生成过程并扩大覆盖范围。Kunal Taneja 等人则提出了一种的新的方法MiTV[16],它采用了多重实现测试来检测验证器。尤其是MiTV将被测验证器的行为与其他同类型的验证器进行比较,从而提供有效的工具支持来生成测试输入和测试预言。MiTV 使用动态符号执行引擎Pex[17]来测试.NET Web 应用程序输入验证函数的正确性。这些函数首先根据它们验证的输入类型进行分类。然后通过将每个验证函数与同一类下的函数子集进行比较来测试每个验证函数。
一般而言,客户端输入验证并不会取代服务端的验证,而只能是增强和辅助。只有服务器后端才能保证数据输入的合法性。随着用户群的增长,应用程序的复杂性也随之增加。因此客户端和服务端都有着较为复杂的逻辑,验证函数在客户端以及服务器端之间的细微差异也会带来一些用户输入漏洞。于是Muath Alkhalaf 等人就开发了ViewPoint[18],通过自动发现客户端和服务端输入验证函数之间的不一致来识别用户输入的错误或不足。由于在客户端和服务端所形成的检查对用户输入会执行相同的约束集,因此可以利用这些冗余的检查来自动识别输入验证中的漏洞。SYM⁃DIFF[19]则是以一种语言不可知的方式计算两函数之间的差异,将这两个函数简化为Boggie[20]中间语言,然后使用Z3SMT 求解器[21]找到它们之间的语义差异。Te⁃vfik Bultan 等人采用了确定有限状态机来识别和修复输入验证中的安全漏洞。他们的方法[22]通过提取客户端和服务端输入验证和检查功能,使用符号定点计算将其建模为确定有限自动机(DFA),最后通过检查与人工指定的攻击模式相关的错误,或者通过客户端和服务端在输入验证和检查操作的不一致,从而识别检查输入验证和校验代码中的错误。
现有研究主要集中在如何对输入进行验证,只涉及到了输入验证的部分工作。无论是在前端页面对输入数据进行验证抑或是在后端进行验证,对于交互设计中以什么样的数据约束规则来进行验证的相关研究较少。
在实际的应用程序开发过程当中,业务频繁的更改以及需求文档的缺失都会使得开发人员对于交互界面之中何处应该存在数据约束以及存在数据约束的组件应该添加上什么样的约束缺乏一个客观的判断标准。有时开发人员可能会遗漏某些需要添加数据约束的地方,或者加上了错误的约束规则。而这同样给开发以及测试工作带来了许多的不利影响。①增加了开发的成本。投入更多人力物力进行测试和验证数据约束是否正确,这在一定程度上增加了开发人员和测试人员的工作量;②拖延了开发进度。开发人员需要对前端代码进行反复修改,影响开发进度,也降低了应用程序的开发效率;③降低了应用的开发质量。
设计并实现输入验证是一个具有挑战性的工作,目前主要的重担都落在了开发人员身上。而且许多已开发的且依赖用户输入的系统还需要多年的维护。在这期间,随着业务需求的变化以及功能的扩展。需求文档和应用程序的源代码都已变得更加复杂,越来越难以理解和维护。这在维护这些系统中实现的输入验证特性时会产生问题。当输入验证的规则发生变化时,开发人员需要理解这些规则是怎么实现的,之后才能启用这个变化。然而在大多数情况下开发文档并不可靠,因为开发人员并不确定他们是否把所有需要更改的地方都考虑到了。另外,开发人员也没有信心从代码中手动恢复输入验证的规则。因此,可以考虑提出一种辅助方法来提示开发人员界面中哪些地方应该有数据约束以及什么样的约束规则。
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!