1.导读文章主要从四个方面进行讲解:产品代码漏洞检测的背景与方法代码漏洞的搜索与深挖技术产品质量提升方法总结与展望二、产品代码漏洞检查背景与方法1.why-why检查产品代码漏洞一般来说,大部分产品质量问题都与程序代码有关。比如,银行软件存在漏洞,导致十几个客户的信用卡被盗刷。2003年,阿丽亚娜5号火箭爆炸,造成5亿美元的损失。由于电控系统软件问题,曾发生大面积停电,严重影响交通、通讯、居民生活等,都与产品代号有关。代码漏洞检测分析可以帮助用户从根源上减少70%-80%的产品崩溃和安全问题。只有及时消除代码中的崩溃和安全缺陷,才能保证最终产品的质量,有效降低整个产品的风险。2.when-whentocheckproductcodeforvulnerabilities在产品开发、测试和发布的过程中,流程越深入,漏洞的影响就越大。越早发现漏洞,修复成本越低。如下图红色曲线所示,横坐标为产品发布过程,纵坐标为缺陷修复成本。可以看出,在测试阶段维修成本比较低,产品发布后维修成本成倍增长。因此,在产品测试阶段,最好把产品代码中的所有漏洞都检查出来。那么如何检查产品代码中的漏洞。3.How-现阶段检查产品代码漏洞一般有两种方法,我们已经实现了这两种方法。一是源代码漏洞扫描和检查。主要方法是检查编码标准。常见的编码标准有四种,分别是error、security、disabled和suggestion。详情见下图。自定义代码规范的制定和实时更新,根据具体业务场景制定代码规范等,都可以查出产品代码的漏洞。另一个是二进制文件的漏洞扫描和检查。例如谷歌提供的veridex工具,可以扫描非法API调用。该工具将非法API分为三类。4、深挖产品代码漏洞的方法通过上面介绍的两种方法,只能检查特定的代码或二进制文件,但产品乃至整个公司代码库中隐藏的BUG都是惊人的。因此,在上述两种基本方法的基础上,我们引入另一种技术,代码漏洞搜索和深度挖掘技术,简称代码搜索。另外,经过调查,发现国外也有类似的研究。NASA、微软和其他组织已经使用代码搜索技术发现了多个零日漏洞。三、代码漏洞搜索与深度挖掘技术1、代码搜索的问题和挑战主要有6个难点,如下图所示。确定代码特征搜索速度慢代码信息量太少,无法定位漏洞。代码存储速度慢,过滤条件不兼容,数据量大,搜索数据量高达千万级代码文件。针对这些问题,我们进行了一系列的优化和改进。2、代码搜索的技术架构主要由5个部分组成,如下图所示。python后台部分用于增量更新数据源信息,实时更新索引。正行数据源主要使用mysql数据库,包括表结构设计、索引和分表设计等。Sphinx实时分布式索引,用于提供索引创建服务和搜索索引服务等。Php+nginxserver部分为前端提供接口服务。前端部分用于显示搜索结果和后台管理。3.代码搜索服务器代码搜索服务器为前端或其他系统提供API接口。共有6个模块,包括搜索模型、登录模型、验证模型、用户模块、日志模块、代码审查模块。数据库为以上六个模块提供数据支持。4、代码搜索后台大致分为3层:底层数据源层,支持svn和git代码仓库,源包括qbuild系统和授权系统,获取代码日志,增量下载文件,最后入库在数据库中。索引层主要从数据源获取文档信息,然后通过分词模型和倒排索引算法将索引存储在文件系统中。服务层主要是sphinx索引工具提供的索引服务。排序获取索引文档信息后,从前排数据库中获取文档的所有信息,返回结果数据。5.数据源的增量存储代码搜索的难点之一是数据源的存储速度很慢。为了解决这个问题,我们有如下优化方案,数据源的增量存储。主要有8个步骤:从qbuild或者授权系统获取代码地址获取当前代码地址的提交日期根据提交日期获取代码提交日志通过解析日志获取增量文件列表,然后执行以下操作对每个文件进行处理,先进行去重判断,然后下载文件,再去重判断,存入数据源,通过分词工具,最后实时存入索引。下载可以参考svn对应的命令如下。svnlog-r{0}--xml-v"{1}"--username"{2}"--password"{3}"--non-interactive--no-auth-cache--trust-server-证书>{4}svnexport-r{0}"{1}""{2}"--force--username{3}--password"{4}"--non-interactive--no-auth-cache--trust-server-cert在数据源增量入库方案中,有一个很大的问题需要解决,就是重复问题。可以看到对于svn,存在路径包含重复的问题。下面的路径包含上面的路径,上面的路径会存储两次。http://svn.example.com/svn/testxxx/111/222/333http://svn.example.com/svn/testxxx/111Git也有类似的问题,分支重复,会出现一大片重复提交不同分支代码记录的次数。http://git.example.com/root/11branch:masterhttp://git.example.com/root/11branch:v1.1我们的去重方法是moduleid+revisionforsvn,forsvn,同一个moduleid下的revision递增,不会有重复的问题。对应的,git通过仓库id+提交的sha1值去重。对于同一个仓库,提交的sha1值是唯一的。6、实时分布式索引技术代码搜索系统遇到的另一个困难是搜索速度太慢。为此,我们引入了sphinx索引工具。我们为什么选择sphinx索引工具?该工具支持多达数十亿的文档、数TB的数据和每秒数千次查询。支持各种数据源,包括xml、sql、python等。支持对结果进行各种过滤和聚合功能,索引快速高效,应用广泛,如维基百科、优酷土豆、github等。下图展示了今年的索引工具排行榜。可以看到sphinx排名第五,受众面广。(1)Sphinx工具使用Sphinx主要包括三个可用的工具:Index实时索引工具,主要对数据源数据进行倒排索引并存储。命令如下,sphinx.conf是sphinx的配置文件。eg:/usr/local/sphinx/bin/indexer-csphinx.confcodeSearchd搜索服务工具,可以通过sphinx扩展php访问该服务,使用如下命令。eg:/usr/local/sphinx/bin/searchd-csphinx.conf&Search搜索工具,客户端搜索工具,可以用这个工具来测试索引的正确性,一般只做测试用。eg:/usr/local/sphinx/bin/search-csphinx.confmykeyword可以看到这三个命令都使用了sphinx配置文件,那么如何配置这个文件呢。(2)sphinx实时分布式的配置细节一般情况下,一开始会使用主索引和增量索引,但是随着数据的增加,服务和运维都会有压力。通过优化,我们最终采用了实时分布式的方式。实时索引的好处是没有代码索引的延迟,不需要额外的计划程序更新和合并索引服务,降低了运维成本,提高了搜索的准确性和可靠性。分布式的好处包括提高资源利用率、提高搜索效率和提高搜索并发性,下面几行是字段的定义,rt_field是需要索引的字段,rt_attr_uint和rt_attr_timestamp是索引字段的属性,一个是int类型,一个是timestamp类型。第二个配置是分布式配置,类型是分布式,后面几行是分布式位置。第三个配置是索引服务配置。9312接口提供索引服务,9306接口接收实时索引服务。以下两行是日志位置。indexcoderealtime{type=rtpath=user/local/sphinx/indexer/files/coderealtimert_field=contentrt_field=filenamert_attr_uint=rpidrt_attr_timestamp=cdate}indexcodedistributed{type=distributedlocal=coderealtimeagent=localhost:9312:crt1agent=localhost:9312:crt2}searchd{listen=9312listen=9306:mysql41log=/user/local/sphinx/indexer/logs/searchd.logquery_log=/user/local/sphinx/indexer/logs/query.log}(三)代码搜索排序方式代码搜索是最重要的指标这是排序方法。本方案主要从词组评分、代码提交时间、BM25算法三个方面对代码结果进行排序。这三个指标中最重要的是BM25算法。下面简单介绍算法的实现。公式如下:Score(Q,d)是衡量query查询与文档相关性的计算公式,d代表当前文档。Q是查询中所有关键词的集合,qi是其中一个关键词,n是Q的长度,Wi是词的权重,R(q,d)是词和文档的权重。Wi默认为IDF值,N代表所有文档的个数,n(qi)代表包含该关键词的文档的个数,0.5是为了避免n(qi)为0的情况。大体意思就是一个关键词在所有文档中出现的频率越高,它越常见,它的重要性就越低,它的权重就越低。R(q,d)是词和文档的权重,大致意思是某个关键词在文档中出现的次数越多,描述越重要。Wi突出显示全局权重,R(q,d)表示局部权重。举个通俗的例子,比如在图书搜索过程中,几乎所有书籍中都会出现【作者】这个词,所以【作者】这个词的权重很低,【人工智能】这个词也不常见,如果某本书中经常提到人工智能这个词,那么很有可能这本书就是讲人工智能的。BM25算法通过统计方法对编码进行合理排序。4、提高产品质量的方法如何利用代码搜索技术提高产品质量,主要有两种方法:第一种方法是业务监管与开发相结合,修复代码漏洞。一方面,根据前面介绍的两种检查产品代码漏洞的方法,根据检测到的这些漏洞进行深入搜索,修复产品和公司代码库中的隐患,消除产品中的隐患。函数调用的模块,以避免代码漏洞的传播。第二种方法是检查产品代码的敏感词,比如代码审计系统的敏感词和禁用API的检查,文件签名系统的敏感签名信息的检查等。下图是一个demo代码搜索,主要由3部分组成。最上面是搜索输入,中间是过滤条件,包括时间、代码语言、所有者、代码仓库。最下面是搜索结果,主要包括文件名、仓库名、文件位置、版本号、提交日期、所有者。测试人员可以根据仓库和所有者信息找到相应的开发主管,然后监督和修复漏洞。五、总结与展望本文主要分三个部分阐述如何从代码层提升产品质量:第一部分是产品代码漏洞检查的背景和方法,主要讲两种检查产品代码漏洞的方法,即源代码漏洞扫描和检查,二进制文件漏洞扫描和检查,但这两种方法只能检查特定项目的代码,隐藏的bug量巨大,这就引出了第二部分,代码漏洞的搜索和挖掘技术。第二部分是本文的重点。扩展了代码搜索的技术方案和实现细节。第三部分从两个方面阐述了如何利用代码搜索技术来提高产品质量。代码搜索系统可以快速定位问题。通过不断探索细节,显着提升搜索速度,提升搜索排序质量。该系统有助于优化产品代码的质量。接下来,我们将从两个方面进一步优化,即代码推荐结合代码语义上下文和AI方法进一步提高代码推荐的准确性,以及功能代码推荐。【本文为栏目组织360科技、微信公众号“360科技(id:qihoo_tech)”原创文章】点此查看本作者更多好文
