Using open source in software products is a hot topic, especially from the perspective of the supply chain attacks exploiting external software dependencies. In view of the global push to ensure the safety and security of the software supply chains, it is paramount to know what components go into your software product.
Open source software is a crucial part of almost every product out there, making it an absolute necessity to follow certain practices when using open source within one’s software.
Open source inbound usage, also known as open source inbounding, is a process of consuming open source software as a part of the software products and services. According to Synopsys, up to 99% of the reviewed codebase contains some form of open source components, while White Source states that 60% to 80% of the modern web applications contain open source.
The use of open source has its advantages and its risks. The main risk stems directly from the open source advantages. Since the upstream open source code contribution is governed with an extremely varied degree of scrutiny and diligence, one cannot guarantee that open source code is uniformly safe to use.
In addition, there is no guarantee that an upstream open source code will retain the assigned open source license, or stay open source at all (see the Elastic, MongoDB, and Grafana cases). One cannot also predict if an upstream open source project will continue to be maintained.
To read more on the open source risks, please check the following article series by Dawn Foster: Navigating Open Source Risk: Licensing, and Navigating Open Source Risk: Contributor and Organization Risks.
Before dealing with the open source dependencies, I think we should define what software should generally achieve. In no particular order:
- It’s always nice to deliver on the planned features.
- It certainly is good to build secure and high quality software.
- It is very practical to follow reliable release processes, while providing build reproducibility and maintainability.
- All the while complying with the licensing, copyright, and intellectual property requirements.
Ensuring that all of the above is accounted for is always a game of balance.
Now with the goals at hand, we can explore the pitfalls that are waiting for us while using open source components. I’ll do it in a form of Do’s and Don’ts:
- Do not presume that community repositories follow the same quality and security practices as you do.
- Do not assume that community artifacts are safe to use or to re-distribute.
- Do know all your dependencies, including transitive ones (the dependency of a dependency). These transitive dependencies are just as important as the direct dependencies.
- Do not ignore binary dependencies, since they pose the same security and legal risk as source code dependencies.
- Do not forget the product or service build toolchains when evaluating security and legal risks.
- Do have a backup plan in case an upstream open source dependency isn’t feasible to use (due to a license change, lack of maintenance, excessive vulnerability profile, etc.).
What can we do to address these risks? The approach I would suggest is multi-stage:
- To address availability and build reproducibility requirements, make sure to mirror the open source dependencies locally (both source code and binary artifacts); and build your software using these local mirrors.
- To minimize potential security threats, strive to build from source code. When it is necessary to use pre-built binaries, use only the authoritative package versions obtained from the sources that you trust.
- To ensure a secure supply chain, both the repository mirrors and the build systems should be securely deployed and configured. Regular security audits are also needed to ensure the system continues to be safe.
- To address both security and compliance requirements, SBOM (Software Bill of Materials) is needed to keep track of all the components in your software product
- Source code package is needed for the source code audit, license compliance verification, as well as keeping component provenance data (this will ensure the precise software build can be reproduced). A local mirror will help in retaining the source code package.
- Whenever you consider changes to the open source component (bug fixes, vulnerability updates, feature implementations), do not hesitate to contribute these changes upstream. This simplifies your software maintenance and in the end this approach benefits the whole community.
By no means this summary will cover absolutely everything around inbound open source usage, yet I’d like to think it will set a right direction for anyone using open source in their projects.
In conclusion, using open source is encouraged and shouldn’t be an obstacle to developing software, as long as you inbound open source responsibly and in a secure way.
One of the key phrases in this article is a trusted source. I will talk about this in the second part of this blog series.