我依靠PHP CLI来处理各种个人和(希望很快)专业/任务关键型“业务逻辑”。 (这可能是任何其他语言,并且完全相同的问题仍然存在;我只是在说明自己是为了上下文而使用的语言。)
在尽可能最大的程度上,我总是编写所有代码我一个人只有在绝对必要时,我才勉强使用第三方库。对于某些事情,这只是必要的。例如,电子邮件解析和其他类似的非常复杂的东西。
为了管理此类第三方库,我使用PHP Composer。这是PHP的库管理器。它能够下载库及其依赖项,并使用类似于其他“包管理器”的命令来更新它们。从实际意义上讲,这比手动跟踪和手动下载ZIP文件并将其解压缩并处理各种问题要好得多。
但是,最基本的安全问题仍然存在:我不知道此“已安装”代码包含的内容,也不知道在其中添加/更改了什么每次更新。当我的Composer获取更新时,库的一位作者可能很容易受到损害,导致我的PHP CLI脚本突然将我的Bitcoin wallet.dat发送到某个远程服务器,在我的机器上安装了RAT /特洛伊木马,甚至更糟。实际上,这可能已经发生了,我再也不明智了。我根本不知道。从逻辑上讲,我没有任何想法。
我自己的代码库总共大约15,000行。我花了一年多的时间才认真地研究该代码库。这就是我编写的代码,我很了解...
我的“ Composer”目录树当前有超过120,000行代码。那是我需要的最少数量的关键PHP库。我使用的很少,但它们具有各种依赖性,与我自己的代码相比,它们总体上会非常膨胀/膨胀。
我怎么应该“审核”所有这一切?!这根本不会发生。尝试后不久,我就会“分区”。我什至不知道如何通过我自己的代码进行另一轮“审核”,更不用说这十倍于其他人的代码了。
当人们这么说时“审核第三方代码”是“必须”,这到底是什么意思?我也同意这是“必须的”,但是那是令人讨厌的现实。我将永远没有时间和精力来做到这一点。另外,我显然没有钱付钱给别人去做。
我花了无数小时试图了解Docker,看看是否有某种方式可以“封装”这些不受信任的第三方党库以某种方式,但这是一场失败的战斗。我发现完全不可能做到这一点,或者我对此有很多疑问。我什至不认为这是我想象中的方式。
#1 楼
您不能审查单独的代码行。您只会死于尝试这样做。在某些时候,您必须信任其他人。 1984年,许多Unix的共同发明者之一肯·汤普森(Ken Thompson)写了一篇关于信任限制的简短文章。在某个时候,您确实必须信任其他人,必须相信,编写文本编辑器的人不会自动隐藏一些PHP解释程序将执行的Trojan代码,这些代码将被植入某些窃取比特币的恶意软件中。
您必须进行成本效益分析,以优先考虑您要审查的内容。
在大多数情况下,您应该尽力去审查代码的作者,项目的内部安全实践以及代码是如何到达您的。审查代码实际上是昂贵且艰巨的,因此应将其保留给您认为对您的项目最重要的部分。
图书馆是一个受欢迎的图书馆,很多有知名公司的人都在使用该图书馆。还是背后的知名项目负责人?项目是否具有适当的项目管理流程?图书馆是否有安全问题的良好历史记录,它们是如何处理的?它是否具有测试以涵盖其需要处理的所有行为?它可以通过自己的测试吗?这样就降低了在没有任何人注意的情况下破坏库的风险。
请获取一些示例文件以进行更深入的审查。你看到有关那里的事吗?如果您拿走的几个文件有重大问题,则可以推断出代码库的其余部分也有类似的问题。如果它们看起来不错,则可以增强您对其余代码库的编写相似的信心。请注意,在非常大的代码库中,代码的不同区域将具有不同级别的代码质量。
包管理器存储库是否检查包签名?是否需要预先审核系统才能将软件包注册到资源库中,还是开放的注册资源库?您是否以源代码的形式或预编译的二进制形式接收该库?这些都会影响您对库的信任程度,风险因素以及进一步提高信任度的方法。
还必须考虑应用程序以及应用程序将在其上运行的执行环境。这是国家安全代码吗?这个代码处理是电子商务或银行处理信用卡号码的一部分吗?此代码是否以超级用户身份运行?该代码寿命/安全性至关重要吗?您是否具有补偿控件来隔离和运行具有不同特权(例如容器,VM,用户权限)的代码?这是周末项目的代码吗?如何回答这些问题应该使您可以定义预算,以便可以在审查代码上投入多少资金,从而确定如何对哪些库需要审查,在什么级别进行优先排序以及哪些库具有较低的信任度进行优先排序。
评论
@forest:它仍然和现在一样重要。谁进行正式验证,以及他们使用哪些工具进行验证?如果经过正式验证的编译器和用来验证编译器的证明助手也都被借壳了怎么办?一直都是乌龟。
– Lie Ryan
19/12/9在8:26
@forest:您怎么知道您使用的文本编辑器/反汇编器/十六进制转储工具也不是后门程序?
– Lie Ryan
19/12/9在8:31
将其存储在足以使用SPI读取器的介质上?当您担心逻辑分析仪的硬件被后门时,您正在进入编码机的科幻领域。
–森林
19/12/9在8:34
尽管@forest与后门SPI读取器不太一样,但是您的论点并没有改变答案的重点,因为在某些时候您必须信任其他人。实质上,您的意思是您应该信任其他人。在任何情况下,对于大多数人来说,使用SPI读取器来验证小型编译器的汇编,然后使用该编译器来编译完整的编译器,然后使用该编译器来编译完整的工具链,都是不太可能的实用方法。
–乔恩·本特利
19/12/9在15:27
@forest您怎么知道您的图形卡没有在您身上开采比特币?您怎么知道您的网卡没有记录所有数据包并将其发送到其他地方?信任一直延伸到硬件级别。即使您构建自己的网卡,您对构建这些基础组件的原始组件有什么真正了解?您是否要重新发现50年的技术进步?
– Cruncher
19/12/9在21:28
#2 楼
我的“ Composer”目录树当前有12万多行代码。那是我需要的最少数量的关键PHP库。
您的错误是试图像对待自己的代码一样审查第三方代码。您不能也不应该尝试这样做。
您没有按名称提及任何库,但是我将假定其中有相当一部分是因为您正在使用较大的框架之一,例如Laravel或Symfony。像其他主要图书馆一样,此类框架也有自己的安全团队;问题被快速修补,并且安装更新很简单(只要您使用的是受支持的版本)。
与其尝试自己审查所有代码,不如让自己放心并信任供应商为您做了-并将继续做-审查。毕竟,这就是为什么您使用第三方代码的原因之一。
实际上,您应该像对待第三方PHP库中一样对待第三方PHP库。 NET或Java之类的编译环境。在那些平台上,这些库以DLL文件或类似文件的形式出现,您可能永远也看不到源代码。您不能审核它们,也不会尝试。如果您对PHP库的态度与此不同,那么您需要问自己为什么。仅仅因为您可以阅读代码并不意味着您会从中获得任何好处。
当然,如果您的第三方库中包含不受支持或没有的较小的库,那么所有这些都将落空。安全策略。因此,这就是您要使用的所有库的问题:是否完全支持它们,并且它们具有您满意的安全策略。对于任何没有的库,您可能要考虑寻找这些库的替代方法。但这并不意味着您应该尝试自己审核它们,除非您实际上打算接管他们的支持。
但是,我将添加一件事:如果要对PHP代码进行安全审核,强烈建议使用RIPS扫描程序。它并不便宜,但是,如果您对安全性有严格的要求,那么它很容易成为您可以从PHP获得的最好的自动化安全性分析工具。绝对在您自己的代码上运行它;您可能会惊讶于它收到了多少个问题。如果您很偏执,当然也可以在第三方库上运行它。但是,这将花费您更多的钱,而我的上述观点仍然成立。您真的应该信任您的第三方供应商为自己做这种事情。
评论
+1,如果您不愿意信任主要的知名框架,那么您会遇到更大的问题,因为您也不应该信任自己的操作系统,软件,固件,硬件等。
–乔恩·本特利
19/12/9在15:31
@FrankHopkins不一定。如果您为那些仅“方便使用”的依赖项重新发明轮子,则会冒引入第三方库中不存在的安全漏洞的风险(该漏洞可能是由经验丰富的开发人员开发的,并且需要进行更多审查) )。
–乔恩·本特利
19年10月10日在15:03
@JonBentley这就是为什么我说最小化对您所需要的依赖的原因。如果您进行加密,则肯定需要这些加密库。但是您可能不需要大型框架-除了很多其他东西之外-它可以为您提供方便的数据库访问。也许有一个已经为您提供几乎一样方便的数据库工具的库,那么这可能是更好的选择。除非它是如此未知,否则您是唯一使用它的人。等等,它总是权衡另一个问题,但是大型框架“总是”存在一些被忽视的问题,这些问题将在某个地方变得可利用。
–弗兰克·霍普金斯
19/12/10在23:40
#3 楼
欢迎使用新的编码范例:您在库之上使用库。您并不孤单,但是您还需要了解,每当您引入未编写的代码时,都会带来一定的风险。您的实际问题是我该如何应对这种风险?
理解您的软件应该做什么?
图书馆管理人员经常会成为一种方便的方式,以“正常工作”的方式添加代码,而无需费心去理解它应该做什么。因此,当您信任的库代码执行不良操作时,您会措手不及,想知道发生了什么。这是单元测试可以提供帮助的地方,因为它可以测试代码应该执行的操作。
了解源代码
Composer(或任何程序包管理器)可以从您指定的任何源代码进行安装,包括滚动库昨天由一个完全未知的消息来源报道。我愿意从具有SDK的供应商那里安装软件包,因为该供应商是高度受信任的来源。我还使用了来自其他可信任工作源的软件包(即,PHP项目中的某个人有一个库回购)。盲目地相信任何来源都会给您带来麻烦。
接受存在一些您永远无法完全缓解的风险
2016年,一个NodeJS开发人员在退出项目并要求他们的图书馆时瘫痪了很多软件包未发布。他们有一个简单的库,其中有数百个其他软件包列为依赖库。或者,也许该基础结构不是为处理软件包分发而构建的,所以它会随机失败。互联网在分布式软件开发世界中已经非常擅长“使事物正常工作”,以至于人们在停止工作时往往会感到沮丧或困惑。
当PHP 7.0发布时,我不得不做大量的工作来制作我们在7.0环境中使用功能的开源第三方软件包。我花了很多时间,但是我能够帮助该软件包的作者解决一些问题,并使它在7.0环境中可用。替代方案是替换它……这将花费更多时间。我们接受这种风险是因为该软件包非常有用。
评论
商定,每段代码都有相关的风险,包括操作系统和编译器。
– Tracy Cramer
19年12月10日在16:30
#4 楼
但是,最基本的安全问题仍然存在:我不知道此“已安装”代码包含的内容,也不知道每次更新都添加/更改了什么。当我的Composer获取更新时,库的一位作者可能很容易受到损害,导致我的PHP CLI脚本突然将我的Bitcoin wallet.dat发送到某个远程服务器,在我的机器上安装了RAT /特洛伊木马,甚至更糟。实际上,这可能已经发生了,我再也不明智了。我根本不知道。从逻辑上讲,我没有任何想法。
查找Heartbleed,这是OpenSSL中的巨大安全漏洞。 Heartbleed通过首先将最后的数百或数千个(网络加密的)交易保存为纯文本,然后为知道它的任何人提供了一种简单且未记录的工具来进行远程连接并检索用户认为的所有内存缓存交易,从而有效地使SSL失效已以纯文本格式安全加密。到那时,OpenSSL可以保护绝大多数的自托管网站,大量的银行甚至政府情报服务。
然后查找Meltdown和Spectre,它们是现代Intel CPU中内置的大量错误。 Meltdown和Spectre完全抵消了在保护模式下运行CPU的能力,并且与操作系统无关,可以在每个操作系统上使用。
多年以前,一个名为MSBlaster的恶意软件利用了(我什至不知道这是一个错误-只是一个非常愚蠢的)Windows XP后台服务,该服务甚至在默认情况下都没有运行-它只会被绝大多数Windows用户,然后仅由IT部门了解。最终,这促使ISP发布了内置于其调制解调器设备中的硬件防火墙,并促使Microsoft将内置软件防火墙嵌入了其操作系统中。大约在同一时间,在主要发行版本中发现了一个所谓的“防病毒” Linux平台发行版,其中包含内置的rootkit。
正如其他人所说:您必须信任某人一点。事故和恶意都会造成问题。我就像您-The X-Files and Uplink(TRUST NO One!)的忠实拥护者-但现实情况是您的SSL加密引擎或物理硬件设备很可能会出现安全漏洞,而这些漏洞的可能性要大得多在出现关键任务故障时代表它们。
如果您认真考虑为保护您和您的用户的安全而花费更多的精力来重新发明Composer滚轮,那么请认真考虑如何再努力:设计您自己的CPU,主板,RAM,HDD和光盘驱动器。编写自己的操作系统和硬件驱动程序。也制作自己的编译器。忘了PHP,因为解释器中可能会出现问题-实际上,也忘了C和C ++,因为编译器中可能存在问题,甚至不用别人编写的汇编器来考虑汇编语言。使用十六进制编辑器从头开始将所有自己的软件编写成机器说明。
或者您可以像行业成员一样行事。订阅Composer / PHP / YourLinuxDistro的更新新闻通讯,也许也可以加入一些基于安全性的独立新闻通讯,并订阅Wired。查看系统日志。使用PCAP定期测试您的网络,以确保没有任何未经授权的网络流流入或流出。主动监控可能的威胁,不要对尚未发生的事情抱有偏执。
评论
好吧,您的第一段中有很大一部分是关于这种错误的理解的,并且与问题实际上没有任何关系。底线是一个很好的建议,但答案可能会因编辑得少一点而受益。最后,您提到的各种漏洞为何存在都无所谓;它们相关的原因是它们的存在位置,因此减少对后门的猜测将使这一点更加清楚。
–IMSoP
19/12/10在17:52
这确实无法回答问题。您的前5个段落似乎是完整的切线。最后一段更接近主题,但这也是切线。这不是关于如何检查代码(预防),而是如何从特定威胁中检测非常特定类型的操作。
– schroeder♦
19/12/11在7:32
我看不到订阅有线新闻(技术新闻杂志)会有什么帮助。
–以前
19/12/12在10:07
#5 楼
作为中高级开发人员,我曾考虑过相同的问题。需要考虑的几点:优先考虑对于安全性至关重要的代码。显然,这将包括身份验证和登录代码,权限验证,支付处理器集成之类的内容。任何需要敏感信息或进行网络呼叫的东西。
在视觉上浏览样式库之类的内容-您应该能够快速确定它们仅在进行样式化-以及效用函数之类的内容。大写的字符串,空格替换,重新排列数组...您应该能够快速浏览代码,并看到它们没有做任何意外的事情。
即使您没有像工程师一样完全反向工程代码自己,您应该能够浏览源代码并确定它是否旨在对逆向工程友好。代码应记录有用的注释,变量和方法名称应相关且有用,功能和实现不应太长或太复杂或包含不必要的功能。令人赏心悦目的代码当然不是恶意黑客的首选攻击媒介。
请确认该代码具有已建立且成熟的用户基础。您想吸引那些获利的知名公司使用的项目。
确认主要贡献者的真实身份。对于大型项目,首席开发人员将为他们的工作而感到高兴。您应该能够找到博客文章,社交媒体帐户,甚至可以找到简历或用于咨询工作的营销页面。联络我!等。
确认最近的错误修复正在积极维护开源代码。查看出色的错误报告-数量肯定会有所减少-不要相信声称某个特定工具或库没有错误的说法。那是个妄想。
避免使用带有过多广告的“免费”网站。请避免没有可用的演示站点的项目,或者该演示“难看”,维护不当或经常脱机的项目。避免过度宣传的项目或过多的流行语,不要宣称未经测试的卓越性能。避免从匿名博客下载。等等。
恶意地思考。如果您想破坏自己的网站,该怎么办?如果您想将不安全的代码潜入广泛使用的库中,该怎么办? (显然,实际上并不尝试这样做。)
分叉开源项目,或下载备份。永远不要相信您喜欢的开源项目的正式回购将无限期地在线。
因此,与其尝试分别阅读和理解每一行代码,不如了解每个库的含义。以及为什么您相信这样做。我真的认为,如果您的工作有利可图,那么项目的规模没有上限。您可以“审核” 1,200,000+行代码或120,000,000+行代码!
#6 楼
Composer可以使用composer.lock
文件,并且默认情况下会通过https://packagist.org/(请注意HTTPS)下载软件包。因此,您将拥有庞大的软件包存储库以及带有SHA1校验和的安全下载,以确保您完全下载曾经指定的内容。仅此一项就对您有很大帮助。如果您坚持依赖更新的保守性,还可以期望该软件包的版本已在生产中使用。
最后,您将不得不信任某个人。您可以信任自己编写无漏洞利用的代码,也可以像其他人一样信任成千上万的社区项目,甚至更多的用户看到它。
最后,我认为您可以选择。如果其他人“盲目地飞行”,即没有您想要进行的安全审核,并且以较低的价格和更快的功能发布来吸引“您的”客户,则无论如何,任何人都不会从您的安全自编写应用程序中受益。
评论
加密的传输和校验和不会告诉您任何代码实际的功能以及谁对其进行了审核。我可以在5分钟左右的时间内将一个程序包放到Packagist上,将其标记为v2.5.9,以便于维护,但要使用可以上传到我选择的服务器上的尽可能多的数据的代码来填充它。
–IMSoP
19/12/10在17:56
评论
评论不作进一步讨论;此对话已移至聊天。