函数strcpy总是很危险吗?

问题描述

| strcpy,gets等函数是否总是很危险?如果我编写这样的代码怎么办:
int main(void)
{

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


}
这样,该函数不接受参数(参数...),并且str变量将始终具有相同的长度...根据编译器版本的不同,此处长度为16或稍长一些...但是yeah 100就足够了2011年3月:)。 黑客有没有办法利用上面的代码? 10倍!     

解决方法

绝对不。与Microsoft的非标准功能营销活动相反,正确使用properly1是安全的。 以上是多余的,但大多数情况下都是安全的。唯一的潜在问题是您没有检查
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函数来执行任意程序。溢出还有其他可能的后果。 但是,ѭ5确实本质上是不安全的,它将从下一版本的C(C1X)中删除。根本没有办法确保输入不会溢出(导致上面给出的相同结果)。有人认为与已知的输入文件一起使用时它是安全的,但实际上没有理由使用它。 POSIX的
getline
是更好的选择。 另外,
str1
的长度不会因编译器而异。它应始终为17,包括终止的NUL。     ,是的,这很危险。经过5年的维护,您的代码将如下所示:
int main(void)
{

char *str1 = \"abcdefghijklmnop\";

{enough lines have been inserted here so as to not have str1 and str2 nice and close to each other on the screen}

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


}
到那时,有人会去并将str1更改为 str1 = \“这是一个非常长的字符串,现在它将超载任何用于复制它的缓冲区,除非采取了预防措施以检查该字符串的限制。并且有很少的人记得在五年内解决这个问题旧的BUGY程序\“ 忘了看在哪里使用str1,然后随机错误将开始发生...     ,您正在将完全不同的内容塞入一类。 ѭ5的功能确实总是很危险的。无论您愿意采取什么步骤以及愿意采取何种防御措施,都无法对ѭ5进行安全呼叫。 如果您愿意采取[简单]必要的步骤来确保对
strcpy
的调用是安全的,则函数
strcpy
是绝对安全的。 那已经将ѭ5和ѭ1划分为截然不同的类别,它们在安全性方面没有共同之处。 针对“ 1”安全方面的流行批评完全基于轶事社会观察,而不是正式事实,例如\“程序员懒惰且无能,所以不要让他们使用
strcpy
\”。当然,在C编程的上下文中,这完全是胡说八道。遵循此逻辑,出于完全相同的原因,我们还应将除法运算符声明为完全不安全。 实际上,ѭ1毫无问题。另一方面,正如我上面所说,“ 5”是一个完全不同的故事。     ,只要知道目标缓冲区足够大以容纳源字符串的字符,1并不危险。否则,“ 1”将快乐地复制超过目标缓冲区可容纳的字符数,这可能会导致若干不幸的后果(堆栈/其他变量被覆盖,这可能导致崩溃,堆栈粉碎攻击等)。 但是:如果输入中没有检查通用的
char *
,确保唯一的方法就是将
strlen
应用于这样的字符串,并检查它是否对于缓冲区太大。但是,现在您必须遍历整个源字符串两次,一次用于检查其长度,一次用于执行复制。 这不是次优的,因为如果ѭ1稍微先进一点,它可以接收缓冲区的大小作为参数,并且如果源字符串太长则停止复制;在一个理想的世界中,这就是
strncpy
的执行方式(遵循其他
strn***
功能的模式)。但是,这不是一个完美的世界,
strncpy
并非旨在做到这一点。取而代之的是,非标准(但很流行)的替代方法是
strlcpy
,它会截断而不是超出目标缓冲区的边界。 几个CRT实现不提供此功能(特别是glibc),但是您仍然可以获取一种BSD实现并将其放入您的应用程序中。一个标准的(但较慢的)替代方法可以是使用
snprintf
\"%s\"
作为格式字符串。 就是说,既然您正在使用C ++进行编程(编辑,我现在看到C ++标记已被删除),为什么不避免所有的C字符串废话(显然,可以的话)并选择with30ѭ ?所有这些潜在的安全问题都消失了,字符串操作变得更加容易。     ,malloc可能失败的唯一方法是发生内存不足错误,这本身就是一场灾难。您无法可靠地从中恢复,因为几乎任何事情都可能再次触发它,并且操作系统可能仍然会终止您的进程。     ,您的代码不安全。
malloc
的返回值未经检查,如果失败并返回0,
strcpy
将给出未定义的行为。 除此之外,除了示例基本不执行任何操作外,我没有发现其他问题。     ,正如您所指出的,在受限制的情况下,strcpy并不危险。通常,采用字符串参数并将其复制到本地缓冲区中,在这种情况下,情况可能会变得很危险并导致缓冲区溢出。只需记住在调用strcpy之前检查您的副本长度,然后将null终止字符串即可。     ,除了可能会取消引用UB(可能不会带来安全威胁)而取消引用NULL(因为您不检查malloc的结果)之外,也没有潜在的安全问题。     ,
gets()
总是不安全的;其他功能可以安全使用。 即使完全控制了输入,33ѭ也不安全-某天,该程序可能会由其他人运行。 使用
gets()
的唯一安全方法是将其用于单个运行项:创建源;编译跑;删除二进制文件和源代码;解释结果。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...