
图1 源代码审计流程
2.3.1 词法分析
词法分析阶段是编译前端的第一个阶段,这个阶段的任务就是从左到右逐个字符对构成源程序的字符串进行扫描,即对源代码进行扫描,并按照定义好的词法规则进行解析,识别出一个个token,将源代码分割成由一个个token组成的数组,即形成一个token流。
2.3.2 语法分析
语法分析是在词法分析生成的token序列基础上,识别token序列之间的关系,并表示成一种后续程序处理过程中更容易理解和访问的中间表示形式,我们也称为抽象语法树。同时,将有关源代码信息存放在符号表的数据结构中,符号表和中间表示形式一起用来构造目标程序。
2.3.3语义分析
语义分析在抽象语法树的基础上进行分析,分析时考虑被检测程序的基本语义,根据上下文环境检测源代码中是否存在语义错误。
2.3.4控制流图构建
控制流图反映了程序中各语句之间的先后执行顺序。控制流图是一个有向图G=(V,E),其中V代表节点的集合,E是有向边的集合。为了更清楚地标识一个控制流图,额外加入2个控制流节点:START和STOP,其中START节点为控制流图的入口节点,STOP节点为控制流图的出口节点。控制流图中的节点V代表程序的1条语句,有向边E表示语句的控制流走向。
2.3.5数据流图构建
数据流图可以通过分析抽象语法树直接获得,数据流图能够表示语句和变量之间的数据依赖关系。通过从控制流图中提取控制依赖关系,从数据流图中提取数据依赖关系,将2种关系融合到同一张图中,进而形成程序依赖图。
2.3.6函数调用图构建
函数调用图是对程序中函数调用关系的一种静态描述,在函数调用图中,节点表示函数,边表示函数之间的调用关系。通过函数调用图可以了解程序中的函数及函数之间的调用关系。由于面向对象程序设计的多态性,程序的函数调用图只能大致表示出实际运行时函数的调用关系。
2.3.7数据流分析
数据流分析是指用来获取有关数据如何沿着程序执行路径流动的相关信息的集合。数据流分析的对象是控制流图,通过对控制流图的遍历,从中收集变量的数值产生位置及使用情况等信息,检测数据的赋值与使用是否发生不合理现象,从而检测源代码中潜在的安全漏洞。
2.3.8污点分析
污点分析是一种信息流分析技术,通过对程序中的敏感数据进行标记,跟踪标记数据在程序中的传播,从而检测系统中存在的安全问题。污点分析被定义为三元组<Source, Sink, Sanitizer>,Source即污染源,表示程序从外界获取的不可信输入;Sink即污点汇聚点,通常为一组安全敏感函数,通过数据流分析跟踪程序中污点数据的传播;Sanitizer即无害处理,代表通过移除危害操作等手段使数据传播不再对程序的安全性产生危害。污点分析则是在不运行和不修改代码的情况下,对程序进行语句分析,运用程序变量之间的数据依赖关系,找出污点源(Sources)和污点汇聚点(Sink)之间的传播路径,从而找出程序潜在的漏洞隐患,再通过验证数据方法进行无害处理(Sanitizer)。
3 安全编码原则和规范
本文给出了源代码安全编码原则和源代码安全编码规范,分析了Java Web漏洞的代码缺陷及产生原因,给出了预防结构化查询语言(SQL)注入、跨站脚本攻击、跨站请求伪造、文件上传、命令执行等漏洞的安全编码规范。
3.1 安全编码原则
3.1.1数据输入验证原则
首先假设所有的输入是恶意的,除非能够证明输入数据是安全的,包括来自传感器、文件、用户或数据库等的输入,不仅要限制输入数据的类型、长度、格式和范围,还要验证输入数据是否包含有害信息。
3.1.2身份验证原则
为防止身份信息被窃取,用户身份验证信息在存储、传输等过程中应采取保护措施。在通信通道采取身份验证信息加密保护机制,如使用安全套接层(SSL)方式进行传输;口令的存储不应直接存储密码,而应存储密码的单向散列值,使用用户提供的密码重新计算哈希值,从而减轻字典攻击的威胁。同时限制用户的口令长度和复杂度,以及限制用户登录次数。
3.1.3 最小授权原则
如果恶意程序被注入软件中,进程被赋予的权限大小很大程度上决定了用户能够执行操作的类型。因此,软件中特定对象如进程、用户或计算机程序应被赋予最小权限,任何需要提权的操作,应尽可能保持最短的时间,一旦任务完成,应该立刻收回权限,从而限制潜在的安全风险。