- 开源软件供应链
- 武延军 梁冠宇 吴敬征 屈晟 赵琛编著
- 5350字
- 2025-06-09 17:26:09
1.1 关注开源软件供应链的原因
计算机软件已经深入人们生产生活的各个方面,无论是小型的智能穿戴设备还是大型的工业重型机械,都离不开计算机软件的支持。人们对软件功能的要求越来越高,这导致软件的复杂度不断增加。同时,人们也希望自己的需求能够快速得到满足,这又促使敏捷快速成为当今软件构建过程中的主要目标之一。软件复用能够提升软件开发效率,降低维护难度,因此软件模块化也被越来越多的开发者认可并付诸实践。在开源软件领域,人们可以自由地访问、修改和分发源代码,以满足他们的特定需求。这不仅使开发者能够节省时间和精力,而且还能促进协作和共享知识。通过使用开源软件,开发者可以避免从头开始编写整个程序,而是利用已经存在的软件模块来构建自己的项目。这种模块化方法提供了更快速、更高效的解决方案,并降低了出错风险。此外,在使用开源软件时,由于其通常广泛受到社区的支持和审查,因此故障修复和安全更新也更及时。另一个值得注意的好处是软件复用还有助于减少维护工作量。一旦有人修复了某个模块中的错误或漏洞,并将该修复提交给社区后,其他用户就能够从中受益,并不需要每个人都重新进行同样的修复工作。这种共享责任和资源有效地减轻了单个用户或组织承担维护任务的负担。当然,在航空航天、工业控制等安全攸关领域利用开源软件时仍然需要谨慎并进行适当评估。总之,在现代软件行业中采用软件复用策略是至关重要的。对于寻求高效率、灵活性和成本优势的组织来说,开源软件供应是一个理想选择,并且它正在变得越来越流行。Synopsys[1]公司的《2024开源安全和风险分析》报告就指出,在2023年所检测的1067款软件产品中,96%都包含开源组件,且开源代码约占总代码量的77%。Sonatype[2]公司在报告《2024年软件供应链状况》中,按编程语言分组比较了2023年至2024年的软件产品对开源组件的依赖数量。结果显示,在所有语言生态系统中,对开源组件的依赖都有大幅增加。其中,Java、PyPI、NPM分别增长36%、87%和70%。GitHub 2020年度报告[3]中对至少依赖一款开源组件的项目进行统计,发现这类项目在对应的语言生态下占比极高,其中以JavaScript(94.0%)、Ruby(90.2%)、.NET(89.8%)、Python(80.6%)最为明显;而在其2019年的报告中也提到,GitHub平台上托管的项目平均有180个开源组件有依赖,依赖最多的项目甚至有1000多个开源组件[4]。
一般情况下,“供应链”是一种由多个组织参与组成的网络,组织在其中以上下游关系互联,它们在不同生产活动或过程中,以产品或服务的形式开展协作为最终用户产品贡献价值。而在现今软件产品的生产过程中,单一人员已经很难独立完成生产需求,通常由多人协作完成。此外,由于大量引用了第三方模块,软件的生产过程不仅存在显式协作关系,还存在间接形成的隐式协作关系。这些协作关系使软件产品的生产过程同样呈现出了类似于“供应链”的特征,因此被称为软件供应链。参与到供应链中的角色需要相互配合和沟通,以确保产品能够按时高质量地完成。由于协同过程中涉及多个组织或人员之间的信息交流和协调,因此良好的沟通和协作技巧对于整个供应链的顺利运行至关重要。合理规划、管理和分配任务也是保证项目顺利进行的关键。基于此,供应链管理可以理解为对一款产品从生产到销售完整生命周期的管理。以冷链产品为例,其生命周期包括采摘、仓储、运输、分销等步骤,供应链管理需要每个环节都将温度控制在一定范围内,且环环相扣,不能中断[5]。类似地,一款软件的生命周期包括编码、测试、构建、打包、分发等多个步骤。而软件供应链管理则涉及软件产品本身,以及所有直接依赖和间接依赖的软件模块的生命周期,任何环节出现问题都会导致软件产品存在安全风险。随着开源软件的广泛采用,一种新一代以开源软件为主的软件供应链已经形成,简称开源软件供应链。
开源软件的特点之一是采用群智开发模式,通常由世界各地的社区、公司、组织甚至个人发起和维护,管理方式相对松散,因此质量和可控性难以保障。Sonatype公司的统计报告显示[6],2021年利用上游开源生态的漏洞,对软件供应链发起的攻击占比上升650%;而2020年这一统计数据[7]为430%。相较于传统软件供应链,开源软件供应链随着供应层级不断加深,其规模也不断扩大。这导致针对上游的攻击更加难以发现,并且影响范围也更广泛。以JavaScript编写的软件产品为例,除去直接依赖,其开源组件间接依赖数量的中位数高达683个。一款成熟的开源操作系统的发行版,更是需要维护上万个节点的供应链规模。由此可见,开源软件供应链面临着许多风险,包括攻击更隐蔽、传播性更强、影响范围更广等。
根据Tanenbaum等人在Operating Systems Design and Implementation中的定义,操作系统是管理计算机硬件资源和软件资源的系统程序集合,其中包括内核(如Linux、FreeBSD等)及其他系统工具。可以看出,操作系统是一种典型的复杂软件,其包含的系统程序间存在着复杂的供应关系,未经优化的开源软件供应链很可能对整个系统造成不良影响。然而,已有工具仅能提供有限的开源软件供应链管理功能。以Linux发行版为例,它们是指Linux内核衍生出的操作系统发行版(如openEuler、Ubuntu、CentOS、Android等)。这些发行版将众多实现不同功能的开源软件,以软件包的形式与Linux内核有机地整合在一起,形成一条复杂的开源软件供应链。常见的Linux发行版,仅一个版本的供应链通常都会包含上万节点(如Ubuntu 18.04涉及29 207个软件包、Debian Unstable涉及32 453个软件包等),即便是通过剪裁构建而成的较为精简的系统,也包含近百个软件包[8]。在没有工具帮助的情况下,成功安装软件包需要遵从其依赖关系,按照正确的顺序执行安装。这要求安装者具备必要的专业知识,并且进行琐碎的准备工作。软件包管理工具被视为Linux发行版的必备组件,依据功能将开源软件拆分或合并为不同的软件包,同时维护它们之间的依赖关系。在一定程度上,这能够帮助软件产品生产商厘清依赖组件间的供应关系。除此之外,Linux社区发起了Linux From Scratch(LFS)项目,旨在指导用户如何从零开始构建操作系统。LFS项目衍生出Automated Linux From Scratch(ALFS)项目,为用户提供自动化构建工具。还有Yocto等更为高级的Linux发行版定制化构建项目,能够帮助Linux发行版产品制造商屏蔽底层硬件架构的差异性。传统供应链的关键步骤[9]如下:①原始材料溯源;②生产商将原始材料加工成基础组件;③集成商将基础组件组装成完整产品;④交付产品给最终用户。经过对照可以发现,已有的工具仅仅关注开源操作系统及其软件供应链的构建环节,对应于传统供应链关键步骤中的第3步,其他步骤均不涉及。除了功能上的不足之外,信息缺失也是难以实现开源软件供应链风险有效管理的重要原因之一。软件包管理工具通常仅包含构建环节所需的基本信息,并不足以支撑风险管控。
针对传统软件供应链风险管控问题,已有的研究成果通常会对软件产品的生产过程进行分析,并构建风险模型,进而实现风险管控。然而,在处理开源软件供应链时,这些方法存在全局信息处理不足、风险识别和应对能力不足、管理效率不足等问题。和传统软件供应链相比,开源软件供应链在运行过程中,会产生侧重不同且规模更大的信息,主要包括以下几点。①开源软件的版本管理信息。由于开源软件是通过不断提交代码来进行更新和改进的,因此必须确保能够正确地追踪和管理不同版本的代码。②开源社区的活动信息。了解开发者和用户在开源社区中的讨论和反馈可以帮助预测可能出现的问题,并及时采取措施进行修复或改进。③安全漏洞报告与修复信息。及时了解有关已经发现的安全漏洞,以及相应的修复方案对于保护系统安全至关重要。④第三方依赖管理信息。许多开源项目都依赖于其他项目或库,需要确保这些依赖能够正确地维护、更新和替换,以避免潜在的问题。⑤开放度量指标信息:通过收集、分析并监控一些度量指标(如代码覆盖率、缺陷率等),可以更好地评估软件质量,并帮助决策者制定风险治理策略。
以上信息是实现风险管控的依据,通过有效地收集和组织,提取有价值的数据,并转化为机器能够理解的知识,构建开源软件供应链知识图谱,并在此基础上,研究自动化程度更高的风险管控方法是一条可行路线。已有的研究中,Bajracharya等人提出的Sourcerer和Ossher等人提出的SourcererDB主要面向Java语言开发的项目进行知识提取和模型构建,为进一步分析相关项目打下基础;Ma等人提出的World of Code实现对软件版本控制信息的知识化表示,并以此为基础为进一步分析开源生态提供支撑;Li等人提出的Software Knowledge Graph则主要对软件缺陷信息实现了知识化表示,并通过面向知识图谱的检索快速查询软件项目的缺陷信息。
总体来看,在开源软件供应链风险的自动化管控方面有很多成果,但仍然存在以下不足。①信息收集与整合问题。由于开源软件供应链涉及开源软件、组织和个人等众多元素,导致信息分散且不完整,进而造成信息的正确性和全面性不足。此外,由于更新成本高,导致在信息的时效性方面也存在不足。②供应关系的建模和分析问题。在开源软件供应链中,多个组织和个人之间存在复杂的供应关系,需要对这些关系进行建模和分析,以便有效地识别潜在的风险。已有建模方法在准确描述开源软件供应链特征方面存在不足。③风险评估与识别问题。在开源软件供应链中存在各种潜在的风险,包括代码漏洞、恶意代码、知识产权纠纷等,如何准确地评估并及时发现这些风险是一个关键问题。④风险管控策略选择问题。针对不同类型的风险,需要制定合适的管控策略,并根据实际情况做出相应调整。⑤监测与反馈机制设计问题。为了确保开源软件供应链风险管控策略的有效性,在实施过程中需要建立监测与反馈机制,并及时进行修正和改进。因此,要实现开源软件供应链风险的有效管控仍然面临许多技术挑战,但只有充分认识到这些挑战并努力解决它们,才能够提高开源软件供应链安全性并推动其可持续发展。
开源软件供应链在技术上面临的挑战主要有以下几点。
(1)开源软件供应链的本质特征不明确 相较于传统软件供应链,开源软件供应链在规模、生产方式、参与主体等方面存在明显差异。然而,由于现阶段缺少相关研究,开源软件供应链的本质特征不够明确,进而导致针对风险管控难以展开系统性的分析和研究。要明确开源软件供应链的本质特征,在厘清系统的运行原理、明确系统各个环节中有哪些角色参与,以及这些角色之间如何交互的等方面尚存在挑战。此外,如何准确而简明地表述这些信息,同样存在挑战。本书1.2节将重点介绍相关内容。
(2)获取开源软件供应链全局状态信息 要检验某一角色行为是否符合规则约束,需要根据当前系统的状态进行判定。然而,开源软件供应链是一个复杂的系统,涉及多个角色参与,并且每次角色之间的交互都会改变系统的状态。这就使一款软件产品,从编码到交付一轮生命周期的状态转换过程中,就包含了众多不同的状态。考虑到开源软件供应链的生产迭代速度快且规模大,可以预见到,在完整的开源软件供应链系统运行过程中,产生的信息规模必然会呈指数级增长。因此,如何组织和维护开源软件供应链全局的状态信息存在大量技术挑战。这些挑战主要体现在以下三个方面。①监测对象众多。针对一个复杂软件供应链系统,需要监测的对象有很多,如代码库、制品、许可协议等。②数据信息规模巨大。由于开源软件涉及许多地区、组织和人员参与,在此基础上形成了海量数据和信息流,处理这一密集而复杂的数据是非常具有挑战性的。③保证检索效率。为了高效获取所需信息并快速做出决策,必须确保信息检索效率,并采用先进技术进行分析和建模。
(3)识别和管控开源软件供应链的潜在风险 开源软件供应链由于自身特征,引入了多种不同类型的风险,而一些风险类型是开源软件供应链特有的,现有的研究成果难以识别和发现。通过厘清开源软件供应链的运行原理,同时获取系统的全局状态信息,为识别和发现潜在的风险提供了必要的前提条件。但是具体如何通过状态的变化,识别和管控潜在的风险仍然存在挑战。在系统运转过程中,如何实时地检验某一角色的某一行为是否会引入安全隐患。由于开源软件供应链的开放性,任何角色都有可能执行自己权限范围以外的操作。因此,如何利用系统全局状态信息验证和溯源参与角色的行为时需要非常谨慎,并确保其不存在越权行为。另外,在识别风险后,如何有效处理和监控开源软件供应链的风险,同样存在挑战。
(4)改善开源软件供应链风险管控效率 开源软件供应链风险管控需要较大资源开销,主要有以下原因。①复杂的软件产品会直接或者间接依赖大量的开源软件,导致需要管控的对象数量庞大;②由于软件产品的自动化生产能力有限,在处理风险时,很多问题只能通过人工解决。更为严峻的是,与其他产品不同,开发软件产品的过程本身所需要的知识和技能门槛较高。开发者不仅需要具备软件开发能力,还需要掌握一定程度相关领域的知识,这进一步提高了参与生产或风险处理的门槛。因此,在获取系统全局状态信息的基础上,如何评估开源软件供应链中风险等级以及处理的优先级,并以此提高风险管理效率,也面临着技术挑战。
(5)供应链软件的评估和筛选 之前2项挑战主要关注供应链上游生产者的视角,面向开源软件供应链进行风险管控,而第五项挑战则是从供应链下游的消费者视角出发。当消费者有意构筑自己的供应链时,需要从大量的开源软件中甄选符合自己需求的软件。由于开源软件的开发过程已经形成了独特的模式,导致其质量良莠不齐。因此,并非任意的开源软件都能符合供应链标准成为合格的供应链软件。目前已有的筛选方法更多地依赖人工操作,在效率、准确性等方面都存在着较大的局限性。因此,如何基于海量的信息实现高效的供应链软件评估和筛选同样存在技术挑战。