C++ snprintf格式字符串安全漏洞问题

C++ snprintf格式字符串安全漏洞问题,c++,c,security,printf,C++,C,Security,Printf,这行代码有一个Coverity错误: snprintf( tempStr, size, testStrings[testID], A2DtoV(testResults[testID].value), A2DtoV(testResults[testID].min),A2DtoV(testResults[testID].max)); 错误显示: non_const_printf_format_string: "format string is not a string literal, pote

这行代码有一个Coverity错误:

snprintf( tempStr, size, testStrings[testID], A2DtoV(testResults[testID].value),
A2DtoV(testResults[testID].min),A2DtoV(testResults[testID].max));
错误显示:

non_const_printf_format_string: "format string is not a string literal, 
potential security vulnerability if user controlled"
我将teststring更改为const,但这没有起任何作用:

static const char *testStrings[] = {"1", ... etc};

关于这个错误的真正含义有什么想法吗?

想法是可以通过某种方式更改
testStrings[testID]
的值,以包含额外的格式说明符

因为
snprintf()
无法检查参数的数量是否与格式说明符的数量匹配,所以它将从堆栈中获取下一个地址作为下一个格式说明符的值,然后可能会发生奇怪的事情

它被称为。

您的代码很好

问题是,如果将用户控制的字符串作为printf格式字符串传递,则可能会出现安全漏洞

例如,
printf(用户名)

当用户名由用户提供时,用户可以传递“%s”,并让您的函数开始访问堆栈上随机地址的数据,这可能会导致崩溃。printf将尝试从堆栈中弹出其他参数,从而导致堆栈损坏。像这样的拒绝服务攻击可能是最好的情况,可以通过让printf转储堆栈上的值来泄露信息,甚至还有方法让printf样式的函数修改堆栈上的返回地址

由于字符串不是用户控制的,因此可以安全地忽略此消息。典型的修复方法是将我给出的printf示例替换为
printf(“%s”,用户名),这在您的情况下似乎没有帮助,因为常量字符串似乎包含格式字符串

Wikipedia在此处提供了更多关于格式字符串漏洞的信息: