SV.BANNED.REQUIRED.COPY
已禁用的复制函数调用
某些 C/C++ 函数被视为是不安全的,因此“已禁用”这些函数。这些函数是:
- 内存分配函数,如 alloca
- 字符串串联函数,如 strcat 和 strncat
- 字符串复制函数,如 strcpy 和 strncpy
- 获取函数,如 gets 和 _getts
- isbad 函数,如 IsBadWritePtr
- 数值转换函数,如 _iota 和 _itow
- OEM 转换函数,如 CharToOem
- 路径函数,如 _splitpath 和 makepath
- 扫描函数,如 scanf
- 字符串打印函数,如 sprintf 和 snprintf
- 字符串令牌化函数,如 strtok
SV.BANNED 系列检查器会查找在代码中使用任何已禁用函数的情况。
SV.BANNED.REQUIRED.COPY 检查器标记出使用不安全的复制函数的情况。
漏洞与风险
这些被禁止的函数大都是因为可能导致缓冲区溢出而被禁用。
已禁用的函数的列表既包括 strcpy 和 strcat 之类的函数,也包括很多相对应的“n”函数,例如 strncpy 和 strncat。虽然经常推荐将“n”函数用于替换其匹配的非“n”函数,但是现在它们被视为难以对溢出的缓冲区进行非空终止,而且缺少返回溢出错误的能力。
缓解与预防
禁止使用这些已禁用的 API 可以很好地消除大量代码漏洞。应该使用更安全的版本替换已禁用的函数,或者应该重新设计代码以完全避免使用已禁用的函数。
要避免安全性问题,建议在编译器具有同等安全的功能时,为每一种函数类别使用安全性能相同的函数。在某些情况下,没有替换函数,因此建议重新构建代码的体系结构。
对于 Microsoft 编译器用户,可以考虑使用 StrSafe 库中的函数替换复制函数:StringCchCopy、StringCchCopyN、StringCchCopyEx、StringCchCopyNEx、StringCbCopy、StringCbCopyN、StringCbCopyEx 或 StringCbCopyNEx,这取决于使用字符计数还是字节计数。
对于 gcc 用户,则可以考虑使用 libssp 库中的函数,例如 __strcpy_chk.c 和 __strncpy_chk.c。
除此之外还可以使用安全的 CRT 函数,例如 strcpy_s 或 strncpy_s。
除了使用安全的替换函数之外,检查目标缓冲区的大小是否合适也很重要。可以考虑使用 std::string 模板类,而不是直接操作缓冲区。
如果您正在使用已在 C 的扩展库中弃用的 memcpy、RtlCopyMemory、CopyMemory 或 wmemcpy 函数(并且您已经意识到不使用扩展库存在安全风险),您可以通过修改此 KAST 检查器的主体来筛选缺陷,具体内容如下:
<pattern>
// CallExpr/Func::IdExpr
[ getName() = 'memcpy' ]
[ $0 := 'memcpy' ] [ $1 := 'memcpy_s' ]
[isMacroDefined('__STDC_LIB_EXT1__')]
[isMacroDefined('__STDC_WANT_LIB_EXT1__')]
</pattern>
<pattern>
// CallExpr/Func::IdExpr
[ getName() = 'RtlCopyMemory' ]
[ $0 := 'RtlCopyMemory' ] [ $1 := 'memcpy_s' ]
[isMacroDefined('__STDC_LIB_EXT1__')]
[isMacroDefined('__STDC_WANT_LIB_EXT1__')]
</pattern>
<pattern>
// CallExpr/Func::IdExpr
[ getName() = 'CopyMemory' ]
[ $0 := 'CopyMemory' ] [ $1 := 'memcpy_s' ]
[isMacroDefined('__STDC_LIB_EXT1__')]
[isMacroDefined('__STDC_WANT_LIB_EXT1__')]
</pattern>
<pattern>
// CallExpr/Func::IdExpr
[ getName() = 'wmemcpy' ]
[ $0 := 'wmemcpy' ] [ $1 := 'wmemcpy_s' ]
[isMacroDefined('__STDC_LIB_EXT1__')]
[isMacroDefined('__STDC_WANT_LIB_EXT1__')]
</pattern>
相关检查器
- SV.BANNED.RECOMMENDED.ALLOCA
- SV.BANNED.RECOMMENDED.NUMERIC
- SV.BANNED.RECOMMENDED.OEM
- SV.BANNED.RECOMMENDED.PATH
- SV.BANNED.RECOMMENDED.SCANF
- SV.BANNED.RECOMMENDED.SPRINTF
- SV.BANNED.RECOMMENDED.STRLEN
- SV.BANNED.RECOMMENDED.TOKEN
- SV.BANNED.RECOMMENDED.WINDOW
- SV.BANNED.REQUIRED.CONCAT
- SV.BANNED.REQUIRED.COPY
- SV.BANNED.REQUIRED.GETS
- SV.BANNED.REQUIRED.ISBAD
- SV.BANNED.REQUIRED.SPRINTF
- SV.UNBOUND_STRING_INPUT.FUNC