Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
strcpy函数总是危险的吗?_C_Security - Fatal编程技术网

strcpy函数总是危险的吗?

strcpy函数总是危险的吗?,c,security,C,Security,strcpy、get等函数是否总是危险的?如果我写这样的代码会怎么样: int main(void) { char *str1 = "abcdefghijklmnop"; char *str2 = malloc(100); strcpy(str2, str1); } int main(void) { char *str1 = "abcdefghijklmnop"; {enough lines have been inserted here so as to not have str

strcpy、get等函数是否总是危险的?如果我写这样的代码会怎么样:

int main(void)
{

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


}
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);


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

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


除此之外,我认为没有问题,除了这个例子基本上没有任何作用。

绝对没有。与微软的非标准功能不同,
strcpy
在正确使用时是安全的

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

不适当和危险的使用是:

char array[100];
// ... Read line into uncheckedInput
// Extract substring without checking length
strcpy(array, uncheckedInput + 10);
这是不安全的,因为strcpy可能溢出,导致未定义的行为。实际上,这可能会覆盖其他局部变量(本身就是一个重大的安全漏洞)。其中一个可能是回信地址。通过攻击,攻击者可以使用C函数(如
system
)执行任意程序。溢流还有其他可能的后果

但是,它确实本质上是不安全的,并且将从下一版本的C(C1X)中删除。根本没有办法确保输入不会溢出(造成上述相同的后果)。有些人会争辩说,当与已知的输入文件一起使用时,它是安全的,但实际上没有理由使用它。POSIX是一个更好的选择


而且,
str1
的长度不会因编译器而异。它应该始终为17,包括终止NUL。

正如您所指出的,在受约束的情况下,strcpy并不危险。更典型的做法是接收一个字符串参数并将其复制到本地缓冲区,在这种情况下,事情可能变得危险并导致缓冲区溢出。只需记住在调用strcpy之前检查副本长度,null在调用后终止字符串。

除了可能取消对null的引用(因为您没有检查malloc的结果),null是UB,可能不会造成安全威胁,这不存在潜在的安全问题。

您将完全不同的内容强行塞入一个类别中

函数
获取
确实总是危险的。无论您愿意采取什么步骤,以及您愿意采取的防御措施如何,都无法安全地调用
get

如果您愿意采取[简单]必要的步骤来确保对
strcpy
的调用是安全的,那么函数
strcpy
是完全安全的

这已经将
获取
strcpy
分为截然不同的类别,在安全方面没有任何共同之处

针对strcpy安全方面的流行批评完全基于轶事式的社会观察,而不是形式上的事实,例如,“程序员懒惰无能,所以不要让他们使用strcpy”。在C编程的环境中,这当然是胡说八道。按照这个逻辑,我们还应该声明除法运算符完全不安全,原因完全相同

实际上,
strcpy
没有任何问题<另一方面,代码>获取,是一个完全不同的故事,正如我上面所说的

get()
总是不安全的
;其他功能可以安全使用。
gets()
即使在您完全控制输入时也是不安全的——有朝一日,程序可能会由其他人运行


使用
get()
的唯一安全方法是将其用于一次运行:创建源代码;编撰;跑删除二进制文件和源文件;解释结果。

strcpy
据您所知,目标缓冲区足够大,可以容纳源字符串的字符,因此并不危险;否则,
strcpy
会很高兴地复制比目标缓冲区所能容纳的字符更多的字符,这可能会导致一些不幸的后果(堆栈/其他变量覆盖,这可能导致崩溃、堆栈崩溃攻击等)

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

这是次优的,因为如果strcpy稍微高级一点,它可以接收缓冲区大小作为参数,如果源字符串太长,则停止复制;在一个完美的世界中,
strncpy
就是这样执行的(遵循其他
strn***
函数的模式)。然而,这并不是一个完美的世界,
strncpy
并不是为实现这一点而设计的。取而代之的是,非标准(但很流行)的替代方法是截断,而不是超出目标缓冲区的界限

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

这是因为,你在C++中编程(<强>编辑< /强>我现在看到C++标签已经被删除了),为什么你不只是避开所有的C字符串废话(显然是可以的),然后跟着<代码> STD::String >?所有的