Improper Validation of Integrity Check Value

Description

Improper Validation of Integrity Check Value is a vulnerability that occurs when a product fails to validate or incorrectly validates integrity check values such as checksums, hashes, or message authentication codes (MACs) in received data. While the data may include integrity check values, the receiving application either skips the verification step, performs the verification incorrectly, uses weak algorithms susceptible to collision attacks, or ignores verification failures. This differs from missing integrity support (CWE-353) because the protocol or format includes integrity mechanisms, but the implementation fails to use them properly. Improper verification of the calculated checksum against the received checksum can enable attackers to inject malicious data, corrupt application state, or distribute malware through seemingly legitimate channels.

Risk

Improper integrity validation allows corrupted or maliciously modified data to be processed as if it were valid, creating severe security risks across multiple attack vectors. Attackers can modify checksummed data knowing the receiving application won't properly verify the checksum, enabling man-in-the-middle attacks, supply chain compromises, and malware distribution. File formats with integrity fields that aren't properly checked allow malicious modifications to go undetected. The risk is particularly severe because the presence of checksum fields creates a false sense of security while providing no actual protection. In software distribution scenarios, malicious actors can alter programs before they reach end-users while maintaining valid-appearing checksums, especially when weak algorithms like MD5 are used. The 2012 Flame malware demonstrated how nation-state actors could exploit MD5 collision vulnerabilities to forge Microsoft certificates and distribute malware through Windows Update. Additionally, human factors compound the risk—studies show more than one-third of users fail to detect checksum mismatches even when explicitly asked to verify them.

Solution

Implement proper integrity check validation exactly as specified by the protocol or format specification. Compute the expected checksum and compare it against the received value using constant-time comparison functions to prevent timing attacks. Reject data immediately when integrity checks fail—never proceed with processing despite verification failures. Use cryptographically strong hash algorithms such as SHA-256 or SHA-3 instead of deprecated algorithms like MD5 or SHA-1 that are vulnerable to collision attacks. For critical applications, combine checksums with digital signatures to provide both integrity and authenticity verification. Implement file integrity monitoring (FIM) solutions that continuously validate critical files against known good baselines. In software distribution pipelines, validate code provenance at every stage rather than only signing at the end of the build process. Consider implementing certificate pinning and secure update channels with multiple layers of verification for software updates.

Common Consequences

ImpactDetails
IntegrityScope: Integrity, Other

Modify Application Data - Skipping or improperly performing integrity checks enables injection of malicious data from invalid sources. Attackers can alter transmitted data while recalculating weak checksums to match, making detection nearly impossible.
IntegrityScope: Integrity, Other

Data Corruption - Parsed and used data may be corrupted without proper verification, leading to application malfunction, crashes, or exploitation of downstream vulnerabilities.
Non-RepudiationScope: Non-Repudiation, Other

Hide Activities - Without proper integrity verification, it becomes impossible to determine if data was altered after transmission, eliminating audit trails and enabling attackers to cover their tracks.

Example Code

Vulnerable Code

#include <stdio.h>
#include <string.h>
#include <stdint.h>

// VULNERABLE: Checksum calculated but never verified
typedef struct {
    uint32_t checksum;
    uint32_t length;
    char data[1024];
} Message;

int process_message_no_verification(Message *msg) {
    // VULNERABLE: Checksum field exists but is completely ignored
    // Attacker can modify data without detection
    printf("Processing: %s\n", msg->data);
    return execute_command(msg->data);  // Dangerous!
}

// VULNERABLE: Verification failure is ignored
int process_message_ignore_failure(Message *msg) {
    uint32_t calculated = calculate_crc32(msg->data, msg->length);

    if (calculated != msg->checksum) {
        // VULNERABLE: Only logs warning, continues processing anyway
        printf("Warning: Checksum mismatch (expected %08x, got %08x)\n",
               msg->checksum, calculated);
    }

    // VULNERABLE: Processes potentially corrupted/malicious data
    return execute_command(msg->data);
}

// VULNERABLE: Using weak MD5 algorithm susceptible to collision attacks
int verify_download_md5(const char *file_path, const char *expected_md5) {
    char calculated_md5[33];
    calculate_md5_hash(file_path, calculated_md5);

    // VULNERABLE: MD5 is cryptographically broken
    // Attackers can create files with same MD5 but different content
    if (strcmp(calculated_md5, expected_md5) == 0) {
        return install_software(file_path);  // Could be malware!
    }
    return -1;
}

Fixed Code

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>

typedef struct {
    unsigned char checksum[32];  // SHA-256
    uint32_t length;
    char data[1024];
} SecureMessage;

