Articles / Software and Data Integrity Failures: Trusting the Untrusted
OWASP A08 · Software and Data Integrity Failures

Software and Data Integrity Failures: Trusting the Untrusted

Software and Data Integrity Failures is one of the two entirely new categories in the 2021 Top 10, and it is the one the era of supply-chain attacks made unavoidable. It covers a single failure with many faces: assuming integrity without verifying it — trusting an update, a dependency, a serialised object, or a CI/CD pipeline that was never checked for tampering. It absorbed the older "Insecure Deserialization" category as one instance of the broader theme.

Integrity means being able to prove that code or data is what it claims to be and has not been altered by an unauthorised party. These failures occur when an application makes decisions based on unverified sources: it pulls a library from a repository without checking a signature, applies an auto-update without validating it, or deserialises attacker-controlled data into live objects. In each case the system trusts something it has no basis to trust.

The supply-chain dimension

tampersfetchedrunsAttacker moves upstreamDependency / update /objectunverifiedPulled & trustedno signature / hash checkYour app executes itIntegrity assumed,never verifiedDeserialisesuntrusted bytes →RCE
Compromise something the target trusts, and its own trust carries the payload in.

The most consequential form is the compromised build or update pipeline. If an attacker can insert malicious code into a component before it is signed and distributed, every downstream consumer receives it as legitimate, signed software. The SolarWinds compromise disclosed in December 2020 was the archetype: attackers subverted the build process so that a trojanised update shipped through the vendor's own trusted channel to thousands of customers. The lesson OWASP drew is that trust in a pipeline is only as strong as the integrity checks around it.

Insecure deserialization

The narrower, older failure is insecure deserialization: turning attacker-controlled bytes back into objects without validation. Depending on the language and libraries, a crafted serialised payload can manipulate application logic, escalate privileges, or achieve remote code execution during the deserialization itself — before your code ever inspects the result.

Deserialising untrusted input into live objectsobj = deserialize(request.body) # attacker-controlled bytes
# crafted payload runs code during reconstruction, before any validation
Why it's new: A08 exists because attackers moved upstream. Rather than breaching a hardened target directly, they compromise something it trusts — a dependency, an update, a pipeline — and let the target's own trust carry the payload in.

Verifying before you trust

  • Verify signatures on code and updates. Use digital signatures to confirm libraries and updates come from the expected source and are unaltered before they run.
  • Pin and verify dependencies. Lock versions, check hashes, and pull only from trusted repositories to prevent silent substitution.
  • Secure the CI/CD pipeline as a production system. Restrict who can change build steps, protect signing keys, and review pipeline configuration like the sensitive code it is.
  • Avoid deserialising untrusted data. Where you must, use formats without code-execution semantics, enforce strict type allow-lists, and validate before acting.
  • Protect data integrity in transit and storage with signatures or authenticated encryption so tampering is detectable.

This category asks an uncomfortable question of every automated trust relationship: how do you know? Modern software runs on a web of implicit trust — in registries, mirrors, pipelines, and vendors — and each link is a place an attacker would rather compromise than confront your defences head-on. Mapping those trust relationships, and knowing which you have actually verified, is the discovery work A08 forces into the open.

Test for it — in practice
  • Look at how your CI/CD pulls dependencies and build steps. If anything is fetched over an unpinned URL or without a checksum, an attacker upstream can change what you ship.
  • Check whether auto-updates or plugins verify a signature before running. Unsigned code that updates itself is a supply-chain compromise waiting to happen.

The full, at-scale version — verifying signing, pinning and provenance across the whole build and update pipeline the way a supply-chain attacker probes it — is what our assessment (and SecStudio agents) runs for you.

Keep reading
Security Logging and Monitoring Failures: The Breach You Never Saw