By: Jonathan Knudsen, Senior Security Strategist at Synopsys Software Integrity Group
Traditional manufacturing is a useful analogy for creating software. I usually relate software to cars. If you want to build a car, you don’t ever start from scratch. It makes no sense to create your own spark plugs or brake pads. Many, many parts of the car come from other companies, which in turn sometimes acquire smaller parts from their own vendors. This web of dependencies is a supply chain, an analogy that carries over very well to the manufacture of software.
Hardly anyone writes software from the ground up. Instead, we assemble software components, often open source components, into a complete product, creating some percentage of original, or first-party, code as glue to hold everything together.
For example, if you created a small device that communicated over SSL, you wouldn’t spend the time and money to create your own implementation. Instead, you’d use one of the available open source implementations, such as OpenSSL, WolfSSL, or MatrixSSL. Likewise, you wouldn’t create an operating system yourself. Instead, you’d use a readily available open source operating system, probably something plucked from the Linux family tree.
Like physical parts used in assembling cars, software components can have a nesting relationship, where one component might be a subassembly of smaller components.
Trust, but verify
One reason car manufacturers produce reasonably safe cars is their careful management of the supply chain. Each manufacturer keeps a bill of materials, a list of every part that goes into the car. The manufacturer also keeps a list of every vendor that supplies parts. The manufacturer builds a trust relationship with its vendors and has processes in place to ensure the correctness of every part. After all, if a car catches fire because of a faulty part, it is the car manufacturer who must take the blame.
The supply chain is really a chain of trust. Consumers trust the manufacturer to sell them a product that is reasonably safe and reliable. The manufacturer trusts its vendors to create parts that are reasonably safe and reliable. In turn, these vendors trust their own vendors to create subparts that are reasonably safe and reliable.
The old Russian proverb is always apt: “Trust, but verify.”
Car manufacturers ensure the quality and safety of their vehicles by actively managing their supply chain. They do this by examining both their vendors and the parts the vendors are supplying.
At a business level, the car manufacturer will want vendors to describe how they create parts that are precise and correct and how the vendors themselves ensure the quality and safety of the parts they produce. Sometimes trust is also based on a shared history. If the manufacturer has had a long, successful relationship with the vendor, both parties might expect that to continue.
The manufacturer should also perform specific testing on the parts it receives from a vendor. If it gets a shipment of 20,000 spark plugs from a vendor, it would be prudent to select a dozen at random and make sure they are the right size and perform correctly.
Freedom is not free
Software manufacturers should follow similar processes of supply chain management. An open source component is like a box full of spark plugs that you found one day by the side of the road on your way to work at the car factory. You wouldn’t say, “What luck! I’ll just use these!” You might use them, but only after careful testing to make sure they work properly. Even then, you’d be skeptical if you didn’t have some idea of who made them and where they originated.
Unfortunately, for too many years, too many organisations have been building software from parts they found on the side of the road. Open source software components provide some functionality that software manufacturers need. Furthermore, you use open source components without buying them—so doesn’t that mean they are free?
It sounds too good to be true. It is too good to be true. Certainly, open source components provide useful functionality. But they do not come for free.
Before using an open source component, you must verify that it does not introduce an unacceptable level of risk into your product. This risk comes from the presence of known vulnerabilities (CVEs) in the open source component, as well as the possibility that the component’s license is incompatible with your product.
Software components, after all, are just pieces of software built by other teams. You probably don’t have much visibility into these teams — who they are, how they ensure quality and security, and so forth. Open source developers are as human as the rest of us, and when they make mistakes, they can introduce vulnerabilities into their software components. Usually, when researchers discover those vulnerabilities, which are tracked as CVEs, the component team will fix the issues and release a new version of the component.
Open source components also have software licenses that set out the rules for how others can use the components. Licenses range from broadly permissive to restrictive, with some requiring that developers who use the components publish their own source code. Understanding the licenses that govern the components you’re using is crucial if you want to release your own product under your chosen license terms.
After you’ve used open source components, you need to keep an eye on them. Researchers discover new vulnerabilities in open source components all the time. You need to be ready to spring into action whenever a vulnerability surfaces in a component that you’ve used. Speed is of the essence. You must examine the vulnerability to see if it’s exposed in your own product. If so, you need to update your product with a fixed version of the component or mitigate the vulnerability some other way. Your customers then must update their installations of your product as soon as possible.
Sometimes, beleaguered product managers use a manual process or a spreadsheet for tracking open source components, but this is akin to moving a pile of dirt with a pair of tweezers. Why not use a bulldozer instead?
Software products often use hundreds of open source components, so the basic task of creating a list of the components in use (the software bill of materials) can be daunting. Furthermore, component version numbers change with each release. While licenses are typically stable across multiple releases of a component, vulnerabilities apply to specific versions. Manually correlating the component versions you are using to their associated CVEs is a huge challenge.
Fortunately, software composition analysis (SCA) tools automate much of this work, leaving you free for more important tasks, such as setting policies about what constitutes acceptable open source component risk.