7

在我看来,人们,尤其是在学习 C 编程语言时,仍在使用该gets函数从标准输入读取数据。尽管它现在已从C11 标准中删除1 ,并且cppreference上的免责声明如下:

gets() 函数不执行边界检查,因此该函数极易受到缓冲区溢出攻击。它不能安全使用(除非程序在限制标准输入上出现的内容的环境中运行)。出于这个原因,该功能在 C99 标准的第三次勘误中已被弃用,并在 C11 标准中完全删除。fgets() 和 gets_s() 是推荐的替代品。

永远不要使用gets()。

然而,这似乎不是一个新问题,而是出现了更现代的编程哲学。它总是会被破坏并导致程序崩溃,我看不出“限制标准输入上可能出现的内容的环境”可能意味着什么。

那么,它在过去有用吗?或者它被添加到 C 的先前标准和预标准版本的原因是什么?


(1) ...或至少更改为具有指示要读取的最大长度的附加参数。然而,我问的是旧签名,只收到一个指针。

4

4 回答 4

5

当您查看 C 早期的残余时,您必须考虑历史背景。

C 语言是在 70 年代设计的。那时,网络系统是一个例外,而不是常态,安全性不像今天那么重要。系统很少在不受信任的第 3 方数据上运行。即使他们这样做,也没有被认为有那么大的风险。信息技术仍处于起步阶段。没有人意识到计算机系统有多么敏感。

另一方面,CPU 时间非常宝贵。程序需要尽可能高效。

这就是 C 标准库中的大多数函数不进行边界检查的原因。性能比安全具有更高的优先级。当您需要安全性时,您应该先验证您的数据,然后再将其提供给您的程序。

但是在 21 世纪的今天,所有计算机系统都相互连接,所有计算机系统都在不断地处理来自不受信任甚至未知来源的信息,而黑客攻击是一个十亿美元的产业,安全已成为每个计算机程序的首要任务。

于 2013-03-05T14:29:48.163 回答
5

是的,它很有用,同时“极易受到缓冲区溢出攻击”。

它总是会被破坏并导致程序崩溃,我看不出“限制标准输入上可能出现的内容的环境”可能意味着什么。

不,gets不会导致程序崩溃。这主要是一个安全问题。您可以在此处阅读有关缓冲区溢出攻击的信息

另请参阅此问题:为什么获取函数如此危险以至于不应该使用它?

于 2013-03-05T14:11:10.010 回答
2

发明时gets,很少有程序需要能够接受来自不可靠来源的大量输入。gets对于来自合作用户的有限输入是足够的。该用户通过在每一行上不输入太多内容来提供“限制显示内容的环境”。您几乎可以指望坐在终端上的用户不会在“y/n”提示符中输入数百字节的数据。如果他们将一个大文件通过管道传输到您的程序中,而您的程序不是为此而设计的,那么他们会得到不好的结果。

必须处理任意输入的程序没有使用gets.

现在,恶意输入在实践中很常见,并且更具破坏性,因为存在允许攻击者轻松利用缓冲区溢出的工具和技术。训练有素的用户在提示下打字是一个小众案例。此外,考虑恶意输入被广泛用作一种很好的技术,以确保软件能够抵御并非旨在作为攻击的意外输入。几乎所有程序都应该处理任意输入。所以gets显然是不够的。

于 2013-03-05T14:31:54.530 回答
0

Gets 对于原型设计仍然有用。它可以快速编写并为程序员产生预期的结果,他们的目标是解决手头的问题,而不是试图让他或她的程序崩溃。

于 2013-03-05T14:21:25.623 回答