Missing Support for Integrity Check
Description
Missing Support for Integrity Check is a vulnerability that occurs when a product employs a transmission protocol or data storage mechanism that lacks a built-in mechanism for verifying data integrity, such as a checksum, hash, or message authentication code. Without integrity verification, there is no way to determine if data has been corrupted during transmission or storage, whether accidentally through hardware failures and network errors, or maliciously through man-in-the-middle attacks and data tampering. The absence of integrity checking removes the first layer of application-level verification, following the end-to-end principle that integrity should be verified at the lowest possible level where the complete message can be examined. This weakness is particularly critical for protocols handling sensitive data, configuration files, firmware updates, or any data where undetected modification could have security implications.
Risk
Missing integrity checks allow both accidental corruption and deliberate tampering to go undetected. In network communications, attackers performing man-in-the-middle attacks can modify data in transit without detection - changing financial transaction amounts, modifying downloaded software to include malware, or altering configuration commands. Firmware and software updates without integrity verification are prime targets for supply chain attacks. Stored data without integrity protection can be silently corrupted, leading to data loss, system instability, or security bypasses. Network protocols without checksums may process corrupted packets, causing application crashes or incorrect behavior. The lack of integrity verification also means there's no non-repudiation - it's impossible to determine whether data was modified after transmission. Critical systems relying on data integrity for safety or security decisions become unreliable when integrity cannot be verified.
Solution
Implement integrity checking at the appropriate protocol layer. For network transmissions, use protocols with built-in integrity verification like TLS (which provides HMAC-based integrity) or implement application-layer message authentication codes (MACs). For data storage, compute and store cryptographic hashes (SHA-256 or stronger) alongside data and verify before use. For firmware and software updates, require cryptographic signatures that provide both integrity and authenticity. Use authenticated encryption modes like AES-GCM that combine confidentiality with integrity. Implement checksums at the packet level for protocols that need error detection without cryptographic overhead. Design protocols following the end-to-end principle with integrity verification at the application layer. Never assume lower-layer integrity (IP checksums, Ethernet CRC) provides sufficient protection for application data.
Common Consequences
| Impact | Details |
|---|---|
| Integrity | Scope: Integrity Data may become corrupted during transmission or storage without detection. Applications processing corrupted data may behave incorrectly, crash, or produce wrong results. |
| Non-Repudiation | Scope: Non-Repudiation Without integrity verification, it's impossible to determine whether data was modified after creation, undermining audit trails and accountability. |
| Availability | Scope: Availability Corrupted data processed without detection can cause application crashes, system instability, or denial of service through malformed input. |
Example Code
Vulnerable Code (Multiple Languages)
The following examples demonstrate missing integrity checks:
# Vulnerable: Network transmission without integrity check
import socket
import pickle
# Vulnerable: UDP communication without checksum
def vulnerable_send_command(host, port, command):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Vulnerable: No integrity check on transmitted data
# Attacker can modify packet in transit
data = pickle.dumps(command)
sock.sendto(data, (host, port))
# Vulnerable: TCP without application-level integrity
def vulnerable_receive_data(sock):
# Vulnerable: Relying only on TCP checksum
# TCP checksum is weak and not cryptographic
data = sock.recv(4096)
# Processing data without integrity verification
return pickle.loads(data) # Dangerous without integrity check
# Vulnerable: File storage without integrity
def vulnerable_save_config(config, filepath):
with open(filepath, 'wb') as f:
# Vulnerable: No hash stored with data
pickle.dump(config, f)
def vulnerable_load_config(filepath):
with open(filepath, 'rb') as f:
# Vulnerable: No integrity verification
# File could be corrupted or tampered
return pickle.load(f)
# Vulnerable: Firmware download without integrity
import urllib.request
def vulnerable_download_firmware(url, output_path):
# Vulnerable: Downloading without integrity verification
urllib.request.urlretrieve(url, output_path)
# Vulnerable: Using downloaded file without checksum
apply_firmware(output_path)
# Vulnerable: Database backup without integrity
def vulnerable_backup_database(db_path, backup_path):
import shutil
# Vulnerable: No checksum computed or stored
shutil.copy2(db_path, backup_path)
def vulnerable_restore_database(backup_path, db_path):
import shutil
# Vulnerable: Restoring without integrity check
# Backup could be corrupted
shutil.copy2(backup_path, db_path)
# Vulnerable: IPC without integrity check
import multiprocessing
def vulnerable_ipc_send(queue, data):
# Vulnerable: No integrity protection
queue.put(data)
def vulnerable_ipc_receive(queue):
# Vulnerable: Processing without verification
return queue.get()
// Vulnerable: Missing integrity checks in Java
import java.net.*;
import java.io.*;
public class VulnerableIntegrity {
// Vulnerable: UDP without integrity
public void vulnerableSendUDP(String host, int port, byte[] data)
throws Exception {
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName(host);
// Vulnerable: No checksum or MAC added to packet
DatagramPacket packet = new DatagramPacket(data, data.length,
address, port);
socket.send(packet);
socket.close();
}
public byte[] vulnerableReceiveUDP(int port) throws Exception {
DatagramSocket socket = new DatagramSocket(port);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
socket.close();
// Vulnerable: No integrity verification on received data
return Arrays.copyOf(packet.getData(), packet.getLength());
}
// Vulnerable: File operations without integrity
public void vulnerableSaveData(Object data, String path) throws Exception {
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(path))) {
// Vulnerable: No hash stored
oos.writeObject(data);
}
}
public Object vulnerableLoadData(String path) throws Exception {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(path))) {
// Vulnerable: No integrity check before deserializing
return ois.readObject();
}
}
// Vulnerable: HTTP download without integrity
public void vulnerableDownloadFile(String url, String outputPath)
throws Exception {
URL fileUrl = new URL(url);
try (InputStream in = fileUrl.openStream();
FileOutputStream out = new FileOutputStream(outputPath)) {
// Vulnerable: No checksum verification
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
// Vulnerable: Using file without integrity check
processDownloadedFile(outputPath);
}
// Vulnerable: Serialized object transmission
public void vulnerableSendObject(Socket socket, Serializable obj)
throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
// Vulnerable: No integrity protection
oos.writeObject(obj);
oos.flush();
}
// Vulnerable: Configuration update without integrity
public void vulnerableApplyConfig(byte[] configData) {
// Vulnerable: Applying config without verification
// Config could be corrupted or malicious
Config config = parseConfig(configData);
applyConfig(config);
}
}
// Vulnerable: Missing integrity checks in C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
// Vulnerable: UDP transmission without checksum
int vulnerable_send_udp(int sockfd, const char *data, size_t len,
struct sockaddr_in *dest) {
// Vulnerable: No integrity check added to data
return sendto(sockfd, data, len, 0,
(struct sockaddr *)dest, sizeof(*dest));
}
int vulnerable_recv_udp(int sockfd, char *buffer, size_t len) {
struct sockaddr_in sender;
socklen_t sender_len = sizeof(sender);
int received = recvfrom(sockfd, buffer, len, 0,
(struct sockaddr *)&sender, &sender_len);
// Vulnerable: Processing data without integrity check
return received;
}
// Vulnerable: File write without checksum
int vulnerable_write_data(const char *path, const void *data, size_t len) {
FILE *f = fopen(path, "wb");
if (!f) return -1;
// Vulnerable: No checksum written
fwrite(data, 1, len, f);
fclose(f);
return 0;
}
int vulnerable_read_data(const char *path, void *buffer, size_t max_len) {
FILE *f = fopen(path, "rb");
if (!f) return -1;
// Vulnerable: Reading without integrity verification
size_t read = fread(buffer, 1, max_len, f);
fclose(f);
return read;
}
// Vulnerable: Firmware update without signature
int vulnerable_apply_firmware(const char *firmware_path) {
FILE *f = fopen(firmware_path, "rb");
if (!f) return -1;
// Vulnerable: No integrity check on firmware
fseek(f, 0, SEEK_END);
size_t size = ftell(f);
fseek(f, 0, SEEK_SET);
unsigned char *firmware = malloc(size);
fread(firmware, 1, size, f);
fclose(f);
// Vulnerable: Applying potentially corrupted/malicious firmware
flash_firmware(firmware, size);
free(firmware);
return 0;
}
// Vulnerable: IPC without integrity
typedef struct {
int command;
char data[256];
// No checksum field
} ipc_message;
int vulnerable_send_ipc(int fd, ipc_message *msg) {
// Vulnerable: No integrity protection
return write(fd, msg, sizeof(*msg));
}
int vulnerable_recv_ipc(int fd, ipc_message *msg) {
// Vulnerable: No integrity verification
return read(fd, msg, sizeof(*msg));
}
Fixed Code (Multiple Languages)
# Fixed: Network transmission with integrity checks
import socket
import pickle
import hashlib
import hmac
import struct
# Fixed: UDP with HMAC integrity
def secure_send_command(host, port, command, secret_key):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data = pickle.dumps(command)
# Fixed: Compute HMAC for integrity
mac = hmac.new(secret_key, data, hashlib.sha256).digest()
# Fixed: Send data with MAC
packet = struct.pack('>I', len(data)) + mac + data
sock.sendto(packet, (host, port))
def secure_receive_command(sock, secret_key):
packet, addr = sock.recvfrom(65535)
# Fixed: Parse length, MAC, and data
length = struct.unpack('>I', packet[:4])[0]
received_mac = packet[4:36] # 32 bytes for SHA256
data = packet[36:36+length]
# Fixed: Verify MAC before processing
expected_mac = hmac.new(secret_key, data, hashlib.sha256).digest()
if not hmac.compare_digest(received_mac, expected_mac):
raise ValueError("Integrity check failed")
return pickle.loads(data)
# Fixed: File storage with hash
def secure_save_config(config, filepath):
data = pickle.dumps(config)
# Fixed: Compute and store hash
hash_value = hashlib.sha256(data).digest()
with open(filepath, 'wb') as f:
f.write(hash_value) # First 32 bytes are hash
f.write(data)
def secure_load_config(filepath):
with open(filepath, 'rb') as f:
stored_hash = f.read(32)
data = f.read()
# Fixed: Verify hash before loading
computed_hash = hashlib.sha256(data).digest()
if not hmac.compare_digest(stored_hash, computed_hash):
raise ValueError("Config file integrity check failed")
return pickle.loads(data)
# Fixed: Firmware download with checksum verification
import urllib.request
def secure_download_firmware(url, checksum_url, output_path):
# Fixed: Download expected checksum
with urllib.request.urlopen(checksum_url) as response:
expected_checksum = response.read().decode().strip()
# Download firmware
urllib.request.urlretrieve(url, output_path)
# Fixed: Verify checksum
sha256_hash = hashlib.sha256()
with open(output_path, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b''):
sha256_hash.update(chunk)
actual_checksum = sha256_hash.hexdigest()
if actual_checksum != expected_checksum:
os.remove(output_path)
raise ValueError("Firmware integrity check failed")
apply_firmware(output_path)
# Fixed: Using TLS for transport integrity
import ssl
def secure_tcp_connection(host, port):
context = ssl.create_default_context()
# Fixed: TLS provides integrity via HMAC
with socket.create_connection((host, port)) as sock:
with context.wrap_socket(sock, server_hostname=host) as ssock:
return ssock
# Fixed: Database backup with integrity
def secure_backup_database(db_path, backup_path, metadata_path):
import shutil
# Copy database
shutil.copy2(db_path, backup_path)
# Fixed: Compute and store hash
sha256_hash = hashlib.sha256()
with open(backup_path, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b''):
sha256_hash.update(chunk)
with open(metadata_path, 'w') as f:
f.write(sha256_hash.hexdigest())
def secure_restore_database(backup_path, metadata_path, db_path):
# Fixed: Verify integrity before restore
with open(metadata_path, 'r') as f:
expected_hash = f.read().strip()
sha256_hash = hashlib.sha256()
with open(backup_path, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b''):
sha256_hash.update(chunk)
if sha256_hash.hexdigest() != expected_hash:
raise ValueError("Backup integrity check failed")
import shutil
shutil.copy2(backup_path, db_path)
// Fixed: Integrity checks in Java
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.net.*;
import java.io.*;
import java.util.*;
public class SecureIntegrity {
// Fixed: UDP with HMAC
public void secureSendUDP(String host, int port, byte[] data,
SecretKey macKey) throws Exception {
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName(host);
// Fixed: Compute HMAC
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(macKey);
byte[] macValue = mac.doFinal(data);
// Fixed: Combine MAC and data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(data.length);
dos.write(macValue);
dos.write(data);
byte[] packet = baos.toByteArray();
socket.send(new DatagramPacket(packet, packet.length, address, port));
socket.close();
}
public byte[] secureReceiveUDP(int port, SecretKey macKey) throws Exception {
DatagramSocket socket = new DatagramSocket(port);
byte[] buffer = new byte[65535];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
socket.close();
ByteArrayInputStream bais = new ByteArrayInputStream(
packet.getData(), 0, packet.getLength());
DataInputStream dis = new DataInputStream(bais);
int dataLength = dis.readInt();
byte[] receivedMac = new byte[32]; // SHA256 = 32 bytes
dis.readFully(receivedMac);
byte[] data = new byte[dataLength];
dis.readFully(data);
// Fixed: Verify HMAC
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(macKey);
byte[] expectedMac = mac.doFinal(data);
if (!MessageDigest.isEqual(receivedMac, expectedMac)) {
throw new SecurityException("Integrity check failed");
}
return data;
}
// Fixed: File with hash
public void secureSaveData(Object data, String path) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(data);
}
byte[] objectData = baos.toByteArray();
// Fixed: Compute SHA-256 hash
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(objectData);
// Fixed: Write hash then data
try (FileOutputStream fos = new FileOutputStream(path)) {
fos.write(hash);
fos.write(objectData);
}
}
public Object secureLoadData(String path) throws Exception {
byte[] fileContent;
try (FileInputStream fis = new FileInputStream(path)) {
fileContent = fis.readAllBytes();
}
// Fixed: Extract hash and data
byte[] storedHash = Arrays.copyOfRange(fileContent, 0, 32);
byte[] objectData = Arrays.copyOfRange(fileContent, 32, fileContent.length);
// Fixed: Verify hash
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] computedHash = digest.digest(objectData);
if (!MessageDigest.isEqual(storedHash, computedHash)) {
throw new SecurityException("File integrity check failed");
}
try (ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(objectData))) {
return ois.readObject();
}
}
// Fixed: Download with checksum verification
public void secureDownloadFile(String url, String checksumUrl, String outputPath)
throws Exception {
// Fixed: Get expected checksum
String expectedChecksum;
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new URL(checksumUrl).openStream()))) {
expectedChecksum = reader.readLine().trim();
}
// Download file
MessageDigest digest = MessageDigest.getInstance("SHA-256");
try (InputStream in = new URL(url).openStream();
FileOutputStream out = new FileOutputStream(outputPath)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
digest.update(buffer, 0, bytesRead);
}
}
// Fixed: Verify checksum
String actualChecksum = bytesToHex(digest.digest());
if (!actualChecksum.equalsIgnoreCase(expectedChecksum)) {
new File(outputPath).delete();
throw new SecurityException("Download integrity check failed");
}
processDownloadedFile(outputPath);
}
// Fixed: TLS for transport
public Socket secureConnect(String host, int port) throws Exception {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
SSLSocketFactory factory = context.getSocketFactory();
// Fixed: TLS provides integrity
return factory.createSocket(host, port);
}
private String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
// Fixed: Integrity checks in C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
// Fixed: UDP with HMAC
typedef struct {
unsigned char mac[32]; // SHA256 HMAC
uint32_t data_len;
unsigned char data[]; // Flexible array
} secure_packet;
int secure_send_udp(int sockfd, const unsigned char *data, size_t len,
const unsigned char *key, size_t key_len,
struct sockaddr_in *dest) {
// Allocate packet with MAC
size_t packet_size = sizeof(secure_packet) + len;
secure_packet *packet = malloc(packet_size);
packet->data_len = htonl(len);
memcpy(packet->data, data, len);
// Fixed: Compute HMAC
unsigned int mac_len;
HMAC(EVP_sha256(), key, key_len, data, len, packet->mac, &mac_len);
int result = sendto(sockfd, packet, packet_size, 0,
(struct sockaddr *)dest, sizeof(*dest));
free(packet);
return result;
}
int secure_recv_udp(int sockfd, unsigned char *buffer, size_t max_len,
const unsigned char *key, size_t key_len) {
unsigned char recv_buffer[65535];
struct sockaddr_in sender;
socklen_t sender_len = sizeof(sender);
int received = recvfrom(sockfd, recv_buffer, sizeof(recv_buffer), 0,
(struct sockaddr *)&sender, &sender_len);
if (received < sizeof(secure_packet)) {
return -1;
}
secure_packet *packet = (secure_packet *)recv_buffer;
size_t data_len = ntohl(packet->data_len);
// Fixed: Verify HMAC
unsigned char expected_mac[32];
unsigned int mac_len;
HMAC(EVP_sha256(), key, key_len, packet->data, data_len,
expected_mac, &mac_len);
if (CRYPTO_memcmp(packet->mac, expected_mac, 32) != 0) {
return -1; // Integrity check failed
}
// Fixed: Data verified, safe to copy
if (data_len > max_len) {
return -1;
}
memcpy(buffer, packet->data, data_len);
return data_len;
}
// Fixed: File with SHA256 hash
int secure_write_data(const char *path, const void *data, size_t len) {
FILE *f = fopen(path, "wb");
if (!f) return -1;
// Fixed: Compute SHA256 hash
unsigned char hash[32];
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
EVP_DigestUpdate(ctx, data, len);
EVP_DigestFinal_ex(ctx, hash, NULL);
EVP_MD_CTX_free(ctx);
// Fixed: Write hash then data
fwrite(hash, 1, 32, f);
fwrite(data, 1, len, f);
fclose(f);
return 0;
}
int secure_read_data(const char *path, void *buffer, size_t max_len) {
FILE *f = fopen(path, "rb");
if (!f) return -1;
unsigned char stored_hash[32];
fread(stored_hash, 1, 32, f);
fseek(f, 0, SEEK_END);
size_t total_size = ftell(f);
size_t data_len = total_size - 32;
fseek(f, 32, SEEK_SET);
if (data_len > max_len) {
fclose(f);
return -1;
}
fread(buffer, 1, data_len, f);
fclose(f);
// Fixed: Verify hash
unsigned char computed_hash[32];
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
EVP_DigestUpdate(ctx, buffer, data_len);
EVP_DigestFinal_ex(ctx, computed_hash, NULL);
EVP_MD_CTX_free(ctx);
if (CRYPTO_memcmp(stored_hash, computed_hash, 32) != 0) {
return -1; // Integrity check failed
}
return data_len;
}
// Fixed: Firmware with signature verification
int secure_apply_firmware(const char *firmware_path, const char *sig_path,
EVP_PKEY *public_key) {
// Read firmware
FILE *f = fopen(firmware_path, "rb");
if (!f) return -1;
fseek(f, 0, SEEK_END);
size_t size = ftell(f);
fseek(f, 0, SEEK_SET);
unsigned char *firmware = malloc(size);
fread(firmware, 1, size, f);
fclose(f);
// Read signature
f = fopen(sig_path, "rb");
if (!f) {
free(firmware);
return -1;
}
fseek(f, 0, SEEK_END);
size_t sig_size = ftell(f);
fseek(f, 0, SEEK_SET);
unsigned char *signature = malloc(sig_size);
fread(signature, 1, sig_size, f);
fclose(f);
// Fixed: Verify signature
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, public_key);
EVP_DigestVerifyUpdate(ctx, firmware, size);
int verified = EVP_DigestVerifyFinal(ctx, signature, sig_size);
EVP_MD_CTX_free(ctx);
free(signature);
if (verified != 1) {
free(firmware);
return -1; // Signature verification failed
}
// Fixed: Only apply after verification
int result = flash_firmware(firmware, size);
free(firmware);
return result;
}
The fix adds cryptographic integrity verification (HMAC, SHA-256, digital signatures) before processing or using data.
Exploited in the Wild
Protocol Integrity Attacks
Various protocols without integrity checks have been exploited to modify data in transit, including unprotected HTTP traffic and UDP-based protocols.
Firmware Tampering
Systems downloading firmware updates without integrity verification have been compromised to install malicious firmware.
Tools to Test/Exploit
-
Wireshark — Analyze network traffic for integrity protection.
-
mitmproxy — Intercept and modify unprotected traffic.
-
Burp Suite — Test web application integrity checks.
CVE Examples
No specific CVEs directly reference this CWE, but the pattern appears in many vulnerabilities involving unprotected data transmission and storage.
References
-
MITRE Corporation. "CWE-353: Missing Support for Integrity Check." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/353.html
-
OWASP Foundation. "Cryptographic Failures." https://owasp.org/Top10/A02_2021-Cryptographic_Failures/
-
RFC 5246. "The Transport Layer Security (TLS) Protocol." https://tools.ietf.org/html/rfc5246