源代码安全检测工具PC_Lint与ITS4实例 zz

【信息科学与工程学】【安全领域】 第八十八篇 网络空间安全21 如果员工认为安全政策和流程(如复杂的密码规则、频繁的认证、繁琐的软件安装审批)阻碍了工作效率,他们可能会寻找变通方法,例如:写下密码、共享账户、使用未经批准的云服务(影子IT)、绕过安全控制。例如,一个用于显示用户列表的API,可能返回每个用户的完整个人资料,包括邮箱、地址、电话等敏感字段,而前端可能只显示了姓名。:在OAuth 2.0或OIDC流程中,攻击者可能截获授权请求中的“授权码”,或窃取“访问令牌”,然后将其用于另一个客户端(非原始授权的客户端),从而以用户身份访问受保护的资源。 阅读详情
 
1. 目前代码的安全形势2 `4 S# {, ~% U4 a
  1.1 缓冲区溢出问题( t) b6 W7 V) n: S- C
  “缓冲区溢出”是越过了数组边界进行读写的一类内存访问错误。大家知道,在标准C 语言库中提供了许多关于字符串的操作的函数,如:gets() 、strcpy () 、strcat ( ) 、strcmp ( ) 、sprintf ( ) 等。它们在本质上是不安全的,存在安全隐患,例如gets (str) 指令,在编译这条指令时,str 以字符数组的身份分配内存空间,并且str是所分配内存的一个连续存储区的首地址。gets 读取标准输入的文本,把第一个字符存入str 首地址内存单元中,后续字符依次存储,直到标准输入遇到结束符“ / 0”并存放到最后一个字节的存储单元中。在执行这条指令时,由于程序员不能预先确定缓冲区的大小,若读入的文本长度超出编译给定的存储区长度,则读入的字符会覆盖str 所代表的存储区的后续空间,因此,出现了所谓的缓冲区溢出。下面是一段存在缓冲区溢出问题的代码:4 i. u# m: O* y
      #include 
  using namespace std; " J; G4 X* N4 T/ W( U- m
  int main() 
  { 5 C  M' p0 q  s0 b, /- s5 }
  char pwd[10]; 6 V' _0 ?7 _7 f: Z# Y0 i' r, j
  cout<<"Please input your inite password(limited 10 chars):"; 
  cin>>pwd; 8 H' I2 s" w( ?* S$ X5 f
  char userpwd[10]; 
  cout<<"Please input your password:"; 6 q; [! S/ A1 t. c# {; g  _$ n+ ?
  cin>>userpwd; $ Q/ Y  /0 I) U- O
  cout<<"pwd :"< 9 h! v8 E' W) q* o5 w. ]
  cout<<"userpwd:"< 
  return 0; , S$ t# R& J6 ?
  } ! m/ ?2 v# {* z- x6 c& q: D

  实验表明,缓冲区溢出会出现两种风险: ①相邻该缓冲区的内存空间容易被覆盖,如果被覆盖的内容很关键,就可能造成非常严重的安全隐患。②通过覆盖运行栈中函数的返回地* r+ s. k- j+ T/ d, r
  址来诱导程序执行其它任意代码,出现“栈溢出”覆盖错误。而上面的这段代码所带来的问题就是第一种,假设程序的密码为“1111111111”(10个‘1’),如果用户输入密码“2222222222222222222222”(22个‘2’),那么,程序原先的密码就会被恶意篡改为“2222222222”(10个‘2’),从而通过验证。
  1.2 访问内存错误; z6 @3 X1 ]7 n% E1 I
  访问内存错误是引发C 程序安全隐患的又一重要因素,它可能由数组、指针或内存管理造成,而缺乏边界检查是C 程序中使用指针和数组导致访问内存出错的根源。9 q4 G, g8 I. ?& Y
  根据内存的分配、使用和释放过程,访问内存可能出现以下错误: ①使用了分配未成功的内存; ②引用了分配成功但未初始化的内存; ③内存分配成功又进行了初始化,但对它的操作越过了边界,出现“空间访问”故障; ④未释放内存直至内存耗尽,出现“内存泄露”错误; ⑤访问被释放的却具有不确定值的内存,出现“时间访问”故障。
  1.3 指针的引用错误
  指针是C 程序的重要的数据类型之一。在C 程序中,对指针的使用最灵活、最核心、最重要,称之为C 程序中最精华的部分,有“掌握C 指针就掌握C 语言”之说。但C中指针的使用又最复杂,最易出错。因此引用指针时须特别注意两个最基本要点: ①定义指针本身; ②必须使已定义的指针指向其应该指向的合法的存储空间。  q+ C0 C8 ^9 w" f
  1.4 随机数的使用和异常的控制
  系统随机数的产生函数rand() 提供的是伪随机数,其内部实现可以生成重复的输出值。
  C 语言程序设计没有提供异常处理机制,异常检测和处理全部由程序员预设完成,一旦异常发生而又无预防处理就会出现不可预测的错误和安全问题
2. 源代码的静态检测工具PC_Lint 的使用7 O6 d) v. }0 N1 `/ x+ Y
  2.1 PC_Lint能做什么. /  P& K! S( X3 [) R8 C) R8 V

                                                                                                          INTRODUCTION PClint/FlexeLint finds quirks, idiosyncrasies, glitches and bugs in C and C++ programs. The purpose ofsuch analysis is to determine potential problems in such programs before integration or porting, or toreveal unusual constructs that may be a source of subtle and, yet, undetected errors. Because it looksacross several modules rather than just one, it can determine things that a compiler cannot. It is normallymuch fussier about many details than a compiler wants to be.


  上面的这段介绍是从 PC_Lint 的自述文档中摘拷贝出来的,它的优点我用亮色突出显示了。PC-lint软件性价比高,易于学习,容易推广和固化到软件开发测试流程中去,所以在全世界得到了广泛的应用。PC-lint使用方法很简单,可以用命令行方式进行,例如lint-nt –u std.lnt test1.c test2.c test3.c 也可以使用MAKEFILE的方式。此外,它还可以集成到很多开发环境或常用的代码编辑软件中,比如集成到Source Insight/SLICKEDIT/MS VC6.0/KEIL C..等。PC-Lint还支持Scott Meyes的名著(Effective C++/More Effective C++)中说描述的各种提高效率和防止错误的方法。; U4 @+ k  L6 U, B& I2 G% K
  2.2 安装和配置PC_Lint5 r4 d3 Q: K8 ]4 f- l- A$ B' U' u
  对于初学者来说,PC_Lint的安装和配置并不简单,特别是要弄懂在配置过程中生成的那些文件的意思和设置环境变量等问题更成问题。; L- D$ u; z6 e  a+ D
  在点击可执行安装文件在安装过程中的最后一步会弹出一个对话框询问是否现在要配置PC_Lint,如果点击是的话,紧接着的操作就是根据你的电脑环境和你的需要来配置你的PC_Lint,并由此来生成配置文件 ** . lnt,一般来说初学者都可以通过这个配置向导来配置一个适合你计算机环境的PC_Lint ,而对于PC_Lint的使用老手,可以直接编( a* }3 D( g. b  J. B& X
  配置文件 ** . lnt.下面是配置向导的配置过程。
  首先,第一步是欢迎界面:7 J4 P8 R, q4 I
  第二步是PC_Lint的一些自述性内容,说明PC_Lint的一种用法和这个配置向导的作用等等。
  第三步是问你生成一个新的配置文件还是使用一个以前已有的配置文件来产生新的配置文件。在此之前,你必须先选择一个工作目录,一般情况下选择你的安装目录这样方便后面配置工作目录。
  第四步,选择你的编译器环境。PC_Lint支持的编译器环境很多。根据你计算机环境选择合适你的计算机选项。3 L8 ^, n% I9 f' b! W
  第五步,选择你计算机的硬件平台(默认情况下是32位的内存模型)。
  第六步,选择你所用的库文件,STL、MFC、ATL是比较常用的几个库,这也是建议选择的几个库。
  第七步,让你选择是否使用曾经为C/C++编程提出过重要建议的人所编写的配置文件。如果选择这些作者的建议,那么他提出的编程建议方面的选项将被打开,作者建议的配置文件名为AU-xxx.LNT将被从一个lnr的目录拷贝到你的安装目录,建议全部选择。3 f2 }" ~: X- X/ }- |: V! {0 U
  第八步,接下来是选择用何种方式设置包含文件目录,如果选择使用 –i方式协助设置包含文件选项,下一步就会要求输入一个或多个包含路径。也可以跳过这一步,以后手工修改配置文件,-i选项体现在STD.LNT文件或新创建的STD_x.LNT文件中,每个目录前以-i引导,目录间以空格分隔,如果目录名中有长文件名或包含空格,使用时要加上双引号,如 -i“E:/Program Files/Microsoft Visual C++/VC98/include”。; l8 N( {* O) K/ f" I
  接下来就是在下面的文本框里可手工输入文件包含路径,用分号“;”或用ctrl+Enter换行来分割多个包含路径,或者在目录树中直接选择。填完后点击“下一步”按钮:
  第九步,因为第三步选择了“Create a new STD.LNT”选项,所以出现以下对话框,表示std_x.lnt在配置路径下已被创建,这里的std_*.lnt实际上包含了 std.lnt的信息,除此之外还有我们选择的包含路径和使用的库等配置信息。! F( r$ x- e# @  h' v4 o( Q

第十步,对话框询问是否使用现在生成的std_x.lnt文件取代std.lnt文件。+ U1 o% Z" l4 [# i% L# a5 ?6 X9 Y

第十一步,接下来将会准备产生一个控制全局编译信息显示情况的选项文:OPTIONS.LNT,该文件的产生方式有两种,一种是安装程序对几个核心选项逐一解释并提问你是否取消该选项,如果你选择取消,则会体现在OPTIONS.LNT文件中,具体体现方式是在该类信息编码前加-e,后面有一系列逐一选择核心选项的过程。如果选择第二种选择方式,安装文件会先生成一个空的OPTIONS.LNT文件,等你以后在实际应用时加入必要的选项。: m2 j9 [& v5 q: u$ P# O- C
  第十二步,选择所支持的集成开发环境选项,可选多个或一个也不选,PC-Lint提供了集成在多种开发环境中工作的功能(最近发布的VisualLintAddinSetup v1.5.7.74.exe可提供更好的集成使用效果),例如可集成在VC、BC、Source Insight中。这里我们选择Microsift Visual C++ 6.0,这样env-v6.lnt就会被拷贝到配置路径中。
  第十三步,安装程序会生成一个LIN.BAT文件,该文件是运行PC-Lint的批处理文件,为了使该文件能在任何路径下运行,安装程序提供了两种方法供你选择。第一种方法是让你选择把LIN.BAT拷贝到任何一个PATH目录下。第二种方法是生成一个LSET.BAT文件,在每次使用PC-LINT前先运行它来设置路径,或者把LSET.BAT文件的内容拷贝到OEXEC.BAT文件中。建议选择第一种方法,指定的目录为当前PC-Lint的安装目录。我们选择第一种方式:“copy LIN.BAT to one of my PATH directory”,然后单击“下一步”输入PATH目录。(至于怎么使用它们来检测我们的代码,将在2.3节中对三种方法进行详细介绍。)
  最后一步,确认完成配置
  就这样我们安装并配置好了PC_Lint,下面我们来看看这配置过程中所生的文件的含义:co-xxx.lnt(co--compiler描述有关编译器环境)、lib-xxx.lnt(lib--library库)、env- xxx.lnt(env--environment开发环境),在这个目录下还有其它PCLint所支持的编译器、库及集成开发环境的lnt配置文件,所有的lnt文件均为文本文件。2.3 在命令行方式下使用PC_Lint
  在工作目录下使用PC_Lint,工作目录也就是你存放源代码的目录,你必须将在配置过程中生成的 lin.bat 拷贝到这个目录下,然后使用形如下面的命令方式检测你的代码: * v1 D7 J0 j/ ]8 /5 L
Lin options filename1.h filename2.cpp ……
; n0 ?6 O% w  R: X( P
  在PC_Lint的安装目录下使用PC_Lint,在使用之前必须将你的存放源代码的目录添加到文件lset.bat中,并运行这个批处理文件。然后就可以使用下面的命令方式检测你的代码了。 ' x# m/ w( c2 r6 D
Lint-nt options filename1.h filename.cpp ……
' M' _/ W4 W! d  Z* O5 w
  我们也可以通过设置环境变量来达到在任何目录下来检测我们的代码的目的。在你的工作目录下直接敲入如下命令: 2 i! u' |' t7 d; u" f* |. c
Set path = Installdir (同样你也可以通过其他方式来设置你的环境变量)
; p3 X* E  ]; D
  然后你就可以在你的任何工作目录下使用 lint-nt 命令而不必在此之前来将文件lin.bat 拷贝到你的工作目录下或将你的源代码拷贝到PC_Lint的安装目录下了,这种方式适合于工作目录多且不确定的情况下使用。
  2.4 将PC_Lint 加载到Visual Studio(6.0 and .net)中# ~- h& K& b0 X( C' j7 w8 p
  因为PC_Lint可以支持单文件检测,工程检测,模块检测,所以我们下面在Visual Studio中分别添加三种外部工具的方式来介绍怎样将PC_Lint加载到Visual Studio中。
  第一种,添加检测单文件的外部工具(PC_Lint(Simple Check))。
  在Visual Studio 8.0 依次打开 Tools—>Exteral Tools, 弹出如下所示的对话框,然后添加一个新的外部工具。并按如下方式填入命令行、参数和初始目录:
      Command: C:/Lint/Lint-nt.exe 7 {* @. ^' P5 e7 F' C4 ^. /% P
  Argument: -i“C:/Lint” –u std.lnt env-vc6.lnt $(ItemFileName)$(ItemExt) 
  Init Directory: $(FileDir) 
  X_Use Output Window __Prompt for arguments __Close on exit
  k  q4 g6 k7 ?. L5 I9 B& `0 B
  第二种,添加工程检测的外部工具。因为一个工程中可能包含多个文件,所以在进行检测之前必须先收集工程的信息。而工程的信息如所包含的文件的文件名、选项信息等都包含在工程目录下的一个后缀名为 .vcproj的文件中,PC_Lint可以读取这个文件中的信息,并声称一个projectname.lnt 的文件,然后,再根据这个文件来对这个工程进行检测。所以必须配置如下的两个工具PC-lint (Project Creation) 、 PC-lint (Project Check)。

在进行检测时,先用工具PC-lint (Project Creation)生成一个projectname.lnt,再用工具PC-lint(Project Check)来检测。
      PC-lint (Project Creation) : & N. w, L/ q$ d/ x# O) w8 k
  Command: C:/Lint/Lint-nt.exe : o4 Q: {; w5 z; ~& M3 e; E
  Argument: - -v -os($(TargetName).lnt) "$(TargetName).vcproj"t 
  Init Directory: $(FileDir) ) p6 f$ m- M5 j2 {
  PC-lint (Project Check): 
  Command: C:/Lint/Lint-nt.exe 
  Argument: -i"c:/lint" std.lnt env-vc7.lnt "$(TargetName).lnt" 3 p0 ^! u* W! Y, f% r1 E3 S
  Init Directory: $(FileDir)
9 o9 [/ t% H0 ?7 m$ ~* J# q
  第三种,添加模块检测外部工具。配置的输入选项如下:
      Title: PC-lint (Unit Check) ) ^  h2 S) N& C- b' D
  Command: c:/lint/lint-nt.exe + f: P+ k8 ^. o5 }
  Arguments: -i"c:/lint" std.lnt env-vc7.lnt --u "$(TargetName).lnt" "$(ItemPath)" 
  Init. Dir.: $(ProjectDir) 
  X_Use Output Window __Prompt for arguments __Close on exit
" x1 z( /( C" H/ R- l7 z6 k
  将PC_Lint加载到Visual Studio 6.0 中的操作步骤和上面大概差不多,毕竟只是版本不同而已。但在配置时的输入有所不同,如下:) o  p1 B; n: A8 D
      6.0 8.0 
  Arguments "$(FileName)$(FileExt)" $(ItemFileName)$(ItemExt) 
  Initial directory $(FileName) $(ItemDir)
2.5 将PC_Lint 加载到 Editplus 中4 C% o! /# e& I7 o/ l0 s

  Editplus和Source Insightde 的检查环境类似,所以借用env-si中的环境配置,配置的参数如下图示:0 H4 ]9 d$ f1 n* [* x' q/ |- Z: u

  菜单文本:PC_Lint(Simple Check)+ Z1 [4 g# B6 O1 t& B2 x
0 k( V, y3 D5 [" C- M  v
  命令: C:/Lint/lint-nt.exe5 Q. m. W- o, H9 f
/ d, ?* N) y( e0 W4 s; |& O7 B: ~
  参数: -i"c:/lint" std.lnt env-si.lnt $(FileName)2 u' |; N: s! S, E+ q4 V: W

  起始目录:$(FileDir)2.6 PC_Lint常用选项(opitions)的解释
2 D; T+ T( Z2 j1 L5 n
  常用参数的设置4 L5 h3 N# |- E- J- /9 i" e3 |
/ ?1 X/ l2 G) Y
  Message的分类:: h9 h# d4 d) B5 ~1 w, S9 I0 C( V
( E* ~7 V% _; k7 B0 |# T! x$ T
      C C++ Warning Level / }9 T+ r+ V% R% M8 ]
  Syntax Errors 1 – 199 1001 – 1199 1 
  Internal Errors 200 - 299 0 " Z0 [1 B5 P% V+ t+ h/ v) G
  Fatal Errors 300 - 399 0 + r* f( N# c$ R
  Warnings 400 – 699 1400 – 1699 2 
  Informational 700 – 899 1700 – 1899 3 ! ]7 F, X+ {! r6 C
  Elective Notes 900 - 999 1900 - 1999 4 * K8 z) D9 F' s- ?3 @# T
6 e0 ?9 C7 d0 m0 n$ |
/ E1 I& J, b  V' x+ t; w. [
  错误信息禁止选项说明$ t$ u7 e! w4 D# [7 u$ s

      命令格式 说明 代码中的举例 + U! Y2 J: b: l, X' v# q6 c
  -e# 隐藏某类错误 /*lint -e725 */ 9 V0 q/ _3 |  _: L  Y8 Z
  -e(#) 隐藏下一表达式中的某类错误 /*lint –e(534) */ 
  printf(“it’s all”); 
  !e# 隐藏本行中的错误 /*lint !e534*/ printf(“it’s all”); ( e. u/ V" /0 G$ l$ t1 |
  -esym(#, Symbol) 隐藏有关某符号的错误 /*lint –esym(534, printf)*/ 3 U/ /( n& E0 V3 t& N
  printf(“it’s all”); , Z, D: J/ z2 P7 a+ m
  -elib(#) 隐藏头文件中的某类错误 /*lint –elib(129) */ 2 U- ~! c9 _" E& m; @. |
  #include “r01.h” 
  -efunc(#, ) 隐藏某个函数中的特定错误 /*lint –efunc(534, mchRelAll)*/ 
  unsigned int mchRelAll(mchHoData 
  *pHoData) 4 c; @1 q; x, A  B8 c8 v9 w1 b2 r
  { 
  printf(“it’s all”); + V: b3 n2 l' J0 `# N/ K
  }   @  k( C6 A. g5 y$ o# R
  PC-Lint检测中的常见错误 8 w# c3 g/ `5 n# l8 q3 l: z2 y
  错误编码 错误说明 举例 
  40 变量未声明 
  506 固定的Boolean值 char c=3; 
  if(c<300){} 4 I" j$ V& w8 }% |2 f) x
  525 缩排格式错误 , m/ K- t6 |; l& L- j) g
  527 无法执行到的语句 if(a > B) 1 T; Z- r- N& d( n
  return TRUE; $ C2 N" [1 N! /# j1 g" [2 U4 `
  else 6 U0 s: Y- t  p  v6 f, h8 e
  return FALSE; 9 i! ^" g; _, I* n- v$ F- [$ b
  return FALSE; , o! O3 [: I- z
  529 变量未引用检查变量未引用的原因 $ w: {; C9 ~2 c  b: H
  530 使用未初始化的变量 
  534 忽略函数返回值 
  539 缩排格式错误 6 s2 y4 D1 H, P4 e% {
  545 对数组变量使用& char arr[100], *p; 8 U7 r" {/ u# G, A) R$ n5 n$ ]; ^
  p=&arr; 
  603 指针未初始化 void print_str(const char *p); 9 j, o* {3 c0 w
  … 
  char *sz; 
  print_str(sz); 
  605 指针能力增强 void write_str(char *lpsz); 
  … 
  write_str(“string”); / X4 h; T4 j! j
  613 可能使用了空指针 
  616 在switch语句中未使用 break; 2 o; i1 k# K# L
  650 比较数值时,常量的范围超过了 if( ch == 0xFF ) ... 
  变量范围 " {/ M; M6 G, Z- }
  713 把有符号型数值赋给了无符号型 
  数值 1 ]% F& T$ k' K9 t
  715 变量未引用 1 u' Y( ^1 E9 F* /9 u
  725 Indentation错误 ; G& j% J. u: M( g
  734 在赋值时发生变量越界 int a, b, c; 
  … 
  c=a*b; 0 V: x8 r, x) S! v0 n3 U; J; @/ e1 D7 S
  737 无符号型变/常量和有变量型 
  变/常量存在于同一个表达式中。 
  744 在switch语句中没有default 
  752 本地声明的函数未被使用 
  762 函数重复声明 
  774 Boolean表达式始终返回真/假 char c; if(c < 300)
3. 源代码的静态检测工具Its4 
  3.1 its4 的相关介绍
% a2 p: R) t8 w: p3 s6 ^% G7 D
ITS4: Software Security Tool 
  Cigital developed ITS4 to help automate source code review for security. ITS4 is a simple tool that statically scans C and C++ source code for potential security vulnerabilities. It is a command-line tool that works across Unix and Windows platforms. . V  }# X- @. d) G
  ITS4 scans source code, looking for function calls that are potentially dangerous. For some calls, ITS4 tries to perform some code analysis to determine how risky the call is. In each case, ITS4 provides a problem report, including a short description of the potential problem and suggestions on how to fix the code. 
ITS4 and its source code are provided here to the security community for any use that does not compete with Cigital's consulting practice. 4 t# N. r4 d  M  q- F( v$ /
4 o1 o( @4 |7 }2 t* o! A

  3.2 怎么安装ITS4+ K8 {" M+ q3 q; J- s( X

  ITS4 同其他windows 平台上的软件不同,它没有可执行的安装文件,从网站上下载下来的全部是ITS4的源代码(因此它的归属公司声称它为自由软件),所以必须编译和链接这些源文件,不过不用怕,它还给我们提供了一个名 MAKEFILE 的文件,在windows环境下,我们只要在使用nmakefile –f MAKEFILE 就可以生成一个可执行文件its4.exe。. I4 }5 ]% B% f7 L  X' F5 U
8 t  w% h: r! ]8 O, V  m: O
  3.3 在命令行方式下使用ITS4

  完成之后,如果你的当前目录不是 C:/its4/,那么你在除ITS4存放目录之外的其他目录下不能执行 its4 命令的(即使你已经设置过了环境变量),因为在执行这个命令的过程中,它会在C:/its4/下搜索一个名为vulns.v4d 的文件,如果失败,则这个命令就不能被正常执行。所以将编译后的整个its4目录复制到C盘生成C:/its4/.

  这样你就可以正常执行了 its4 命令了。如果你嫌输入its4 命令的目录太长,你可以将C:/its设置为环境变量,这样你就可以在任意目录下 执行这个命令来检测你的源代码了。
3 i9 s# d" j/ S- j. _! z
  3.4 在编辑器和编译器环境下使用ITS4

  由于将its4 添加为编辑器和编译器的操作同PC_Lint差不多,所以这里就不罗嗦了。但要提醒的是,一定要注意配置Visual Studio 6.0 和 Visual Studio 8.0 时,参数项和初始目录有所不同,前者为 $(FileName)$(FileExt)/ $(FileDir)后者为$(ItemFileName)$(ItemFileExt)/ $(ItemDir)0 P% r. q# f1 `2 J# b" ?

  4. 怎样的代码算是安全的代码, l3 e, o2 j3 X& U5 i
  H3 G- z1 T" k0 q$ Q
  4.1. 尽量少使用(或不使用)存在严重安全的C语言库函数
& m9 |. |7 ]' q4 m$ g& x1 l
  由于C 语言自身的支持库存在本质上的安全隐患,由此引发出C 程序设计中存在多方面的安全问题。如下面的这些可能引发缓冲区溢出错误的函数: 
; R" ^& S8 ^" D2 t* /
Strcpy() strcat() printf() scanf() gets() put() …… 
' E# B8 e. s( F- Y! h" A
7 L' n5 Y: W: @6 W7 W8 D
  在使用到这些函数的时候,我们应该尽量找其他一些更安全的函数来替换,如下: 6 z5 j  }) U  Y

Strncpy() strncat() fscanf(stdin, "%255s", buffer)…… 
, X8 R# d5 `" S

  下面的例子演示了怎样安全的写代码:, M( h; b8 m" [5 u/ C# o

      不正确情况                        正确的情况 5 g$ X9 H1 d) c$ [' C4 /8 S
  void func(char *str)         void func(char *str) 
  {                                      { 
  char buffer[256];             char buffer[256]; 
  gets(buffer, str);              fgets(buffer, sizeof(buffer) –1,stdin); . p8 U( e$ ~( K% v
  return;                             return; 
  }                                      }
  5. 我们应该怎样来写安全的代码- J" a/ I  J! E+ R
! d3 y" Z4 V5 H9 o
  5.1. 按照如下书中所诉说的标准和规范:/ }0 g( `5 P, ]9 @
; C* Q6 V8 G; P. K
  《More Effective C++》、《C++编程规范》

  5.2.遵循行业行规& L4 x* r4 R- @& E0 m9 a: k

  我的建议是遵循行业行规,严格按照规范写程序6. 用PC_Lint 、ITS4分别检测源代码示例, s! d* b' f* ?. r# e

  下面是一个用ITS4检测一个名为a.cpp源文件时的报告:

  源代码:$ o* q1 f0 b! A  _! /% K1 @7 h( l

      #include % K/ f- B; ^% Z) i: H6 y  m
  void main() 
  { 
  printf("Hello Makefile!"); 
  char ch[50]; 
  gets(ch,stdin); 
  scanf("%c",ch); % ~. p% r8 @) d
  } 7 T5 c2 R# a$ @% K$ J: F4 C2 D
( Q/ R+ o! Z8 l( b* r0 |: y0 x
) f& C0 b7 m9 |: U3 d
  检测报告:
! _/ c# G4 W& G$ ?8 h! ?
      a.cpp:7:(Urgent) gets # c; w) O8 g& M; `2 O
  The input buffer can almost always be overflowed. : f0 c9 S) J- N4 a: R; w
  Use fgets(buf,size,stdin) instead. / {  M* W1 @9 s' E3 e3 |
  ---------------- 
  a.cpp:5:(Urgent) printf 1 U: M  m; O) p
  Non-constant format strings can often be attacked. 
  Use a constant format string. $ t2 _; d" x0 ~' o
  ---------------- / X" e5 m8 o# p8 i2 o. g* R
9 W$ {2 L' i- {5 }
5 ~. B! _' F. a( D6 y% r6 F; P* k
  下面是一个用PC_Lint检测一个名为testpc.cpp源文件时的报告:8 /3 q; W7 `, w0 s6 e6 p; Y
; }9 X! J0 I4 Q+ i
  源代码:
9 R/ z: |) |; B/ @9 Z! ^
      #include 
  using namespace std; 
  int main() 
  { 
  int*fo; + h9 H% Z& q3 E2 W8 ?- t2 D- B
  fo[1] = 3; 
  fo = new int(10); 
  for (int i = 5 ; i < 15 ; i++ ) 4 G" e* T6 p' k  t9 y/ D- q1 O
  { / h; R! h8 h2 _/ T5 o4 j5 C& V% Q4 p
  fo = i; 
  cout<<"fo["< 

: w6 @+ U, o. h
      检测报告:

1 int main() 
2                     ………………     r9 u2 Z) j- d) O  |
3        int*fo; 
4 testpc.cpp(5) : Note 970: Use of modifier or type 'int' outside of a typedef ' {, @4 x3 b0 l: O2 Q  r1 V3 p
5    [MISRA Rule 13] ' F/ Z% {9 M3 |, c) H& ?
6                 _ 
7        fo[1] = 3; 
8 testpc.cpp(7) : Warning 530: Symbol 'fo' (line 5) not initialized [MISRA Rule 
9    30] 
10                      …………………     ^. R3 O6 W) Z, y* p0 o4 R
11                 _ 
12        fo = new int(10); 9 a" ^( ]1 G8 J8 N1 D/ {  Y
13 testpc.cpp(9) : Note 970: Use of modifier or type 'int' outside of a typedef & k5 m7 ?  L2 n, k
14    [MISRA Rule 13] 5 _. F( e& ^7 X5 H* D- w: p2 X7 E
15 testpc.cpp(9) : Warning 1556: 'new Type(integer)' is suspicious 4 E) h: b; I/ `' c5 m4 ~
16             _ 
17        for (int i = 5 ; i < 15 ; i++ ) 
18 testpc.cpp(12) : Note 970: Use of modifier or type 'int' outside of a typedef : }. c* ]/ a) F* I* Y* n% V. v2 o
19    [MISRA Rule 13] 
20                     …………………   
21                  _ 
22                fo = i; 
23 testpc.cpp(14) : Warning 662: Possible creation of out-of-bounds pointer (5 7 T# u& e- p3 d" O2 ?$ Q
24    beyond end of data) by operator '[' [Reference: file testpc.cpp: lines 9, 3 c' G  Y8 K# v8 I3 ]2 ^
25    12, 14] 
26                      …………………   ' P" y3 G# F: t0 u+ Z
27                                                 _ 0 b; c% R0 A/ n  k6 w/ K( U
28                cout<<"fo["<<i<<"]="<<fo<<endl; 
29 testpc.cpp(15) : Warning 662: Possible creation of out-of-bounds pointer (5 3 |) T& S( Z# H, ]/ B" ]
30     beyond end of data) by operator '[' [Reference: file testpc.cpp: lines 9, 9 u3 A  E: f' R* D0 E. W* L/ O: i
31    12, 15] 
32                     …………………   
33               _ 
34       return 0; ) p9 y, ~$ Z% ^5 d% l
35 testpc.cpp(17) : Warning 429: Custodial pointer 'fo' (line 5) has not been & W& n" j% Y+ A  ]$ o
36    freed or returned 7 // W0 P: k" I7 l4 d! _
37    

0 `; P, a: f/ G2 s$ O+ [
      报告分析:
0 L3 n. N' H* i9 p' t2 |; N1 ]3 {3 P
  在这份报告中,PC_Lint检测出了许多Visual Studio 8.0 不能检测出的潜在问题,如:
( E- d5 ^5 x5 b, G# m) o" k4 ^
  在上面的第8行报告使用了为初始化的变量fo;* b! o/ m! C6 b/ d( /0 o9 G

  在上面的第23、29行报告使用的指针索引可能越界了;$ I, W" W& k! m/ P5 b! /
% V$ I& ?0 x0 N2 i( ?( H% B9 L* D0 V
  在上面的第35行报告程序中动态申请的空间没有释放。
ITIL 4 最新中文教程.pdf ITIL 4 最新中文教程 ITIL 4 最新中文教程 立即下载

相关推荐

its4(已经编译)

代码安全,主要用于C++代码的安全作用,我现在正在学习中,与你们共享

PC-lint 的代码实例

下面这些例子说明FlexeLint/PC-lint的一些功能。通过修改这些代码样本,可以分析它们的原因和处理结果。 “Off-By-One”错误实例(C源码) 下面的例子说明了FlexeLint/PC-lint为什么会出现“Off-By-One”错误。 /* Off-By-One Example */ #include <stdio...

weixin_34162695的博客 350

its4静态分析工具

一个静态扫描工具,主要针对API漏洞进行检测,他的分析技术比较简单,基于词法的

【C语言内存安全防线】:为什么90%的项目都忽略了这4项静态检测关键点?

掌握C语言内存泄漏的静态检测方法,有效提升项目稳定性与安全性。适用于嵌入式、系统开发等场景,涵盖工具选择、代码分析、资源追踪与自动化集成四大关键点。精准定位内存问题,降低崩溃风险,值得收藏并点击了解。

PixelGlow的博客 715

静态分析工具

FindBugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。有了静态分析工具,就可以在不实际运行程序的情况对软件进行分析。

DRAM 埋入式字线(Buried Wordline)技术深度解析:从二维平面到三维凹槽

埋入式字线(bWL)及其核心的埋入式沟道阵列晶体管(BCAT)架构,无疑是 DRAM 发展史上的一次关键性革命。它在约 40nm 技术节点被行业主流采纳,成功地帮助 DRAM 产业克服了传统平面晶体管的物理缩放极限。力挽狂澜的续命技术:bWL 通过引入三维沟道结构,从根本上解决了由短沟道效应和漏电流失控引发的数据保持危机,为经典的 1T1C(单晶体管 - 单电容)DRAM 单元架构延续了超过十年的生命力。协同优化的基石技术。

m0_37606066的博客 3325

函数的一些注意点

1,什么时候用重载? 当要实现相同功能而参数(个数、类型)不同时,用重载。在一个类里面允许用相同函数名定义函数,但其参数列表中的参数个数、类型要不同。

紫瞳妹纸的专栏 444

从零构建MAVLink通信:PX4飞控与QGC的协议握手全解析

本文详细解析了PX4飞控与QGC地面站通过MAVLink协议进行通信的全过程,重点介绍了航点传输协议的状态机设计、INT类型消息的优化优势以及异常处理与调试技巧。通过实战案例和性能优化建议,帮助开发者高效构建无人机通信系统,提升数据传输效率与稳定性。

weixin_29209805的博客 504

pc-lint使用

最近在做arm64的移植,在网上看到了lint系列静态代码分析工具,在windows下就是pc-lint了,便拿来用了一下,功能还是挺强大的。初次上手,过程中也遇到不少疑惑,写此文来记一下。 首先,安装好pc-lint后,可去官网上下载最新的补丁(包括补丁更新器lpatch和补丁配置如l9-a-b.lp),这些都是最新的功能补充,网址:http://www.gimpel.com/

duobaohongtu3的专栏 1412

SAP HR模块配置假期日历和缺勤类型

SAP的HR模块。业务顾问在实施时一般会配置未来10年的假期日历,到期后再进行配置。同时,增加请假类型(缺勤信息类型)。记录这一过程。

福来阁86号技师的妖孽日常 5523

葵花 Himawari 8/9号数据学习记录-01-数据初识

葵花卫星学习记录,第一章:卫星的来源与卫星数据的波段介绍

weixin_44111909的博客 533

pc_lint的用法转

PC-Lint是一款C/C++软件代码静态分析工具,不仅可以检查一般的语法错误,还可以检查潜在的错误,比如数组访问越界、内存泄漏、使用未初始化变量、使用空指针等。在单元测试前使用PC-Lint来检查代码,可以提前发现程序中的潜在的错误,提高代码 的质量。 本文主要从两个方面介绍PC-lint,第一部分是在与不同的工具安装集成,第二部分是PC-lint的使用方法。 1. 安装PC-lint

duobaohongtu3的专栏 876

vcenter server6.0上vmware inventory 、virtualvcenter等服务无法开启

描述:一天,vcenter访问不了,因此Windows远程到vcenter server上。相关服务未开启,开启virtualCenter server服务提示相关依赖服务未开启,于是开启依赖项服务Inventory服务报错。然后打算使用 C:\Program Files\VMware\vCenter Server\bin\servcivce-control来开启vmware服务 1....

Pespi_Co1a的博客 3067

pclint在VS2013中的使用

什么是pclint?pclint是一个加强版C++编译器,是一种执行静态编译检查的工具,可以配合其它的C++编译器使用。step 1. 安装,注意我的系统是64 windows + visual studio 2013。因此应该安装pclint 9i版本。安装非常简单,安装完成后记得打补丁,参见附1.step 2. 配置。Step 3. 使用参考:https://blog.youkuaiyun.com/fin...

一心两用 2161

KEPServerEX 6 之 EX 6.11.718.0 发布说明

KEPServerEX 6.11.718.0 发布说明

-雲飛兄-博客 2880

如何利用gretna软件计算脑网络全局属性(聚类系数,小世界属性,最短路径),局部属性指标(度,度分布,节点效率),如何理解网络稀疏度

grena工具箱被设计用于fMRI数据的图论网络分析。它是一套MATLAB函数和基于MATLAB的接口,用于常规的fMRI预处理,用于计算和统计分析最常用的网络指标,如小世界参数、效率、度、间性、关联性、层级性、同步性和模块化。......

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 9173

CWE-125: Out-of-bounds Read(越界读取)

ID: 125 类型:基础 结构:简单 状态:草稿 描述 软件读取缓冲区之前或者之后的数据。 扩展描述 通常,这会允许攻击者从其它内存位置读取敏感信息或导致崩溃。假定存在用于停止读取操作(如字符串中的nul)的哨兵变量时,当代码读取可变数量的数据时候可能会发生崩溃。预期的哨兵可能不在越界内存边界之内,导致读取过多数据,引发“分段错误”...

plstudio1的博客 5305

RT-DETR改进策略【损失函数篇】| 2024 引进Focaler-IoU损失函数 加强边界框回归 (Focaler-DIoU、Focaler-GIoU、Focaler-CIoU等)

本文记录的是改进RT-DETR的损失函数,将其替换成。现有研究通过利用边界框之间的几何关系来提高回归性能,但忽略了困难样本和简单样本分布对边界框回归的影响。不同检测任务中困难样本和简单样本的分布不同,对于简单样本占主导的检测任务,关注简单样本的边界框回归有助于提高检测性能;对于困难样本比例较高的检测任务,需要关注困难样本的边界框回归。,提高检测器在不同检测任务中的性能。实现的。

Limiiiing的博客 1922

静态代码分析工具汇总

<br /> <br />静态代码扫描,借用一段网上的原文解释一下(这里叫静态检查):“静态测试包括代码检查、静态结构分析、代码质量度量等。它可以由人工进行,充分发挥人的逻辑思维优势,也可以借助软件工具自动进行。代码检查代码检查包括代码走查、桌面检查、代码审查等,主要检查代码和设计的一致性,代码对标准的遵循、可读性,代码的逻辑表达的正确性,代码结构的合理性等方面;可以发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分、违背程序编程风格的问题,包括变量检查、命名和类型审查、程

daqinzl的专栏 1378

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Web安全工具大集合

Test sites / testing grounds SPI Dynamics (live) – http://zero.webappsecurity.com/ Cenzic (live) – http://crackme.cenzic.com/ Watchfire (live) – http://demo.testfire.net/ Acunetix (live) – http:

guxiaoguo的博客 4909

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

上一篇: AC3简介及压制攻略 zz
下一篇: 智能指针
发现心流
博客等级 码龄20年 52粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值