OWASP Top 10Long read

Software and Data Integrity Failures in CI/CD Pipelines

One compromised credential can traverse the entire pipeline without verification.

· 10 min read
Cover illustration for “Software and Data Integrity Failures in CI/CD Pipelines”
OWASP Top 10 · October 11, 2026 · 10 min read · 2,355 words

A CI/CD pipeline is the one place in a company's infrastructure where a single compromise turns into trusted, production-ready code automatically. That is the subject of this piece: software and data integrity failures inside CI/CD pipelines, and the misplaced trust that makes them so damaging. When code moves through a pipeline, it inherits the legitimacy of everything that pipeline already does, the testing, the signing, the deployment approval. An attacker who gets a foothold anywhere in that chain doesn't need to fight their way to production. The pipeline carries them there.

That asymmetry is what makes the pipeline the highest-value target in a modern environment, higher than a single server, higher than a single database. The payload doesn't look like an attack when it lands. It looks like a release.

Every section that follows names a specific point in the pipeline where that trust gets misplaced: a dependency pulled without checking its signature, a runner with more cloud access than its job requires, a secret sitting in a log file, a deserialization call that assumes the data it receives is clean. Each is a different mechanism, but each one works the same way. Something gets treated as safe because of where it came from, not because anyone verified what it actually is.

How OWASP A08:2025 defines the integrity failure class

OWASP gives this problem a name and a place in its Top 10: A08:2025, Software or Data Integrity Failures.

A08 sits at a different altitude than A03, Software Supply Chain Failures. A team can have a fully governed, well-documented list of approved dependencies and still fail under A08, because governance over what's approved says nothing about whether what arrives at runtime is actually what was approved.

The 2025 revision renamed the category from "Software and Data Integrity Failures" to "Software or Data Integrity Failures." One word changed, but it marks a real shift in emphasis: this category is about verification at the trust boundary, the exact point where something external meets something internal, not about the integrity of the supply chain as a whole.

Three CWEs do most of the work here. Two more round out the category: CWE-494, Download of Code Without Integrity Check, which covers auto-updates and dependency fetches that skip signature validation, and CWE-345, Insufficient Verification of Data Authenticity, which is the root condition producing most of the others.

Every one of those CWEs describes the same underlying gap. Something arrives, from a dependency, a request, an update server, and the system accepts it without asking where it actually came from or whether it changed along the way. That is the technical shape of misplaced trust, and it's the thread connecting everything in this article.

The kill chain: how a single developer credential becomes full infrastructure access

Tracing how an actual breach moves makes these abstract categories concrete. CI/CD audits from 2025 and 2026 describe a kill chain that starts small and ends with full infrastructure access, and every hop in it depends on the next system trusting the one before it.

The chain usually begins when phishing targets a developer, so an attacker harvests credentials and MFA codes directly. A Personal Access Token issued months earlier can remain valid long after the account that created it has been shut off everywhere else.

From there, the attacker moves into the CI/CD environment itself, and that access tends to include artifact management credentials, tokens for systems like Nexus, which store and distribute the build artifacts that every downstream system treats as trusted. Control of the artifact store turns the compromise into a distribution mechanism. So instead of attacking each system on its own, the attacker lets the normal deployment process carry a poisoned build out to everything that consumes it.

The final stage is lateral movement into cloud infrastructure. From there they escalate privileges and plant persistence mechanisms that survive the original credential being rotated.

Not one of these four stages requires a zero-day or a novel exploit. Each one works because a system downstream accepted what the system upstream handed it, and never checked it. A developer identity trusted by the identity provider, a token trusted by the repository platform, an artifact trusted by the package registry, a cloud role trusted by the runner. So the kill chain is just misplaced trust, repeated four times in a row.

Diagram: The CI/CD Kill Chain: Four Hops From Stolen Credential to Full Infrastructure Access. Visualizes: Show a four-stage linear kill chain that traces how a single developer credential becomes full infrastructure access.

Compromised third-party dependencies: when the package registry is the attack vector

The dependency layer is the first specific failure mode, because it's where the kill chain most often begins and because the blast radius is the widest of any failure type in this article. An application that pulls in open-source libraries without checking signatures, pinning versions, or watching for tampering is extending trust to an ecosystem it has no control over.