// FIXED: Proper validation with strong algorithm and constant-time comparison
int process_message_secure(SecureMessage *msg) {
    unsigned char calculated[32];

    // FIXED: Use strong cryptographic hash (SHA-256)
    SHA256((unsigned char*)msg->data, msg->length, calculated);

    // FIXED: Use constant-time comparison to prevent timing attacks
    if (CRYPTO_memcmp(calculated, msg->checksum, 32) != 0) {
        // FIXED: Reject and log the failure - do NOT process
        log_security_event("Integrity check failed - message rejected");
        return -1;
    }

    // Only process after successful verification
    return execute_command(msg->data);
}

// FIXED: Proper software verification with SHA-256 and signature
int verify_download_secure(const char *file_path,
                           const char *expected_sha256,
                           const char *signature,
                           EVP_PKEY *public_key) {
    unsigned char calculated_hash[32];
    unsigned char hash_hex[65];

    // FIXED: Use SHA-256 instead of MD5
    if (calculate_sha256_file(file_path, calculated_hash) != 0) {
        return -1;
    }

    // Convert to hex for comparison
    for (int i = 0; i < 32; i++) {
        sprintf((char*)&hash_hex[i*2], "%02x", calculated_hash[i]);
    }
    hash_hex[64] = '\0';

    // FIXED: Constant-time comparison
    if (CRYPTO_memcmp(hash_hex, expected_sha256, 64) != 0) {
        log_security_event("SHA-256 verification failed");
        return -1;
    }

    // FIXED: Additionally verify digital signature for authenticity
    if (!verify_signature(file_path, signature, public_key)) {
        log_security_event("Signature verification failed");
        return -1;
    }

    // Both integrity and authenticity verified
    return install_software(file_path);
}

The vulnerable code demonstrates three common mistakes: ignoring checksums entirely, logging failures but continuing execution, and using cryptographically broken algorithms like MD5. The fixed code uses SHA-256 for strong integrity checking, employs constant-time comparison to prevent timing side-channel attacks, and combines hash verification with digital signatures for defense in depth.


Exploited in the Wild

Flame Malware MD5 Collision Attack (Microsoft/Middle East, 2012)

The Flame malware, discovered in 2012, represents the first known real-world exploitation of MD5 collision vulnerabilities for malware distribution. Nation-state attackers forged a Microsoft code-signing certificate by exploiting the weak MD5 hash algorithm used by Microsoft's Terminal Server Licensing Service. The attackers used a previously unknown MD5 chosen-prefix collision attack to create a fraudulent certificate that appeared to originate from Microsoft. This forged certificate was then used to sign malware components, which were distributed via a man-in-the-middle attack against Windows Update. The attack was described as requiring "world-class cryptanalysis" and affected computers primarily in Middle Eastern countries for cyber espionage purposes.

SolarWinds Supply Chain Attack (SolarWinds/US Government, 2020)

The SolarWinds SUNBURST attack compromised software integrity verification by injecting malicious code directly into the build pipeline before final signing. Russian nation-state attackers gained access to SolarWinds' development environment and inserted the SUNBURST backdoor into the Orion platform source code. Because the malicious code was introduced before the build process completed, the final signed DLLs appeared legitimate since they were digitally signed by SolarWinds' valid certificate. This attack demonstrated that end-of-pipeline signing is insufficient—integrity must be validated throughout the entire development and distribution process. The attack affected approximately 18,000 organizations including US government agencies, with estimated costs of $12 million per impacted company.


Tools to test/exploit

  • hashcat — Advanced password recovery and hash cracking tool that can demonstrate weaknesses in various hash algorithms and test collision resistance.

  • HashClash — Framework for MD5 and SHA-1 differential collision attacks, demonstrating practical exploitation of weak integrity algorithms.

  • OSSEC — Open-source file integrity monitoring (FIM) tool that detects unauthorized changes to files by comparing checksums against known baselines.


CVE Examples

  • CVE-2012-0158 — Microsoft Office vulnerability where integrity checks were bypassed, enabling arbitrary code execution through malformed documents.

  • CVE-2019-9169 — GNU C Library heap-based buffer overflow where improper validation of input integrity enabled memory corruption.

  • CVE-2020-14882 — Oracle WebLogic Server authentication bypass where integrity validation of session tokens was improperly implemented.


References

  1. MITRE Corporation. "CWE-354: Improper Validation of Integrity Check Value." https://cwe.mitre.org/data/definitions/354.html

  2. Microsoft Security Response Center. "Flame malware collision attack explained." June 2012. https://www.microsoft.com/en-us/msrc/blog/2012/06/flame-malware-collision-attack-explained

  3. NIST NCCoE. "Data Integrity: Detecting and Responding to Ransomware and Other Destructive Events." https://www.nccoe.nist.gov/data-integrity-detecting-and-responding-ransomware-and-other-destructive-events

  4. OWASP. "Software and Data Integrity Failures." https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/