Vendor code vulnerabilities: what third-party security assessments miss in the build pipeline

Key takeaways
Dependency confusion exposure, unpinned transitive dependencies, and CI/CD credential leakage were present in vendor environments that had passed third-party risk reviews within the prior 12 months, based on Vulnox assessment data.
A typical Node.js application with 50 direct dependencies carries 500-800 transitive dependencies that no developer on the team reviewed -- transitive chain compromise is how most successful supply chain attacks execute.
Internal package names are findable through GitHub commit history, job postings, and public error logs in under an hour for most mid-market software organizations, making dependency confusion a low-reconnaissance attack.
CI/CD build cache sharing between pipelines of different trust levels is the least-documented supply chain attack surface and bypasses both code review and dependency scanning controls.
SBOM generation for compliance without active vulnerability monitoring against the SBOM creates a searchable attack surface -- attackers can use public SBOM data to identify vulnerable targets before zero-day patches exist.
Requesting a vendor SBOM in SPDX or CycloneDX format and running it against a CVE feed takes less than an hour and surfaces more actionable risk than a 40-question security questionnaire.
TL;DR
Third-party security assessments are almost entirely disconnected from the actual risk surface in vendor software environments. The questionnaire measures policy intent. The build pipeline is where the attack happens. Dependency confusion, transitive dependency compromise, and CI/CD misconfiguration are the three mechanisms that produce successful supply chain breaches -- and none of them show up in a vendor risk score. This article is about what hands-on assessment finds in vendor build environments and what you can ask for without needing system access.
The vendor that passed the risk review and shipped the backdoor
A fintech in Singapore running a third-party risk program that their compliance team described as mature -- annual questionnaires, SOC 2 Type II certificates on file, contract security addendums -- engaged Vulnox to do a technical assessment of three critical vendors before a platform migration. One vendor had received an acceptable risk score in the annual review four months earlier. The technical assessment found an internal package name exposed in a public GitHub repository commit from 18 months prior. That name had been registered on npm by an unknown account two months after the commit. The vendor's CI/CD pipeline was configured to check the public npm registry before their private one. Every build since the registration had pulled the public package. The public package contained no malicious payload at the time of assessment. It was a clean placeholder. The mechanism was fully operational and had been for 16 months.
The risk review had asked whether the vendor used a private package registry. They did. The questionnaire did not ask whether the private registry took priority over the public one in dependency resolution. The vendor's security team did not know the resolution order. It was a build configuration detail that had never been reviewed because the build worked and the pipeline passed.
How dependency confusion executes and why the build succeeds
Most package managers resolve dependencies by name and version. When a private registry is configured alongside a public one, the resolution behavior depends on configuration that most development teams have never explicitly set. npm, by default in many configurations, checks all configured registries and takes the highest version number. If an internal package is at version 1.2.0 and an attacker publishes a package with the same name at version 9.0.0 to the public registry, npm takes version 9.0.0. The build succeeds. The package installs. The CI/CD logs show a clean dependency resolution. The attacker's code executes with the permissions of the build agent during the postinstall hook -- a lifecycle event that runs automatically after package installation and is invisible in standard build output unless you are specifically watching for it.
Example
In the Vulnox assessment referenced above, the exposed package name was found in a git commit from a developer who had pushed a package-lock.json file containing the internal registry URL and a full dependency tree including internal package names. The commit had been removed from the default branch but remained in the git history, accessible via the GitHub API without authentication. The attacker -- or in this case a security researcher who had registered the name -- needed the package name, a public npm account, and a postinstall script. The entire attack setup takes under 30 minutes once the name is known.
The postinstall hook executes as the user running npm install, which in CI/CD pipelines is frequently a service account with access to environment variables containing registry credentials, deployment tokens, and cloud provider API keys. The malicious code does not need to modify the application. It only needs to exfiltrate the environment variables during the build. The application ships clean. The credentials are already gone.
What technical assessment finds in vendor build environments
Assessment base: Technical pre-assessment engagements across 19 vendor environments assessed as part of client third-party risk programs, 2023-2024, primarily SaaS and fintech vendors in EU and APAC
Internal package name exposure in public repositories in 11 of 19 vendor environments
Recon work on vendor GitHub organizations, including commit history on deleted files and forked repositories, found internal package names in 11 of 19 environments. The sources were: package-lock.json files committed to public repositories (7 cases), error messages in public GitHub issues that contained internal import paths (3 cases), and job postings that named internal tooling directly (4 cases -- some environments had multiple sources). In 3 of the 11 environments, the exposed package names had been registered on public registries by accounts with no visible connection to the vendor.
The vendor security teams were unaware in every case. None of the three registered names contained malicious payloads at assessment time. The window between name registration and payload deployment is at the attacker's discretion. The mechanism was live for an average of 9 months before discovery.
CI/CD secrets in environment variables accessible to all pipeline steps in 14 of 19 environments
When vendors provided CI/CD configuration files for review, 14 of 19 used plaintext environment variables for registry credentials, deployment tokens, or cloud provider keys rather than a secrets manager with step-level access control. In this configuration, a compromised dependency executing a postinstall hook during any build step can read all environment variables set for the pipeline run. The secrets are not encrypted at rest in the pipeline context -- they are available as process environment variables to any code that runs.
This is the amplifier for dependency confusion. The dependency confusion attack delivers code execution. The CI/CD secret exposure determines what that code execution can reach. In most of the 14 environments, the accessible secrets included deployment credentials for production artifact registries -- meaning a successful postinstall hook during a build could publish a malicious artifact to the production distribution channel without any additional exploitation step.
Transitive dependency vulnerability counts 8 to 14 times higher than direct dependency counts
Across the 19 vendor environments where we could review SBOM data or generate it from build artifacts, the ratio of vulnerable transitive dependencies to vulnerable direct dependencies averaged 11:1. Organizations that tracked dependency vulnerabilities were tracking their direct dependency counts accurately. The transitive chain was largely unmonitored. In two environments, a critical CVE in a transitive dependency had been present for over 200 days without appearing in the vendor's vulnerability tracking system because the tracking system only ingested direct dependency data.
Vendors that report their vulnerability exposure based on direct dependency scanning are reporting a fraction of their actual exposure. The fraction varies by application and dependency graph structure but is consistently less than 15% of the real number. When clients ask vendors for evidence of vulnerability management, the evidence typically shows direct dependency coverage. The transitive chain is the part that produces the actual breaches.
Build cache sharing between trust boundaries in 6 of 19 environments
Six vendor environments used shared build caches across CI/CD pipelines with different privilege levels -- for example, a cache shared between a documentation build pipeline running with minimal permissions and a release pipeline running with production deployment credentials. A poisoned cache entry from a low-privilege build could affect a high-privilege build without the poisoning being visible in the high-privilege pipeline's code or dependency manifest. None of the six environments had implemented cache integrity verification or pipeline-level cache isolation.
Cache poisoning via shared CI/CD caches is the supply chain attack vector with the least public documentation and the most structural prevalence. It bypasses dependency scanning entirely because the poisoned artifact is delivered through the cache layer, not through the dependency resolution process. Standard SCA tooling does not examine cache contents.
The vendors with the most mature dependency scanning had the worst transitive exposure
Common belief
Organizations that have invested in Software Composition Analysis tooling understand their dependency risk. If a vendor uses SCA, their supply chain exposure is being managed.
What we found
In one assessment, a vendor's security team produced SCA scan results showing 4 open medium-severity findings in their direct dependencies. When we generated an SBOM from their build artifacts and ran it against the NVD feed, the transitive chain contained 47 findings including 3 critical CVEs. The SCA tool was working correctly. It was configured to look at the wrong scope. The security team had been reporting their vulnerability posture to their enterprise clients based on the 4-finding number for 18 months.
SCA tooling is almost universally configured to scan direct dependencies. The tooling is capable of scanning transitive chains but the configuration to do so is non-default, slower, and produces more findings that require triage. Teams that have deployed SCA typically configured it at setup to scan direct dependencies and suppressed transitive scanning to keep the finding count manageable. The result is that organizations with SCA tooling have a precise, well-managed view of their direct dependency exposure and an almost entirely unmeasured view of their transitive exposure. Organizations without SCA tooling at least know they have unmeasured exposure. Organizations with SCA tooling believe they have measured it.
What organizations say when they rely on vendor risk questionnaires
'We require all vendors to complete our security questionnaire and provide a SOC 2 Type II report. That covers our third-party risk obligations.'
Root cause:SOC 2 Type II covers the controls the vendor selected for their audit scope. Build pipeline security, dependency management practices, and CI/CD secret handling are not standard SOC 2 control categories -- they appear only if the vendor or auditor elected to include them. Most SOC 2 reports do not mention dependency resolution configuration, transitive dependency monitoring, or build cache isolation because those are not SOC 2 control categories. The report confirms the controls it tested. It says nothing about the controls it did not test.
'Our vendor uses Snyk and sends us monthly scan reports. Their dependency risk is covered.'
Root cause:Snyk scanning a vendor's repositories addresses known CVEs in dependencies at the time of the scan. It does not address dependency confusion exposure from namespace conflicts with public registries, transitive dependency scope if configured for direct-only scanning, CI/CD credential exposure that would be reachable by a malicious postinstall hook, or build cache integrity. The scan report answers a specific question about known CVEs in the dependency manifest. It does not answer the broader question about whether the build pipeline can be used as an attack delivery mechanism.
'We asked the vendor if they use a private package registry and they said yes.'
Root cause:Using a private registry and having the private registry take resolution priority over public registries are two different configurations. The question 'do you use a private registry' has a yes/no answer that does not distinguish between them. The configuration detail that matters is whether the package manager is set to prefer-offline, registry-only, or how the registries are ordered in the npmrc or pip.conf. Most vendor security teams do not know this configuration off the top of their head because it was set by a DevOps engineer during initial project setup and has not been reviewed since.
What standard vendor assessment processes do not reach
Git history as an attack intelligence source
Deleted files in git repositories are not deleted -- they remain in commit history and are accessible via the GitHub API or git log without special permissions on public repositories. Developers who accidentally commit internal configuration files, package manifests with internal registry URLs, or environment files and then delete them believe the sensitive content is gone. It is not. Any recon process that includes git history traversal will find it. Vendor security reviews that ask 'have you had any accidental secret commits' are asking about the developer's awareness of the commit, not about whether the content is retrievable.
SBOM data as an attacker resource before it is a defender resource
Organizations publishing SBOMs for compliance purposes are publishing a searchable list of their dependency versions. The defensive value requires monitoring that SBOM against a vulnerability feed on a continuous basis. The offensive value is immediate -- any attacker who finds a pre-disclosure vulnerability in a widely used library can cross-reference public SBOM data to identify which organizations are running the vulnerable version before a patch exists or a CVE is published. The SBOM publication and the monitoring capability are two separate organizational decisions that are frequently made independently, with publication happening for compliance reasons months before monitoring infrastructure is in place.
Vendor developer account security as a supply chain control
The XZ Utils incident demonstrated that a long-term social engineering campaign against an open source maintainer can result in a backdoor in infrastructure that millions of systems depend on. For commercial vendors, the equivalent attack surface is the individual developer accounts that have publish rights to the vendor's private artifact registry or public package namespace. If a developer with registry publish permissions has their npm or GitHub account compromised -- through credential stuffing, phishing, or session token theft -- the attacker can publish a malicious package version under the vendor's legitimate namespace. Vendor risk assessments almost never ask about MFA enforcement on developer accounts with publish rights to artifact registries.
Where vendor code attacks are heading
Within 18 months, a publicly disclosed supply chain attack will be traced to CI/CD build cache poisoning rather than dependency confusion or compromised package accounts, establishing cache integrity as a named attack surface category.
Cache poisoning via shared CI/CD infrastructure is structurally prevalent -- Vulnox found it in 6 of 19 assessed vendor environments -- but has not yet produced a publicized breach traceable specifically to the cache layer. As dependency confusion defenses improve (private registry priority enforcement, namespace reservation), attackers will move to the next weakest point in the build pipeline. Build cache sharing is that point. The attack does not require compromising a package registry or a developer account. It requires code execution in any build pipeline that shares a cache with a higher-privilege pipeline.
Confidence: mediumA published incident report or security research paper specifically attributing a compromise to CI/CD build cache poisoning, distinct from dependency confusion or direct account compromise, before Q4 2027.SBOM-based pre-disclosure targeting will become a documented attacker capability within 24 months, with at least one coordinated attack campaign that demonstrably used public SBOM data to select targets during a vulnerability disclosure window.
The infrastructure for this attack is entirely passive -- no exploitation, no scanning, just data aggregation. Public SBOM repositories and package transparency logs already contain enough version data to identify which organizations are running specific dependency versions. The coordination required is between vulnerability discovery and SBOM data harvesting. As SBOM publication becomes more widespread due to US executive order requirements and EU CRA obligations, the dataset grows. The attack does not require novel technique -- it requires attention to a data source that defenders are creating for compliance reasons.
Confidence: mediumA threat intelligence report documenting an attack campaign where SBOM data was used for target selection during a pre-patch vulnerability window, attributed by a named threat intelligence organization before Q2 2028.
Why vendor risk questionnaires will keep failing and what would actually work
The vendor questionnaire process survives because it produces documentation that satisfies compliance requirements, not because it produces accurate risk assessment. A questionnaire with a passing score creates an audit trail showing due diligence was performed. That audit trail has value in regulatory and legal contexts regardless of whether the underlying risk is real. Organizations know this. Vendors know this. The questionnaire persists because both parties benefit from the documented exchange more than either party needs accurate risk information from it. The technical assessment process -- actually looking at what a vendor's build pipeline does -- produces accurate information but creates friction, requires vendor cooperation on something they cannot easily prepare for, and produces findings that might complicate a vendor relationship the procurement team has already committed to. Accuracy and compliance documentation are different products, and the market has consistently chosen the cheaper one.
Counterargument
The counterargument is that questionnaires scale in a way that technical assessments do not. A mid-market organization with 150 software vendors cannot technically assess all of them. Questionnaires are a triage mechanism that concentrates technical review effort on the highest-risk vendors. That argument is correct and I do not disagree with it. The failure is not that questionnaires exist. The failure is that organizations treat questionnaire results as risk assessments rather than as triage outputs. The questionnaire tells you which vendors to look at more carefully. It does not tell you whether those vendors are actually secure. Most organizations have stopped reading that sentence after the first part.
What to actually ask vendors and what to do with the answers
The passive recon step (step 3) is skipped almost universally because it feels like offensive security work rather than vendor risk management work. It is the step most likely to find an active exposure the vendor does not know about. Running it before the vendor assessment conversation means you enter the conversation with specific, verifiable findings rather than a questionnaire response to evaluate.
- 1Security / vendor risk team
Request an SBOM in SPDX 2.3 or CycloneDX 1.4 format from every vendor running software in your critical path. Do not accept a scan report PDF. The SBOM is a machine-readable file. Run it against the NVD feed using a tool that processes transitive dependencies, not just the top-level manifest. The difference in finding count will be significant.
Expected outcomeAccurate picture of the vendor's real dependency vulnerability exposure including the transitive chain. Identifies critical CVEs that the vendor's own reporting may not include.
- 2Security / vendor risk team
Ask specifically: what is the registry resolution priority order in your package manager configuration? Do your CI/CD pipeline service accounts have publish rights to production artifact registries? Are CI/CD secrets stored in a secrets manager with step-level access control or as pipeline-level environment variables? These three questions cannot be answered correctly by guessing. If the vendor cannot answer them, that is itself a finding.
Expected outcomeIdentification of dependency confusion exposure and CI/CD credential scope. Vendors with mature practices can answer these immediately. Vendors with risk answer vaguely or need to check.
- 3Security team
Run passive recon on vendor GitHub organizations before the vendor assessment call. Search commit history for package manifests, internal registry URLs, and environment file patterns. This takes under an hour for most vendor organizations and requires no vendor cooperation. If internal package names are findable, check whether those names are registered on public registries.
Expected outcomeIdentification of dependency confusion exposure the vendor is unaware of, and a specific, verifiable finding to raise in the assessment conversation rather than a questionnaire response.
- 4Security team
For high-criticality vendors, request evidence of MFA enforcement on all developer accounts with artifact registry publish rights. This includes npm organization membership with required 2FA, GitHub organization settings showing required two-factor, and internal registry access review logs. Developer account compromise is the most direct path to supply chain injection under a legitimate vendor namespace.
Expected outcomeConfirmation that the publish access surface for the vendor's packages requires MFA. Absence of this evidence is a finding that should affect vendor risk tier.
One thing to do before the next vendor review
Pick your three most critical software vendors and search their public GitHub organizations for package-lock.json or requirements.txt files in commit history -- including on deleted files, which remain accessible via the commit graph. Look for internal registry URLs and internal package names. Then check whether any of those names are registered on npm, PyPI, or RubyGems. This takes about 45 minutes total and requires no vendor cooperation. In Vulnox assessments this check found active exposure in more than half of assessed vendor environments. If you find a registered name that should be internal, that is an incident response conversation, not a questionnaire follow-up.
Further Reading
Digital Footprint
digital footprint analysisVulnerability Assessment
vulnerability assessment servicesThird-Party Risk Management
third-party risk management guideNVD CVE Process Explained
NVD CVE vulnerability processShadow IT Discovery
shadow IT discovery insights
Frequently Asked Questions
What does a vendor code vulnerability assessment cover that a standard third-party risk questionnaire does not?
Questionnaires capture what vendors say about their security practices. A code-focused assessment looks at what their build pipeline actually does. The gaps that matter most -- dependency confusion exposure, unpinned transitive dependencies, CI/CD secrets stored in environment variables, and container base images with unpatched CVEs -- are invisible to questionnaire processes because they exist at the build artifact level, not the policy level. In Vulnox assessments of vendor environments, these findings were present in organizations that had completed third-party risk reviews within the prior 12 months and received acceptable risk scores.
How does a dependency confusion attack work technically?
A dependency confusion attack exploits the resolution priority order of package managers. When a build system requests a package by name, most package managers check public registries before private ones by default, or in some configurations check both and take the higher version number. An attacker who identifies an internal package name -- through job postings, GitHub commit history, or error messages in public bug trackers -- registers a package with the same name on npm, PyPI, or RubyGems with an artificially high version number. The build system pulls the attacker-controlled package. The malicious code executes in the build environment with whatever permissions the build agent holds. The vendor sees a successful build.
How do attackers find internal package names to use in dependency confusion attacks?
Four sources dominate: GitHub repositories where developers accidentally committed package-lock.json or requirements.txt files containing internal registry URLs and package names; job postings that list specific internal tooling by name; public error logs or stack traces pasted into Stack Overflow or GitHub issues that contain internal import paths; and open-source contributions from vendor developers that reveal internal naming conventions in their commit history. Vulnox recon work on vendor environments consistently finds one or more of these sources for every medium-to-large software organization. The internal package namespace is not a secret -- it is findable in under an hour for most organizations.
What is a transitive dependency and why does it create more risk than direct dependencies?
A direct dependency is a package your code explicitly imports. A transitive dependency is a package that your dependency imports. A typical Node.js application with 50 direct dependencies has 500-800 transitive dependencies. The development team reviewed and chose the 50 direct ones. Nobody reviewed the transitive chain. When a transitive dependency is compromised -- as happened with event-stream in 2018 and colors/faker in 2022 -- the malicious code is two or three levels removed from anything the development team ever looked at. SBOM generation catches this, but only if the SBOM is being monitored against a vulnerability feed and not just generated for compliance evidence.
What CI/CD misconfigurations create the highest supply chain risk in vendor environments?
Three patterns appear most consistently in Vulnox vendor environment assessments: secrets stored as plaintext environment variables in CI/CD pipeline configuration rather than in a secrets manager, where a compromised pipeline step can read all environment variables; overly permissive pipeline service account tokens that allow artifact publishing to production registries without a separate approval step; and build cache sharing between pipelines of different trust levels, where a poisoned cache entry from a low-privilege pipeline can affect a high-privilege build. The last one is the least well-known and the hardest to detect because cache poisoning via the build system does not trigger standard code review or dependency scanning controls.
How should organizations include build pipeline security in third-party vendor assessments?
Three additions to the standard assessment process close most of the gap: request a current SBOM in SPDX or CycloneDX format and run it against a vulnerability feed rather than accepting a vendor attestation; ask specifically about CI/CD secrets management -- where secrets live, whether they are rotated, and whether pipeline logs are audited for accidental secret exposure; and request evidence of dependency pinning practice, specifically whether lock files are committed and whether renovate-style automated dependency update PRs go through code review. None of these require access to the vendor's systems. They require evidence that the vendor can produce if the practices exist.
What is SBOM weaponization and how does it affect vendor security posture?
SBOM weaponization refers to attackers using publicly available software bill of materials data to identify targets before a zero-day is disclosed. If a vendor publishes an SBOM listing their dependency versions and an attacker discovers a pre-disclosure vulnerability in one of those versions, they have a target list before any patch exists. This is not hypothetical -- coordinated disclosure timelines between researcher, vendor, and package maintainer routinely involve a window where the vulnerability is known to the researcher but the SBOM data is already public. Organizations that publish SBOMs for compliance reasons without a corresponding vulnerability monitoring and rapid patching capability are creating a searchable attack surface.
Related Articles

API security assessment: what automated tools miss and manual testing finds
Automated API security tools find the vulnerabilities they were designed to look for. The findings that matter in real assessments, broken object-level authorization, JWT algorithm confusion, and unauthenticated internal endpoints, require a tester who understands what the API is supposed to do before probing what it actually does.

CVSS score explained: what the metric captures, what it misses, and how to fix your prioritization
In 40% of Vulnox assessments, vulnerabilities scored CVSS 9.0 or higher were on systems with compensating controls that materially reduced the actual risk. The score was accurate. The priority order it implied was not. This guide covers how to use CVSS correctly and what to layer on top of it.

Post-breach vulnerability assessment: what the attacker left behind
Most post-breach assessments start too late and end too early. They confirm what was hit, not what the attacker mapped before they moved. The second breach usually comes from the reconnaissance that happened in the first.
Ready to Secure Your Digital Assets?
Get a comprehensive vulnerability assessment for your website today.