A Unit 42 reported campaign shows how far this reaches. Between late February and March 2026, a threat actor designated TeamPCP compromised widely trusted open-source security tools and AI tools, including the vulnerability scanners Trivy and KICS, the AI gateway LiteLLM, and the Telnyx Python SDK, the official SDK for Telnyx's communications platform. The detail that matters most here is what kind of software got targeted. Security scanning tools and AI infrastructure are exactly the components teams are least likely to question, because their entire function is to be trusted by default.

Transitive dependencies compound this risk. Dependency confusion attacks exploit a specific version of this blind spot: an attacker registers a public package under the same name as a private internal one, gives it a higher version number, and lets the package manager's default behavior, checking public registries first, pull the malicious version in automatically.

OWASP's prevention guidance for this failure mode is direct. Validate digital signatures or checksums before consuming any package. Pin dependency versions explicitly and lock the lockfile into version control, so an unexpected update can't slip in unnoticed. For higher-risk environments, host an internal vetted repository and pull packages from it. And maintain a software bill of materials, so the dependency graph is something the team can see.

Insecure CI/CD pipeline configuration: how excessive permissions and weak access controls become the attack path

Dependencies are the external supply chain. The pipeline's own configuration is the internal one, and it's usually weaker. CI/CD audits from 2025 and 2026 found that leaked credentials, misconfigured runners, insecure artifact stores, and overly permissive cloud roles form a chain attackers can walk end to end, and none of it requires a novel exploit. It requires only the permissions teams already granted, often years earlier, for the sake of moving fast.

The runner is the point where this becomes dangerous. Attach broad cloud credentials to that runner for convenience, and any code that runs on it, legitimate or not, inherits access to production systems, secrets stores, and deployment targets.

GitHub Actions workflows show how low the skill bar actually is. Adding a single step to a workflow file that sends environment variables, which commonly hold database credentials, API keys, and cloud credentials, to an attacker-controlled server requires no exploit. It passes through every normal deployment gate as though it were a legitimate build step, because as far as the pipeline is concerned, it is one.

Infrastructure-as-code makes the damage persistent. It propagates the same compromise into staging and disaster recovery, so the attacker gets copies of their access seeded everywhere the template gets applied.

Fixing this starts with treating the pipeline itself as something that needs integrity controls, not just the code flowing through it, which is OWASP's own framing. And monitoring should watch for the specific anomalies that mark a compromise: deployments at unusual times, new PAT creation, the kind of activity a legitimate workflow rarely produces.

Hardcoded secrets and unprotected artifact repositories: the credentials that turn a code read into a production write

Two failure modes tend to travel together, and they're usually what converts early-stage access into the kind of high-privilege persistence the kill chain depends on: hardcoded secrets and unprotected artifact repositories.

A hardcoded credential sitting in source code or a CI log is a direct bridge to whatever system that credential unlocks. No exploitation step is needed, just authentication with material that was never supposed to be visible.

The scale at which this gets harvested is documented. The GhostAction campaign, detected by GitGuardian on September 5, 2025, reportedly compromised 327 GitHub user accounts and injected malicious workflows across 817 repositories, exfiltrating 3,325 secrets, including PyPI, npm, and DockerHub tokens. That figure shows you secrets exposure isn't a rare accident caught by chance. Automated campaigns built for exactly this purpose scan for it and harvest it at scale, continuously.

Unprotected artifact repositories extend the same problem downstream. Teams then pull that artifact believing it's a trusted release and deploy it, and the compromise spreads to every consumer of that artifact without anyone making a mistake at the point of deployment.

These two failures map directly onto stages 3 and 4 of the kill chain you saw earlier. An unprotected artifact store is how that access turns into a poisoned build that moves laterally into production.

Secrets scanning belongs in the pipeline as a gate, so it catches committed secrets at push time rather than during a periodic audit, by which point the secret has likely already propagated. Internal artifact repositories need access controls and checksum verification, the same as any other trust boundary.

Insecure deserialization and unsigned updates: integrity failures inside the application layer

Pipeline configuration and dependency management cover infrastructure.

OWASP's own example makes the mechanism concrete. Gadget chains, like those built from Commons Collections, chain together classes already present in the application's own classpath, triggering execution the application never intended but technically made possible.

