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

时间:2009-03-10 18:31:04

标签: 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, 
potential security vulnerability if user controlled"

我将testStrings更改为const,但是没有做任何事情:

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

关于这个错误究竟是什么意思的任何想法?

2 个答案:

答案 0 :(得分:11)

你的代码很好。

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

例如,printf(userName);

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

由于您的字符串不受用户控制,因此可以安全地忽略此消息。典型的解决方法是用printf("%s", userName);替换我给出的printf示例,这对你的情况似乎没有帮助,因为const字符串似乎包含格式字符串。

Wikipedia在格式字符串漏洞方面有更多内容:http://en.wikipedia.org/wiki/Format_string_vulnerabilities

答案 1 :(得分:2)

想法是testStrings[testID]的值可以某种方式改变以包括额外的格式说明符。

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

它被称为format string attack