Supply Chain Security

Supply Chain Attack Surface: Dependencies, Images, and SDKs

Why I started thinking about the supply chain

I used to review only the code that the development team wrote. I assumed that the packages, containers, and third-party services were somebody else's problem. Then I read about attacks that started with a malicious dependency or a compromised build pipeline. The dependency was trusted, so the attack spread through the entire supply chain.

This post is my personal study note on the software supply chain attack surface. I am writing it because the topic is broad and the details matter. A package manager, a CI pipeline, a base image, and an SDK are all parts of the supply chain. Each part can be attacked separately, and the result can affect every user of the final product.

Build a dependency inventory

The first step is knowing what the product depends on. A dependency inventory is a list of every direct and transitive dependency, including the version and the source. The inventory is the foundation for every other supply chain check.

The inventory can be generated from lock files, package manifests, container manifests, and SBOMs. A software bill of materials, or SBOM, is a machine-readable list of components. It is the best way to share the inventory with the rest of the organization.

The inventory should include the application libraries, the build tools, the container base images, and the infrastructure automation code. An attacker can target any of these components. If I only look at the application dependencies, I am missing most of the attack surface.

Check the package sources

Packages come from public registries, private mirrors, and direct URLs. The source matters because a package from an unexpected source may contain malicious code. I check the repository URL, the package checksum, and the maintainer history.

Typosquatting is a common attack. An attacker publishes a package with a name that looks like a popular library. The package may contain a malicious install script or a backdoor. Developers who type the name quickly or copy it from an old post can install the wrong package.

I also check the release history. A package that was stable for years and then changed suddenly may be compromised. The change can be in the code, in the dependency, or in the maintainer. I compare the release with the previous versions and look for unusual additions.

Understand the install and build time

Malicious code can run at different times. It can run during installation, during the build, during the test, or during the runtime. The earlier the code runs, the more access it has.

Install scripts are a common vector. A package can define a script that runs when the package is installed. The script can read environment variables, send data to an external server, or modify the build. I review the install scripts in the packages that are used by the project.

Build tools are another vector. A malicious compiler, a compromised build plugin, or a modified task runner can inject code into the final artifact. The code is present in the output even though the source repository looks clean.

Inspect the CI pipeline

The CI pipeline is one of the most valuable targets in the supply chain. It has access to the source code, the secrets, and the deployment environment. If an attacker can control the pipeline, they can modify the final product.

The pipeline often uses third-party actions, plugins, and scripts. Each one is a potential supply chain attack. I check the action versions, the checksums, and the repository origins. I also look for secrets that are stored in the pipeline configuration.

The pipeline credentials should be short-lived and scoped to the job. A credential that can push to the production repository is a much bigger risk than a credential that can only download dependencies. I review the credential policies and the audit logs.

Container images and base images

Container images are another layer of the supply chain. A base image can contain outdated packages, default credentials, and unnecessary services. The image is built once and then used by many workloads, so a flaw in the base image spreads widely.

I check the image provenance, the digest, and the signature. A signed image with a known digest is harder to tamper with than an image that is pulled by tag. The tag can change without notice, while the digest identifies the exact content.

The image should be minimal. A production image does not need a package manager, a shell, or a compiler. Every extra component is a potential attack surface. I look for unnecessary tools and writable layers in the image.

Third-party SDKs and services

Mobile and web applications often integrate third-party SDKs. The SDKs collect data, provide analytics, or implement authentication. Each SDK is a trusted third party inside the application.

The SDK can collect more data than the product needs. It can access the clipboard, the contacts, the location, or the device identifiers. I map every SDK to the data it receives and the permissions it requests.

Third-party services also expand the trust boundary. A payment processor, an email provider, or a file storage service handles data on behalf of the application. If the service is compromised, the application data may be exposed. I document the services and the data flow.

Secrets in the supply chain

The supply chain is a common source of secret leakage. A package may contain a hardcoded API key, a container image may contain a cloud credential, or a CI log may contain a password. The secret is then distributed to everyone who uses the component.

I search the inventory for secrets. The search includes the source code, the configuration files, the container layers, and the CI logs. A secret that is embedded in a public image or a public package is a critical finding.

The impact depends on the secret. A database password affects the database. A cloud credential affects the cloud account. A signing key affects the entire software supply chain, because the attacker can sign malicious updates.

Mitigation controls

The first control is pinning. I pin the exact versions of dependencies, actions, and images. The pin prevents a new release from changing the behavior without review. The pin should include a checksum or a digest so that the content can be verified.

