The Kollected Kode Vicious

Kode Vicious - @kode_vicious

  Download PDF version of this article PDF

医生坐诊

KV 重返岗位,准备治疗另一种编码疾病:糟糕的 API。这是影响甚至感染我们所有人的最普遍的病理之一。但是,无论我们编写 API 还是仅仅使用 API(或两者兼而有之),我们都应该继续阅读并听取这位恶毒者的建议。与往常一样,我们欢迎并感谢您持续提出的与代码相关的问题:[email protected]

尊敬的 Kode Vicious,
我阅读您的长篇大论已经几个月了,希望您能读一下我的。实际上,这只是一个非常简单的抱怨:我只是厌倦了听到关于缓冲区溢出的事情,并且不明白为什么任何头脑正常的人还在使用 strcpy()。为什么这种不安全的例程会继续存在?为什么不直接从库中删除它,并迫使人们迁移他们的代码?我 Wonder 的另一件事是,这样的 API 最初是如何产生的?
为了更好的 API,

尊敬的 YBAPI,
是的,确实如此,有些 API 看起来就是很迟钝,或者写出来就是为了让你绊倒。通常这不是因为编码者的恶意。正如我的祖母常说的那样,“永远不要将恶意归因于可以用愚蠢来充分解释的事情。” 哦,等等,不,我的祖母说的是,“如果你不能对别人说些好话,那就什么也别说。” 我一生中对这两条建议都只是稍加注意,但我的祖母是一位智者。事实是,你甚至不能在大多数时候责怪愚蠢;你最常必须责怪的是人们无法成为全知全能。

您知道,在很久以前,计算机没有联网,并且是由一小群敬业的专业人员使用一套精心构建的工具和库来编程的。这些专业人员非常了解他们的工具,并且并没有真正考虑过人们攻击他们的计算机程序,因为他们中的许多人在研究实验室工作,并且他们的大多数程序都不处理金钱。当然,这些人中的一些人考虑过安全性,但不是在数亿人可以访问计算机和互联网之后必须考虑的那种方式。在我们将所有东西连接到互联网之前,生活是美好的——程序员们整天欢笑玩耍,同时梦想着更大的磁盘驱动器和动态 RAM。至少,这是我听到的故事。因此,在编写 strcpy() 时,大多数程序员只考虑自己的错误,而不是有人试图通过网络和缓冲区溢出攻击来接管他们的计算机。

正如您所说,缓冲区溢出攻击已经被讨论烂了,也许我们应该考虑是什么让 strcpy() 成为如此有问题的 API,而不是纠结于缓冲区溢出。毕竟,人们仍在构建不安全且考虑不周的 API,也许我们应该推动他们,即使不是推入大海,也要朝着正确的方向前进。

部分问题来自字符串本身的定义。字符串只是指向以 NULL 结尾的字节集的指针。让我们考虑一下在将这块内存传递给其他 API 之前我们需要了解的一些事情。一个重要的问题是,“它有多大?” 是的,有点不雅,但在这种情况下,大小实际上很重要。如果您是字符串的接收方,并且您不知道它有多长,那么真的没有办法安全地处理它。您必须扫描整个字符串,直到找到终止 NULL,即使您找到了,它也可能是错误的。

字符串的第二个问题实际上与程序中内存的分配和控制方式有关。指向内存的指针只告诉您内存的起始位置,而不是您真正应该使用多少内存。由于以字节组(操作系统称为页面)为单位管理内存更有效,因此如果您的程序意外地写入超出您认为分配给它的空间,它将不会收到明确的信号。在不使用特殊工具和库的情况下,程序无法知道何时走得太远。当然,特殊的工具和库会减慢您的程序速度,因此您不能一直使用它们,即使您使用了,您也必须设计足够的测试来查看您的代码中是否有任何漏洞。

现在我们来谈谈 strcpy(),对于那些可能从未见过此例程的人来说,它看起来像这样

char *strcpy(char *destination, char *source)

它应该将字节从源复制到目标,包括终止 NULL 字节,以便当例程返回时,您有一个指向目标的源副本。这个 API 有几个问题

因此,让我们稍微抽象一下这些不良品质,并尝试更清楚地说明它们。首先,API 无法验证其参数。不验证参数会导致错误。错误是不好的。其次,没有明确的方法来传达错误状态。错误会发生;应该检查并返回它们。不检查错误的程序员是坏人,并且将永远遭受永恒的调试会话,阿门。第三,参数和返回值令人困惑。当您不需要时,为什么要返回您已经传递给例程的东西?最后,文档没有警告我们任何可能的边界条件以及如果它们发生我们可能期望发生什么。

当然,我可以继续举例说明那些可怕的 API,它们让 strcpy() 看起来像是和 Rose 阿姨在公园里散步一样轻松,但我被限制在 1,200 字左右。那么,好的 API 看起来像什么,或者它们应该是什么样的?嗯,在 KV 非常有偏见的观点中,一个好的 API 具有以下几个属性

KODE VICIOUS,凡人称之为 George V. Neville-Neil,以网络和操作系统代码为乐,并从中获利。他还教授与编程相关的各种主题的课程。他的兴趣领域是代码探险、操作系统和重写您的糟糕代码(好吧,也许不是最后一个)。他获得了马萨诸塞州波士顿东北大学计算机科学学士学位,并且是 、Usenix 协会和 IEEE 的成员。他是一位狂热的自行车爱好者和旅行家,自 1990 年以来一直将旧金山作为自己的家。

acmqueue

最初发表于 Queue vol. 3, no. 9—
数字图书馆中评论本文





更多相关文章

Catherine Hayes, David Malone - Questioning the Criteria for Evaluating Non-cryptographic Hash Functions
虽然加密和非加密哈希函数无处不在,但在它们的设计方式上似乎存在差距。出于各种安全要求,存在许多针对加密哈希的标准,但在非加密方面,存在一定程度的民间传说,尽管哈希函数历史悠久,但尚未得到充分探索。虽然针对现实世界数据集的均匀分布很有意义,但在面对具有特定模式的数据集时,这可能是一个挑战。


Nicole Forsgren, Eirini Kalliamvakou, Abi Noda, Michaela Greiler, Brian Houck, Margaret-Anne Storey - DevEx in Action
DevEx(开发者体验)在许多软件组织中越来越受到关注,因为领导者寻求在财政紧缩和人工智能等变革性技术的背景下优化软件交付。直观地,技术领导者普遍认为良好的开发者体验可以实现更有效的软件交付和开发者幸福感。然而,在许多组织中,旨在改善 DevEx 的拟议举措和投资难以获得支持,因为业务利益相关者质疑改进的价值主张。


João Varajão, António Trigo, Miguel Almeida - Low-code Development Productivity
本文旨在通过展示使用基于代码、低代码和极端低代码技术进行的实验室实验结果,以研究生产力差异,从而提供关于该主题的新见解。低代码技术已清楚地显示出更高的生产力水平,为低代码在短期/中期内主导软件开发主流提供了强有力的论据。本文报告了程序和协议、结果、局限性和未来研究的机会。


Ivar Jacobson, Alistair Cockburn - Use Cases are Essential
虽然软件行业是一个快节奏且令人兴奋的世界,在这个世界中,新的工具、技术和技巧不断被开发出来以服务于商业和社会,但它也很健忘。在追求快速前进的匆忙中,它容易受到时尚潮流的影响,并且可能会忘记或忽略针对其面临的一些永恒问题的成熟解决方案。用例最初于 1986 年引入,后来普及,是这些成熟解决方案之一。





© 保留所有权利。

© . All rights reserved.