This belongs in the same category as pipeline integrity failures for a specific reason. Assuming internal microservice traffic is safe because it originates inside the network is structurally the same mistake as assuming a CI artifact is clean because it came from the usual build process. Both treat origin as a stand-in for verification, so neither one checks what arrived. PHP's unserialize() with magic methods, Python's pickle.loads(),.NET's BinaryFormatter, and equivalent mechanisms in Ruby all carry the same risk.

Unsigned updates are the distribution-layer version of the same failure. An auto-update mechanism that skips cryptographic signature validation lets an attacker swap a legitimate package for a trojanized one, turning routine patching into a malware delivery channel. If a device has no remediation path besides waiting for a future update, a compromised version can persist on it indefinitely.

CDN script inclusion carries a quieter version of the same gap. A compromised CDN, or a DNS-level attack redirecting the request, can serve a modified script that runs a keylogger or credential stealer in every visiting user's browser, with nothing on the application side signaling that anything changed.

OWASP's guidance here is direct: never accept unsigned or unencrypted serialized data from untrusted clients without an integrity check or digital signature to catch tampering. Add SRI hashes to every externally loaded script so the browser can catch tampering the moment it happens.

Why point-in-time assessment cannot keep pace with a continuously changing pipeline

Every failure mode covered so far gets introduced through the ordinary mechanics of software development: a dependency update, a pipeline config change, an IaC commit, a credential rotation.

Compliance testing runs into this directly. Testing programs built to satisfy an audit scope their depth and frequency to the minimum the audit requires, and that minimum routinely excludes the pipeline-level and supply chain checks that most integrity failures actually need.

The mismatch comes down to speed. A testing cadence measured in months has no chance of catching something that moves that fast.

Verification across the full pipeline, end to end

Treating the pipeline as a trust boundary rather than an internal safe zone means putting verification at every point where unverified input enters, not just at the edge of the application.

At the identity layer, phishing-resistant MFA, FIDO2 keys or certificate-based authentication, should cover every developer identity, since token hijacking and session theft bypass weaker MFA methods. Access recertification should happen on a regular schedule, with immediate revocation across every system, repository platforms included, the moment an account is offboarded.

At the dependency and artifact layer, every dependency and artifact needs a verified signature or checksum before use. Versions should be pinned and lockfile changes reviewed the same way code changes are reviewed. High-risk dependencies belong in a vetted internal repository.

At the pipeline configuration layer, files like GitHub Actions YAML, gitlab-ci.yml, and Jenkinsfile deserve the same security scrutiny as application code, with review required on every branch, not only the protected ones. Short-lived workload identity tokens should replace long-lived static secrets wherever the infrastructure allows it, and anomalous runner behavior, unexpected secret access, unusual deployment timing, new PAT creation, should trigger an alert.

The structural shift is moving security checks out of periodic audits and into every build. Secrets scanning works the same way as a pipeline gate rather than a scheduled scan, and pull-request scanning that flags dependency changes, IaC modifications, and pipeline configuration edits gives a security reviewer a chance to catch the problem before it merges, not after it ships.

Evaluating whether your pipeline's integrity controls are working

Describing these controls and actually having them are different things.

A real assessment of pipeline integrity attempts to exploit the pipeline, not just review its configuration on paper. An unverified maybe has no place informing a remediation decision or sitting in front of an auditor.

A few questions separate a meaningful assessment from a surface-level one. Pipeline controls change with every deployment, so a retest after remediation confirms a control actually holds in the pipeline's current state, not the state it was in when the finding was first written up.

A few signs point to a superficial assessment. And a report with no attack chain documentation, individual findings scattered as isolated tickets instead of mapped out as a path to production, misses the entire point of testing a pipeline in the first place: showing how a single compromised credential actually gets to full infrastructure access, and where along that path it could have been stopped.

Sources

  1. A08 Software or Data Integrity Failures - OWASP Top 10:2025
  2. Enhancing Software Supply Chain Security Through STRIDE-Based Threat Modelling of CI/CD Pipelines
  3. A Systematic Literature Review on Continuous Integration and Deployment (CI/CD) for Secure Cloud Computing
Filed underOWASP Top 10

More in OWASP Top 10