Today, software regularly integrates open-source code from third-party sources into applications. While this practice empowers developers to create more capable software in a shorter time frame, it brings with it the risk of introducing inadequately vetted code. How aware are we of the security of our open-source code?
Most of us use pip or npm to freely install software, making decisions based on functionality and support. Efficiency is the goal when we have delivery targets to meet. If we choose not to use open-source solutions, we miss out on their significant productivity benefits. But, if we decide to use open-source solutions, we take the chance of potentially introducing insecure components into our software supply chains and must mitigate any risk with the right tools and processes.
So what is the software supply chain? The software supply chain comprises the steps it takes to develop code before it makes its way into an organization’s application. The chain includes all open-source contributors who wrote the code, the dependencies the code relies on, the repositories where developers downloaded the code, and the organization’s internal review. Each link in the chain represents a potential weak point where unsafe or malicious code can make its way into a production application.
What Can Go Wrong
Google’s security policy points out that “if an attacker successfully injects any code at all, it’s pretty much game over.” Unfortunately, with continuous deployment (CD) becoming more commonplace, the window to spot such attacks before releasing infected code to users has narrowed.
Attackers’ goals are varied. Hijacking resources for cryptocurrency mining, harvesting username and password combinations for credential stuffing, and data scraping are just a few examples. The consequences are often dire.
Let’s explore some of the potential risks of using open-source solutions.
Common Forms of Attack
Malicious software posing as genuine packages routinely shows up in package management software. Two types of supply chain attacks take advantage of modern software’s numerous dependencies: typosquatting and dependency confusion. In both, the assailant uses a variety of tactics to trick the developer or management software into downloading a dependency file that can execute malicious code.
Typosquatting relies on the proximity of keys on a keyboard and common misspelling to gain entry. This method of attack transcends programming language bases. Since the early days of the web, domain name typosquatting has been a problem. Package and image deception has become increasingly prevalent, banking on developers’ quick fingers.
In typosquatting, a publisher has uploaded a package with a misspelled name. The misspelled name is so similar to the original package’s that the developer fails to notice they have misspelled the word, unknowingly downloading malicious code.
Dependency confusion exploits the mix of private and public dependencies that software uses. Hackers typically inspect package.json files for Node.js applications to find internal unclaimed packages on npm. They create malicious packages with this same namespace, and automated developer tools install these external malicious packages instead of the intended internal package.
This tactic isn’t limited to npm. For example, Python’s pip displays insecurities ripe for exploitation. Here, a hacker can register a package on PyPi with the same name as an internal package, identified in a requirements.txt file. At registration, they select a higher version number than the genuine package. When this higher number is in builds that include –extra-index-url, it takes precedence, and this seemingly newer version replaces the older.
Like typosquatting, dependency confusion is a problem for all languages. Similar attacks could happen with a Maven pom.xml file or Gradle settings file in Java or a .csproj file referencing NuGet packages in .NET. Tools incorrectly substitute the code, leaving our application vulnerable.
It’s important to remember that these issues can be present deep in the chain, in transitive dependencies. In the diagram above, we can see that an attacker has targeted a dependency, of a dependency, of a dependency. This nesting makes our ecosystem unmanageable and challenging to audit.
We may trust our developers not to make malicious codebase changes and perhaps feel content that a four-eye review policy will protect our software. When a dependency gets upgraded, we trust that someone else is carrying out reviews with our rigor. But this may not be the case for packages maintained in small teams or by individuals.
An Example Scenario
A malicious actor creates a seemingly innocent package, like some utility functions. Let’s call this Package X.
They then publish their code to a package distribution site. Remember, just because code is inspectable on GitHub doesn’t necessarily mean it’s the same code on the package management site.
They use Package X as part of a pull request into the code for Package Y, fixing minor bugs on open-source projects. Their genuinely-useful bug-fix has pulled in the malicious dependency (Package X), and presto! The malicious code is in the repository.
If our code uses Package Y, then our software inherits the vulnerability in Package X.
Organizations must update their open-source code constantly to mitigate the risk of hidden vulnerabilities. These organizations must also use detection methods such as automated vulnerability scanning to identify known vulnerabilities before they cause damage.
With global news coverage quick to publicize any data or security breach, these incidents can damage an organization’s reputation. Rebuilding that trust is highly challenging.
Empowering Developers to Secure Your Supply Chain
All of the security risks that come with development means developers need access to tools that make security as easy as possible for them. Luckily, Docker seamlessly integrates security measures across our platform to help mitigate risks and secure the software supply chain. The first step is attestation and verification. To establish trust, we must verify code and not make any assumptions about its security.
Docker’s Image Access Management feature, available to Docker Business users, enables organizations to control where they get their software. This approach shifts the control of access and permissions from developers to the site level, with toggle options to easily set options and role-based access control (RBAC) available to manage authorization at scale. This control helps ensure developers are only using approved and secure images.
Image Access Management is also a good way of guaranteeing the sources are legitimate. When your business has hundreds of developers, tracking what each software engineer is innocently installing becomes challenging. Docker Business users get an audit log that records the creation, deletion, and editing of teams and repositories to enhance visibility.
To help developers make better container image decisions, Docker provides a visual way of validating images via badging in Docker Hub. These badges are specific to Docker Verified Publisher Images and Docker Official Images and signal to developers that what they’re pulling is trusted, secure, and ready for use.
Docker also provides vulnerability scanning tools via our security partner, Snyk. Developers can use the Snyk scanner right in their CLI for the insight and visibility they need into the security posture of their local Dockerfiles and local images. This includes a list of Common Vulnerabilities and Exposures (CVEs), the sources, such as OS packages and libraries, versions in which they were introduced, and a recommended fixed version (if available) to remediate the CVEs discovered. When this step is automated, we no longer rely solely on our developers to manually scan for insecurities.
Gaining Peace of Mind
Returning to our Package X example, we now have multiple layers to prevent that worst-case scenario:
- Image Access Management ensures that our developers can only pull base images from trusted, verified sources.
- Role-Based Access Control enables developers to reduce the blast radius by controlling which developers can bring in new content and potentially isolating the breach to a single team’s work.
- Vulnerability Scan automatically scans for CVEs when we build a new image. To quickly resolve our insecure dependency issues, Vulnerability Scanning vets and flags dependencies for our developers and offers remediation options.
- Audit Log provides three months of history capturing all activities. This record helps organizations discover all affected internal supply chains quickly.
This layered approach to security offers increased opportunities for checks. While vigilance and manual checks are still ideal, it’s reassuring to have these tools available to help prevent and combat attacks.
In this article, we’ve explored the genuine supply chain security problem, one that President Biden has even addressed.
By targeting an app’s dependencies, cybercriminals can reach multiple organizations with the hope of evading scrutiny. It’s often the easiest way to break in when organizations are locked down. Everyone is a potential target, and attacks can have wide-reaching implications. Assailants seem happy to play the long game and use social engineering to gain access, perhaps offering their time as repository maintainers. As developers and automated tools integrate components into systems, there become multiple points where an adversary could inject malware.
Docker offers a robust suite of tools for vetting open-source code and dependencies before making their way into an application. Docker Business enables software development to continue to benefit from the productivity gains of containers without being hampered by security concerns.
Get started with Docker Business to discover how Docker helps keep your business safe and secure.
Join us for DockerCon2022 on Tuesday, May 10. DockerCon is a free, one day virtual event that is a unique experience for developers and development teams who are building the next generation of modern applications. If you want to learn about how to go from code to cloud fast and how to solve your development challenges, DockerCon 2022 offers engaging live content to help you build, share and run your applications. Register today at https://www.docker.com/dockercon/