strcpy函数总是危险的吗?

strcpy,gets等function总是危险的吗? 如果我写这样的代码怎么办:

int main(void) { char *str1 = "abcdefghijklmnop"; char *str2 = malloc(100); strcpy(str2, str1); } 

这样,函数不接受参数(参数…),并且str变量将始终具有相同的长度…这里是16或稍微多一些,具体取决于编译器版本……但是100可以满足3月,2011年:)。 有没有办法让黑客利用上面的代码? 10倍!

绝对不。 与微软针对其非标准function的营销活动相反, strcpy 在正确使用时是安全的。

以上是多余的,但大多数是安全的。 唯一可能的问题是你没有检查malloc返回值,所以你可能正在取消引用null(如kotlinski所指出的)。 实际上,这可能会立即导致SIGSEGV和程序终止。

不正当和危险的用途是:

 char array[100]; // ... Read line into uncheckedInput // Extract substring without checking length strcpy(array, uncheckedInput + 10); 

这是不安全的,因为strcpy可能会溢出,导致未定义的行为。 在实践中,这可能会覆盖其他局部变量(本身就是一个主要的安全漏洞)。 其中一个可能是返回地址。 通过返回lib C攻击,攻击者可能能够使用像system这样的C函数来执行任意程序。 溢出还有其他可能的后果。

但是, gets确实本质上是不安全的,并将从下一版本的C(C1X)中删除。 根本没有办法确保输入不会溢出(导致上面给出的相同后果)。 有些人认为与已知输入文件一起使用时是安全的,但实际上没有理由使用它。 POSIX的getline是一个更好的选择。

此外, str1的长度不会因编译器而异。 它应该总是17,包括终止NUL。

是的,这很危险。 经过5年的维护,您的代码将如下所示:int main(void){

char * str1 =“abcdefghijklmnop”;

{这里插入了足够多的行,这样就不会让str1和str2很好并且在屏幕上彼此靠近}

char * str2 = malloc(100); strcpy(str2,str1);

}

在那一点上,有人会去改变str1

str1 =“这是一个非常长的线索,现在超过任何缓冲区被用来复制它,除非有预先检查弦线的限制。并且很少有人记得在5年前有一个问题的困难BUGGY计划“

并且忘记查看str1的使用位置,然后随机错误将开始发生……

你有力地把完全不同的东西塞进一个类别。

函数gets确实总是危险的。 无论你愿意采取什么步骤以及你愿意获得多少防守,都没有办法安全地接听。

如果您愿意采取[简单]必要步骤以确保您对strcpy strcpy是安全的,那么strcpy函数是非常安全的。

这种情况已经gets非常不同,在安全方面没有任何共同之处。

针对strcpy安全方面的流行批评完全基于轶事社会观察而不是正式事实,例如“程序员懒惰和无能,所以不要让他们使用strcpy ”。 在C编程的背景下,这当然是完全无稽之谈。 遵循这个逻辑,我们也应该完全相同的原因声明除法运算符完全不安全。

实际上, strcpy没有任何问题。 另一方面,如上所述,这是一个完全不同的故事。

strcpy并不危险,只要您知道目标缓冲区足够大以容纳源字符串的字符; 否则strcpy会愉快地复制比你的目标缓冲区可以容纳的更多字符,这可能导致一些不幸的后果(堆栈/其他变量覆盖,这可能导致崩溃,堆栈粉碎攻击和co。)。

但是:如果你在输入中有一个尚未检查的通用char * ,唯一的方法是将strlen应用于这样的字符串并检查它是否对你的缓冲区来说太大了; 但是,现在你必须遍历整个源字符串两次,一次用于检查其长度,一次用于执行复制。

这是次优的,因为如果strcpy稍微提高一点,它可以作为参数接收缓冲区的大小,如果源字符串太长则停止复制; 在一个完美的世界中,这就是strncpy表现(遵循其他strn***函数的模式)。 然而,这不是一个完美的世界, strncpy不是为此而设计的。 相反,非标准(但很受欢迎)的替代方案是strlcpy ,它不会超出目标缓冲区的范围,而是截断。

几个CRT实现不提供此function(特别是glibc),但您仍然可以获得其中一个BSD实现并将其放入您的应用程序中。 标准(但较慢)的替代方案可以是使用带有"%s" snprintf作为格式字符串。

也就是说,既然你是用C ++编程的( 编辑我现在看到C ++标签已被删除),你为什么不避免所有的C字符串废话(显然你可以),并使用std::string ? 所有这些潜在的安全问题都消失了,字符串操作变得更加容易。

malloc可能失败的唯一方法是发生内存不足错误,这本身就是一种灾难。 您无法可靠地从中恢复,因为几乎任何东西都可能再次触发它,并且操作系统可能会终止您的进程。

你的代码不安全。 malloc的返回值未选中,如果失败并返回0,则strcpy将给出未定义的行为。

除此之外,我认为没有问题,除了示例基本上没有做任何事情。

正如你所指出的,在有限的情况下,strcpy并不危险。 更常见的是接受一个字符串参数并将其复制到本地缓冲区,这就是事情可能变得危险并导致缓冲区溢出的情况。 只需记住在调用strcpy之前检查你的拷贝长度,然后null终止字符串。

除了可能解除引用NULL(因为你没有检查来自malloc的结果),这是UB并且可能不是安全威胁,因此没有潜在的安全问题。

gets()总是不安全的 ; 其他function可以安全使用。
即使你完全控制输入, gets()也是不安全的 – 有一天,程序可能会由其他人运行。

使用gets()的唯一安全方法是将它用于单个运行的东西:创建源; 编译; 跑; 删除二进制文件和源文件; 解释结果。