为什么“strcat”被认为是“不安全”的?

8
可能是重复问题:
为什么MSVC++认为“std::strcat”是“不安全”的?(C++) 这是我的代码:
char sentence[ 100 ] = "";
char *article[ 5 ] = { "the", "a", "one", "some", "any" };

lexeme = rand() % 4; // random lexeme
strcat( sentence, article[ lexeme ] );
strcat( sentence, " " );

在MSVC++中进行调试时,它会给我这些警告消息:
Warning 1   warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead.
Warning 2   warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. 

我该如何修复它?
3个回答

19
这是因为没有任何限制阻止您向缓冲区中strcat超过100个字节,结果未定义,包括堆栈损坏,程序退出,甚至如果第100个字节之后的数据适当构造,则可能会使某人拥有您的计算机。这是一种常见的安全漏洞类别,称为缓冲区溢出
为避免此问题,请使用std::stringoperator+,毕竟这是C++。CRT不再限制您。

3
在C++中,像这样的问题,建议使用std::string,这个答案总是正确的。 - Jonathan Grynspan
我认为strncat是一个完全合理的方法来做这件事,特别是在他在这个例子中已经使用了C字符串。 - Max E.
2
@Max,是的,那会是一个不错的替代回答。但我个人更喜欢在C++代码中避免使用CRT,就像上面的问题所述的原因一样。 - Steve Townsend

2

因为这是合法的

char sentence[ 1] = "";
char *article[ 5 ] = { "the", "a", "one", "some", "any" };

lexeme = rand() % 4; // random lexeme
strcat( sentence, article[ lexeme ] ); // BUFFER OVERRUN
strcat( sentence, " " );

这将允许您修改句子数组后的堆栈上的任何内容。您可能会无意中覆盖其他堆栈变量,而语言或操作系统不会阻止您引发错误。此外,存在一个巨大的安全问题--堆栈上的内容包括指针返回到函数。聪明的攻击者可以在您的数据中插入指向其代码的指针,从而允许他们执行任何想要的操作。

我建议尽可能避免使用C风格的字符串。只有在必须使用C字符串时,请使用std::string和Microsoft推荐的C std lib安全增强功能


至于如何修复它,使用strncat并传入一个计数,以确保“sentence”字符串不会溢出。 - fredw

0

您可以使用strcat_s来解决潜在的缓冲区溢出问题。


3
strncat 更加标准。 strcat_s 是一个被提议的标准,但是它并不被普遍支持。 - Left For Archive

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接