Software and Data Integrity Failures
Verify CI/CD pipelines, updates, and serialized data — never trust code or artifacts without integrity checks.
URL: trusteed.io/academy/web-security/software-and-data-integrity-failures
Software and Data Integrity Failures cover code and infrastructure that make assumptions about the integrity of software updates, critical data, or CI/CD pipelines without verifying them — including insecure deserialization, unsigned or unverified software updates, and CI/CD pipelines without adequate access control or integrity checks. This category was added in the 2021 OWASP revision partly in response to a wave of high-profile software supply chain attacks that exploited exactly this gap.
What Is This Category?
The unifying theme is trusting something — a serialized object, a software update, a build pipeline step, a third-party plugin — without verifying it hasn't been tampered with. Insecure deserialization occurs when an application deserializes untrusted data into objects without validation, potentially allowing an attacker to construct a malicious serialized payload that executes code on deserialization. Unverified software updates occur when an application or its update mechanism doesn't cryptographically verify that an update actually came from the legitimate source and hasn't been altered in transit. CI/CD pipeline integrity failures occur when a build or deployment pipeline lacks access controls, allowing an attacker who compromises a single dependency, plugin, or pipeline step to inject malicious code into every build that follows — the exact pattern behind several major supply chain compromises in recent years.
Why AI Coding Assistants Get This Wrong
Deserialization APIs (pickle.loads() in Python, unserialize() in PHP, unrestricted Java deserialization) are often the most direct, simple-looking way to reconstruct an object from stored or transmitted data, and assistants will reach for them as the natural completion of "load this saved state" without inherent awareness that deserializing untrusted data is fundamentally different from deserializing data your own application produced and controls end-to-end. Similarly, CI/CD configuration generated quickly to "get the pipeline working" often grants broader permissions and less signature verification than a security-reviewed pipeline would, because the immediate goal is a working build, not a hardened one.
Vulnerable Pattern
import pickle
# Deserializing untrusted data directly — arbitrary code execution risk
@app.route('/api/load-session', methods=['POST'])
def load_session():
data = request.get_data()
session_obj = pickle.loads(data) # attacker-controlled bytes deserialized directly
return jsonify(session_obj.to_dict())
# CI pipeline with no signature verification on a critical dependency and broad write access
- name: Install dependency
run: curl -sSL https://example.com/install.sh | bash # unverified script executed directly
- name: Deploy
run: deploy.sh # runs with full production credentials, no approval gate
Secure Pattern
import json
from itsdangerous import URLSafeTimedSerializer, BadSignature
serializer = URLSafeTimedSerializer(app.config['SECRET_KEY'])
# Use a signed, restricted serialization format instead of arbitrary object deserialization
@app.route('/api/load-session', methods=['POST'])
def load_session():
try:
# Verifies integrity via signature before any data is trusted
data = serializer.loads(request.get_data(as_text=True), max_age=3600)
except BadSignature:
return jsonify({'error': 'Invalid or tampered session data'}), 400
return jsonify(data) # plain JSON structure, never arbitrary object reconstruction
# CI pipeline with pinned, hash-verified dependencies and a required approval gate
- name: Install dependency
run: |
curl -sSL https://example.com/install.sh -o install.sh
echo "expected-sha256-hash install.sh" | sha256sum -c - # verify before executing
bash install.sh
- name: Deploy
run: deploy.sh
environment: production # requires manual approval gate configured at the environment level
Copy-Paste Rules for Cursor, Claude Code, and Codex
---
description: Software and data integrity — safe deserialization, verified updates, pipeline security
alwaysApply: true
---
# Software and Data Integrity Rules
- Never deserialize untrusted data using a general-purpose, unrestricted
deserialization API (`pickle.loads`, PHP `unserialize`, Java's default
deserialization). Use a restricted, signed format (JSON with an
integrity signature, or a schema-validated structure) instead.
- Any data that needs integrity verification (session tokens, signed
payloads, cached state) must use cryptographic signing (HMAC or
equivalent) and be verified before being trusted, not merely parsed.
- Never execute a remotely fetched script or install a dependency without
verifying its integrity (checksum, signature, or pinned, hash-locked
version) — do not pipe a downloaded script directly into a shell.
- CI/CD pipeline steps that deploy to production or handle credentials
MUST require explicit approval gates and run with the minimum necessary
permissions — never broad, standing production credentials available to
every pipeline step by default.
- Pin CI/CD action and plugin versions to specific, verified commits or
hashes rather than a mutable tag (like `@latest` or an unpinned major
version), to prevent a compromised upstream update from silently
altering pipeline behavior.
- When generating code that saves and later reconstructs application
state, default to a safe serialization format (JSON, with signature
verification if integrity matters) rather than a language's native
object serialization.
Verification Checklist
- No untrusted data is deserialized using an unrestricted, general-purpose deserialization API
- Integrity-sensitive data uses cryptographic signing, verified before use
- No remotely fetched script is executed without checksum or signature verification
- CI/CD steps with production access require explicit approval gates and least-privilege credentials
- CI/CD actions and plugins are pinned to specific, verified versions, not mutable tags
- Software update mechanisms verify update authenticity before applying them
- Continuous scanning includes supply-chain and pipeline integrity checks — see Trusteed's vulnerability scanner for dependency and configuration scanning across the build pipeline
Frequently asked questions
Why is this considered a "supply chain" issue rather than just a coding issue?
Because a significant share of real-world incidents in this category involve compromising something upstream of the application's own code — a CI/CD pipeline step, a widely used build tool, or a software update mechanism — meaning the vulnerability's blast radius extends to every application or build that trusted the compromised link, not just one codebase.
What's the difference between signing data and encrypting it?
Signing (e.g., with HMAC) proves data hasn't been tampered with and came from a party holding the signing key — it addresses integrity. Encryption protects data from being read by unauthorized parties — it addresses confidentiality. Data can need one, the other, or both depending on its sensitivity and trust requirements.
How does this relate to Unsafe Consumption of APIs (API10)?
[API10:2023](https://trusteed.io/academy/api-security/unsafe-consumption-of-apis) covers trusting third-party API response data without validation — a related but distinct trust failure focused on the API integration boundary specifically, whereas Software and Data Integrity Failures covers the broader set of trust assumptions around deserialization, updates, and build pipelines.