代码审查技术

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

代码审查技术学习目标•掌握代码分析和评审技术•掌握自动化代码分析工具的使用建筑工程师的第一堂课-关注细节关注并弄清楚桥梁修建细节,否则你建起来的桥就有可能坍塌。-《安全编程–代码静态分析》1940年TacomaNarrows大桥600英尺的一段坍塌落入普吉特湾。代码审查对成本的节省黑盒测试的缺陷•黑盒测试既不充分,而且效率也低。•在系统完成之前,测试就无法开始,测试人员只有软件版本发布时才能拿到版本进行测试。Staticwhite-boxtesting•Findbugsearly•Findbugsthatwouldbedifficulttouncoverorisolatewithdynamicblack-boxtesting•Costeffective•Sidebenefit:giveblack-boxtesterideasfortestcasestoapplywhentheyreceivethesoftwarefortesting不懂开发怎么做代码审查?霍元甲因为他本人身体虚弱,所以父亲从小不让练武功,而生长在那样的环境中,他天天可以看到兄弟们在练功,招式已经记忆在心里,但是苦在没有练功的机会,他利用体力劳动的过程中,改变劳动方式,趁机练功,后来发展到独创“迷踪拳”。代码静态分析•静态分析是指在不执行的情况下对代码进行评估的过程。包括:-类型检查-风格检查-程序理解-BUG查找-安全审查静态分析-类型检查在Java中,下面的语句虽然符合类型检查规则,但是会在运行时失败,抛出一个ArrayStoreException异常:Object[]objs=newString[1];objs[0]=newObject();//lint-w2//lint+e734#includestdafx.hintmain(){charch=0;intn=0;//...ch=n;return0;}VC6编译通过,但是PCLint可以通过静态代码检查找出类型转换造成的精度丢失问题静态分析-风格检查•常见工具C/C++:PC-LintJAVA:PMD.NET:StyleCop风格检查更加挑剔,也更加注重空格、缩进、命名、注释、程序结构这些表面的东西。风格检查程序所展示的错误往往都是影响代码的可读性和可维护性的问题。typedefenum{red,green,blue}Color;char*getColorString(Colorc){char*ret=NULL;switch(c){casered:printf(red);}returnret;}gcc的“-Wall”选项将检查出其中的问题。typedefconstchar*CSTRING;CSTRINGrevere(intlights){CSTRINGmanner=byland;if(lights0)if(lights==2)manner=bysea;elsemanner=;returnmanner;}intmain(){printf(TheBritisharecoming%s\n,revere(1));return0;}静态分析-程序理解•程序理解工具能帮助我们搞懂代码库中的大量代码,洞察程序运转之道。•集成开发环境(IDE)一般至少都包含某些程序理解功能,例如:“查找本方法的所有应用”。•常用工具:-代码流程图:CodeVisualtoFlowchart-UML与源代码双向工程,例如FujabaFujiaba能在UML视图和源代码之间来回转换静态分析-Bug查找•BUG查找的目的不像风格检查那样抱怨格式方面的问题,而是根据“BUG惯用法”(规则)来描述代码中潜在的缺陷。•常用工具:PMD、FindBugs、Coverity、Klocwork•EmptyCatchBlock:EmptyCatchBlockfindsinstanceswhereanexceptioniscaught,butnothingisdone.Inmostcircumstances,thisswallowsanexceptionwhichshouldeitherbeactedonorreported.•Example:publicvoiddoSomething(){try{FileInputStreamfis=newFileInputStream(/tmp/bugger);}catch(IOExceptionioe){}}stringstr=;for(inti=0;i100;i++){str+=i.ToString();}静态分析-安全审查•最早的安全工具ITS4、RATS、Flawfinder比素有美名的grep多不了多少东西;绝大多数情况下,它们将对代码进行扫描,寻找对strcpy()这样的函数所进行的调用。intmain(intargc,char*argv[]){charbuf1[1024];charbuf2[1024];char*shortstring=“ashortstring”;strcpy(buf1,shortstring);//safestrcpy(buf2,argv[0]);//dangerous}好的安全分析工具将会区分出第一个strcpy调用是安全的(尽管可能不需要),而第2个调用则是危险的。静态安全分析工具测试基准•SecuriBench是一个基于Web的开源Java程序集合,包含一些已知的安全缺陷:~livshits/securibenchSecuriBenchMicro是SecuriBench的缩减版:~livshits/work/securibench-micro•ABM(AnalyzerBenchmark)测试基准由一些小程序和大型的真实程序构成:比较静态安全分析工具的最佳方法是使用这些工具分析同一代码并比较其结果。把工具引入到代码审查流程中练习:读代码、找错误intmain(intargc,char*argv[]){charheightString[12];charweightString[12];intheight,weight;floatbmi;printf(Enteryourheightininches:);gets(heightString);printf(Enteryourweightinpounds:);gets(weightString);height=atoi(heightString);weight=atoi(weightString);bmi=((float)weight/((float)height*height))*703.0;printf(\nBodymassindexis%2.2f\n\n,bmi);return0;}通过代码审查找出常见安全问题•不恰当地处理输入•缓冲区溢出•错误和异常处理审查输入处理错误•怀疑、审慎是安全之本。-本杰明.富兰克林•“绝对不要相信输入!”•程序员不得不接收用户输入,但是又不能够相信输入-那该怎么做呢?明智的方法是充分检查输入,并且验证输入的正确性。•输入包括:命令行参数配置文件从数据库中检索出来的数据环境变量网络服务注册表值临时文件…不要盲目依赖数据库的数据来保证应用程序的正确运行。这段代码没有对查询所返回的记录行数进行检验,只是简单地调用返回的第一行记录:ResultSetrs=stmt.executeQuery();rs.next();intbalance=rs.getInt(1);对来自数据库的数据加以验证,确保数据表中唯一值所对应的数据行的唯一性。如果存在2个数据行,则表明可能有攻击者试图插入伪造的数据行。修正后的代码检验了返回的数据行,以保证只返回一行数据:ResultSetrs=stmt.executeQuery();if(!rs.next()){thrownewLookupException(“没有余额数据行!”);}if(!rs.isLast()){thrownewLookupException(“余额数据行多余一行!”);}intbalance=rs.getInt(1);•千万不要依赖DNS域名或者IP地址来进行认证。因为如果攻击者获取了DNS更新权限(DNS缓存中毒),则可能将数据包路由到自己的机器上,或者伪装IP地址,使得系统误认为是同一个域中的机器。structhostent*hp;structin_addrmyaddr;char*tHost=trustme.com;myaddr.s_addr=inet_addr(ip_addr_string);hp=gethostbyaddr((char*)&myaddr,sizeof(structin_addr),AF_INF);if(hp&&!strncmp(hp-h_name,tHost,sizeof(tHost))){trusted=true;}else{trusted=false;}黑名单vs.白名单•黑名单法(blacklisting):尝试枚举所有不能接受的输入值。•白名单法(whitelisting):通过已知正确值清单来进行检查。•下面是摘自Tomcat5-1.31版本中的一段程序,采用了一个黑名单,假定在Web页面中只有4个特殊的字符输入才会导致程序的安全问题:for(inti=0;icontent.length;i++){switch(content[i]){case'':result.append(<);break;case'':resule.append(>);break;case'&':resule.append(&);break;case'':resule.append(");break;default:result.append(content[i]);}}•黑名单法只拒绝已知恶意的数据,而在给定环境中,恶意值的集合通常是难于枚举的(或者可能是无限的),所以黑名单法一般是不完善的。•即使可能列出一个危险输入值的完整清单,也很可能随着时间的变迁而过时。黑名单法是不利于应用程序安全的。审查缓冲区溢出错误•缓冲区溢出(bufferoverflow):将大量数据塞入一个较小的缓冲区中所导致的程序漏洞•缓冲区溢出通常被攻击者用于重写内存中的数据。•近10年来,缓冲区溢出漏洞的数量没有明显下降的趋势。voidtrouble(){inta=32;charline[128];gets(line);}•缓冲区溢出就是将长度超过缓冲区大小的数据写入程序的缓冲区,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其他指令。•当一个超长的数据进入到缓冲区时,超出部分就会被写入其他缓冲区,其他缓冲区存放的可能是数据、下一条指令的指针,或者是其他程序的输出内容,这些内容都被覆盖或者破坏掉。可见一小部分数据或者一套指令的溢出就可能导致一个程序或者操作系统崩溃。天生危险的函数•gets、cin、scanf、•strcpy、wcscpy、lstrcpy•sprintf、fprintf、swprintf禁用函数列表Linux和Windows平台上替换C类库的字符串解决方案GNU/Linux•Bstrlib:•FireString:•GLib:•Libmib:•Vstr:•SafeCRT:

1 / 150
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功