禁用不安全的字符串函数
10.6.11 ID_unsafeStringFunction
由于历史原因,C 标准库中的某些字符串函数不执行边界检查,易造成运行时错误和安全漏洞。
这类函数包括:
gets、strcpy、strcat、wcscpy、wcscat、
sprintf、vsprintf、swprintf、vswprintf、
scanf、sscanf、fscanf、vfscanf、vscanf、vsscanf
与这类函数相似的函数同样受本规则约束,如下列 Windows API:
StrCpy、StrCpyA、StrCpyW、StrCat、StrCatA、StrCatW、
lstrcpy、lstrcpyA、lstrcpyW、lstrcat、lstrcatA、lstrcatW
在 C 代码中应采用更安全的库函数,如用 fgets 代替 gets,snprintf 代替 sprintf。在 C++ 代码中应采用 STL 标准库提供的相关功能。
示例:
char buf[100];
gets(buf); // Non-compliant
例中 gets 函数无法检查缓冲区的大小,一旦输入超过了 buf 数组的边界,程序的数据或流程就会遭到破坏,这种情况会被攻击者利用,可参见 ID_bufferOverflow 的进一步说明。如果代码中存在 gets 等函数,可以直接判定程序是有漏洞的。
应改为:
char buf[100];
fgets(buf, sizeof(buf), stdin); // Compliant
fgets 与 gets 不同,当输入超过缓冲区大小时会被截断,保证缓冲区之外的数据不会被破坏。
又如:
char buf[100];
scanf("%s", buf); // Non-compliant
例中 scanf 函数与 gets 函数有相同的问题,可改为:
char buf[100];
scanf("%99s", buf); // Let it go, but ‘fgets’ is better
scanf、sprintf、strcpy 等函数无视缓冲区大小,需要在外部另行实现防止缓冲区溢出的代码,完全依赖于开发者的小心谨慎。历史表明,对人的单方面依赖是不可靠的,改用更安全的方法才是明智的选择。
相关
依据
ISO/IEC 9899:2011 Annex K
ISO/IEC 9899:2011 K.3.7
ISO/IEC 9899:2011 K.3.9