The second control is private registries and mirrors. A private registry controls which packages are available and can proxy the public registry. It also provides a place to scan the packages before they are used.

The third control is short-lived credentials. The CI pipeline and the deployment process should use credentials that expire quickly and are scoped to the task. The credentials should be rotated automatically.

The fourth control is continuous monitoring. The SBOM should be compared with vulnerability feeds and incident reports. A new vulnerability in a dependency should trigger a review and an update.

SBOM in practice

The SBOM is more useful when it is connected to the rest of the security process. A static list of components does not help if it is never compared with the vulnerability feeds. I want to see the SBOM in the CI pipeline, in the deployment process, and in the incident response plan.

The SBOM should be generated from the actual build, not from a separate list that can drift. The build output is the source of truth. The SBOM should include the package names, the versions, the licenses, and the checksums.

The SBOM should be reviewed when a new vulnerability is announced. The review should identify every product that uses the affected component. The result is a list of systems that need an update.

The SBOM also helps with procurement. A vendor can be asked to provide the SBOM for their product. The buyer can compare the components with their own policy and their own vulnerability database.

A realistic attack scenario

To understand the supply chain risk, I walk through a realistic attack. The attacker chooses a package that is used by many projects. The package has a maintainer account with a weak password. The attacker takes over the account and publishes a new version.

The new version includes a small change in the install script. The script reads the environment variables, looks for a cloud credential, and sends it to the attacker's server. The change is hidden in a package that has been trusted for years.

The next build pulls the new version. The build runs the install script, the credential is leaked, and the attacker gains access to the cloud account. The source code looks clean because the malicious code was only in the package.

The attack does not require a vulnerability in the application code. It requires a trusted component that is compromised. That is why the supply chain is a separate attack surface.

Vendor risk

The software that an organization buys is also part of the supply chain. A vendor may use a component that has a known vulnerability, or the vendor may have weak development practices. The buyer cannot inspect every line of vendor code, but the buyer can ask questions.

The questions include: what components are in the product, how are the components updated, who has access to the build, and how are the release artifacts signed. The answers reveal the vendor's security posture.

The vendor relationship should include a security incident process. If the vendor is compromised, the buyer needs to know quickly. The incident response plan should cover the supply chain, not just the internal network.

The vendor risk is not only about software. A hardware vendor, a cloud provider, or a hosting provider is also part of the chain. The trust boundary extends beyond the code.

Incident response for the supply chain

When a supply chain incident happens, the first question is whether the affected component is in use. The SBOM answers the question quickly. Without the SBOM, the team has to search the entire codebase and the deployment history.

The second question is what the attacker could do. The answer depends on when the malicious version was introduced and where the component was used. The deployment logs and the SBOM history provide the timeline.

The third question is how to respond. The response may include removing the malicious version, rotating the credentials, and rebuilding the affected images. The rebuild should use a clean base image and a verified dependency.

The response should also include a review of the detection. Why was the malicious component not caught earlier? The answer leads to new controls, such as checksum verification and dependency scanning.

One more thing to check

The supply chain risk does not stop at the code that is deployed. The same dependencies are often used in the documentation, the training environment, and the customer-facing artifacts. A malicious component in a training image is still a supply chain issue because it can be copied into a production deployment. I check the full lifecycle, from the developer workstation to the final release. The weakest point in the chain is often the one that the security team does not monitor. The inventory should cover the whole path, not just the last step.

Common mistakes I make

My biggest mistake is focusing on the application dependencies and ignoring the build tools and images. The supply chain includes everything that produces the final artifact. My second mistake is trusting a package just because it is popular. Popular packages can be compromised, and the attack can affect millions of users.

The third mistake is not checking the checksums. A package with the right name and version can be modified in transit. The fourth mistake is storing secrets in the pipeline configuration.

My quick checklist

  1. Build a complete dependency inventory, including transitive dependencies.
  2. Verify the package source, checksum, and release history.
  3. Review install scripts and build-time behavior.
  4. Inspect the CI pipeline actions, plugins, and credentials.
  5. Verify container image provenance and minimality.
  6. Map third-party SDKs and services to the data they receive.
  7. Search the supply chain for hardcoded secrets.
  8. Pin versions and use private registries and short-lived credentials.

What I would do next time

Next time I want to start with the SBOM instead of building the inventory from scratch. The SBOM saves time and gives me a complete view of the components. I also want to spend more time on the CI pipeline, because that is where a small change can affect every release. The supply chain is not a single component. It is the whole path from source code to running software.