This weakness occurs when software accepts data without properly verifying its integrity check value—such as a checksum, hash, or digital signature. An…
This weakness occurs when software accepts data without properly verifying its integrity check value—such as a checksum, hash, or digital signature. An attacker or corrupted transmission can modify data in transit or at rest, and the application will accept it as legitimate because the integrity check is missing, weak, or not enforced. This can lead to silent data corruption, unauthorized modifications, or acceptance of malicious payloads.
02How It Happens
Integrity checks (checksums, cryptographic hashes, HMACs, or signatures) are meant to detect whether data has been altered. This weakness arises when:
- The application computes a checksum but never compares it to the received value.
- The integrity check is present but validation is skipped under certain conditions (e.g., "if the file is small, skip verification").
- A weak or non-cryptographic checksum (like CRC32) is used where a cryptographic hash is required.
- The check is performed but the result is logged or ignored rather than enforced.
- The integrity mechanism is optional or can be disabled by user input.
The root cause is a gap between *computing* an integrity value and *enforcing* it as a prerequisite for accepting data.
03Real-World Impact
Depending on context, improper integrity validation can allow:
- Silent data corruption: Files or database records are modified without detection, leading to incorrect calculations, lost transactions, or corrupted application state.
- Malware injection: Tampered software updates, plugins, or configuration files are installed and executed.
- Privilege escalation: Modified authentication tokens or session data bypass access controls.
- Supply chain attacks: Compromised packages or downloads are accepted as legitimate.
The danger is often that the compromise goes unnoticed until significant damage has occurred.
04Vulnerable & Fixed Patterns
Vulnerable pattern
import hashlib
def process_uploaded_file(file_data, provided_checksum):
# Compute checksum but never validate it
computed_checksum = hashlib.sha256(file_data).hexdigest()
# File is processed regardless of checksum match
save_to_database(file_data)
return "File accepted"
Why it's vulnerable: The checksum is computed but never compared to the provided value. An attacker can modify file_data and the application will accept it without detecting the tampering.
Fixed pattern
import hashlib
def process_uploaded_file(file_data, provided_checksum):
computed_checksum = hashlib.sha256(file_data).hexdigest()
# Validate checksum before processing
if computed_checksum != provided_checksum:
raise ValueError("Checksum mismatch: data may be corrupted or tampered")
save_to_database(file_data)
return "File accepted"
Vulnerable pattern
<?php
function verify_and_process_data($data, $provided_hash) {
$computed_hash = hash('sha256', $data);
// Hash is computed but validation is optional
if (!empty($provided_hash)) {
// Validation only happens if hash is provided
if ($computed_hash !== $provided_hash) {
error_log("Hash mismatch");
}
}
// Data is processed regardless
save_data($data);
}
?>
Why it's vulnerable: Validation is conditional and non-blocking. Even if the hash doesn't match, the data is still processed. An attacker can omit the hash or provide a mismatched one and the data will be accepted.
Fixed pattern
<?php
function verify_and_process_data($data, $provided_hash) {
$computed_hash = hash('sha256', $data);
// Validation is mandatory and enforced
if ($computed_hash !== $provided_hash) {
throw new Exception("Integrity check failed: data rejected");
}
save_data($data);
}
?>
05Prevention Checklist
Always compute and compare: For any data that must not be tampered with (downloads, uploads, configuration, backups), compute the integrity check and enforce a match before accepting the data.
Use cryptographic hashes: Use SHA-256, SHA-3, or BLAKE2 for integrity checks. Avoid weak checksums like CRC32 or simple sums for security-critical data.
Make validation mandatory: Never make integrity checks optional or conditional on user input. Reject data that fails validation, don't log and continue.
Validate at every boundary: Check integrity when data is received, loaded from storage, or passed between components.
Use HMAC or signatures for authenticity: If you need to verify both integrity *and* origin, use HMAC (with a shared secret) or digital signatures (with public-key cryptography).
Document and test: Clearly document which data requires integrity checks and test that validation actually blocks tampered data.
06Signs You May Already Be Affected
- Unexpected changes to files, database records, or configuration without corresponding audit logs.
- Corrupted or malformed data appearing in production without obvious cause.
- Users reporting that downloaded files or updates behave unexpectedly or contain unfamiliar code.
- Integrity checks present in code but never actually enforced (validation code exists but is unreachable or ignored).