Unsachgemäße Durchsetzung der Nachrichtenintegrität während der Übertragung in einem Kommunikationskanal

Beschreibung

Unsachgemäße Durchsetzung der Nachrichtenintegrität während der Übertragung tritt auf, wenn ein Produkt einen Kommunikationskanal mit einem Endpunkt aufbaut und Nachrichten von diesem Endpunkt empfängt, aber nicht ausreichend sicherstellt, dass Nachrichten während der Übertragung nicht modifiziert wurden. Ohne ordnungsgemäße Integritätsprüfmechanismen können Angreifer, die auf den Netzwerkpfad zwischen kommunizierenden Parteien zugreifen können, Nachrichteninhalte ohne Erkennung modifizieren. Dies umfasst das Ändern von Datenwerten, das Einschleusen bösartiger Inhalte, das Wiedereinspielen alter Nachrichten oder das vollständige Ersetzen von Nachrichten.

Risiko

Diese Schwachstelle ermöglicht verschiedene Man-in-the-Middle-Angriffsszenarien. Angreifer können Finanztransaktionen modifizieren, um Beträge oder Ziele zu ändern. Befehls- und Kontrollnachrichten können verändert werden, um andere Operationen auszuführen. Software-Update-Mechanismen können kompromittiert werden, um bösartige Payloads zu liefern. Konfigurationsdaten können geändert werden, um Sicherheitseinstellungen zu schwächen. Authentifizierungs-Tokens oder Session-Daten können für Privilegieneskalation modifiziert werden. Das Risiko ist besonders schwerwiegend bei Protokollen, die sensible oder sicherheitskritische Informationen übertragen, da Modifikationen unbemerkt bleiben können, bis erheblicher Schäden entstanden ist.

Lösung

Implementieren Sie kryptographische Nachrichtenintegritätsprüfung mit HMACs (Hash-based Message Authentication Codes) oder digitalen Signaturen. Verwenden Sie authentifizierte Verschlüsselungsmodi (GCM, CCM), die sowohl Vertraulichkeit als auch Integrität bieten. Setzen Sie TLS/HTTPS für Transportsicherheit ein, das eingebaute Integritätsprüfungen bietet. Fügen Sie Sequenznummern oder Zeitstempel hinzu, um Replay-Angriffe zu verhindern. Überprüfen Sie die Nachrichtenintegrität, bevor Sie Nachrichteninhalte verarbeiten. Für signierte Nachrichten validieren Sie Signaturen mit vertrauenswürdigen öffentlichen Schlüsseln. Erwägen Sie die Verwendung etablierter Protokolle (TLS, SSH) anstelle der Implementierung benutzerdefinierter Integritätsmechanismen.

Häufige Auswirkungen

AuswirkungDetails
IntegritätBereich: Integrität

Anwendungsdaten modifizieren - Angreifer können Nachrichteninhalte während der Übertragung ohne Erkennung modifizieren.
Integrität, VertraulichkeitBereich: Integrität, Vertraulichkeit

Privilegien erlangen oder Identität annehmen - Wenn Angreifer Endpunkte fälschen oder Nachrichten modifizieren können, können sie Privilegien erlangen, die für legitime Parteien bestimmt sind.

Beispielcode

Anfälliger Code

# Anfällig: Keine Nachrichtenintegritätsprüfung
import socket
import json

class VulnerableClient:

    def __init__(self, host, port):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect((host, port))

    def send_command(self, command, amount):
        # Anfällig: Kein Integritätsschutz
        message = json.dumps({
            'command': command,
            'amount': amount
        })
        self.sock.send(message.encode())

    def receive_response(self):
        # Anfällig: Keine Verifizierung, dass Antwort nicht modifiziert wurde
        data = self.sock.recv(4096)
        return json.loads(data.decode())

# Angreifer im Netzwerk kann "transfer 100" zu "transfer 100000" ändern
// Anfällig: Benutzerdefiniertes Protokoll ohne Nachrichtenauthentifizierung
public class VulnerableProtocol {

    public void sendMessage(OutputStream out, String command, Map<String, String> params)
            throws IOException {

        // Anfällig: Keine Integritätsprüfung
        StringBuilder message = new StringBuilder();
        message.append(command).append("|");

        for (Map.Entry<String, String> entry : params.entrySet()) {
            message.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }

        out.write(message.toString().getBytes());
        out.flush();

        // Angreifer kann Nachrichteninhalt während der Übertragung modifizieren
    }

    public Map<String, String> receiveMessage(InputStream in) throws IOException {
        byte[] buffer = new byte[4096];
        int bytesRead = in.read(buffer);

        // Anfällig: Empfangenen Daten ohne Verifizierung vertrauen
        String message = new String(buffer, 0, bytesRead);
        return parseMessage(message);
    }
}
# Anfällig: Software-Update ohne Verifizierung
import urllib.request

class VulnerableUpdater:

    def download_update(self, url):
        # Anfällig: Keine Verifizierung der Update-Integrität
        response = urllib.request.urlopen(url)
        update_data = response.read()

        # Angreifer könnte bösartiges Update liefern
        self.install_update(update_data)

    def install_update(self, data):
        # Potenziell modifiziertes/bösartiges Update installieren
        with open('/opt/myapp/update.bin', 'wb') as f:
            f.write(data)
        # Update ausführen...

Korrigierter Code

# Korrigiert: Nachrichtenintegrität mit HMAC
import socket
import json
import hmac
import hashlib
import os
import time

class FixedClient:

    def __init__(self, host, port, shared_secret):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect((host, port))
        self.secret = shared_secret.encode()
        self.sequence = 0

    def send_command(self, command, amount):
        self.sequence += 1

        message = json.dumps({
            'command': command,
            'amount': amount,
            'sequence': self.sequence,
            'timestamp': time.time()
        })

        # Korrigiert: HMAC für Integrität berechnen
        mac = hmac.new(self.secret, message.encode(), hashlib.sha256)
        signature = mac.hexdigest()

        # Nachricht mit Signatur senden
        packet = json.dumps({
            'message': message,
            'signature': signature
        })
        self.sock.send(packet.encode())

    def receive_response(self):
        data = self.sock.recv(4096)
        packet = json.loads(data.decode())

        message = packet['message']
        received_signature = packet['signature']

        # Korrigiert: HMAC überprüfen, bevor Daten vertraut werden
        expected_mac = hmac.new(self.secret, message.encode(), hashlib.sha256)
        expected_signature = expected_mac.hexdigest()

        if not hmac.compare_digest(received_signature, expected_signature):
            raise SecurityError("Nachrichtenintegritätsprüfung fehlgeschlagen!")

        return json.loads(message)
// Korrigiert: Nachrichtenauthentifizierung mit digitalen Signaturen
import java.security.*;
import javax.crypto.*;

public class FixedProtocol {

    private PrivateKey signingKey;
    private PublicKey verifyKey;

    public FixedProtocol(PrivateKey signingKey, PublicKey verifyKey) {
        this.signingKey = signingKey;
        this.verifyKey = verifyKey;
    }

    public void sendMessage(OutputStream out, String command, Map<String, String> params)
            throws Exception {

        StringBuilder message = new StringBuilder();
        message.append(command).append("|");
        message.append(System.currentTimeMillis()).append("|");

        for (Map.Entry<String, String> entry : params.entrySet()) {
            message.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }

        byte[] messageBytes = message.toString().getBytes("UTF-8");

        // Korrigiert: Nachricht signieren
        Signature sig = Signature.getInstance("SHA256withRSA");
        sig.initSign(signingKey);
        sig.update(messageBytes);
        byte[] signature = sig.sign();

        // Länge + Nachricht + Signatur senden
        DataOutputStream dos = new DataOutputStream(out);
        dos.writeInt(messageBytes.length);
        dos.write(messageBytes);
        dos.writeInt(signature.length);
        dos.write(signature);
        dos.flush();
    }

    public Map<String, String> receiveMessage(InputStream in) throws Exception {
        DataInputStream dis = new DataInputStream(in);

        int msgLength = dis.readInt();
        byte[] messageBytes = new byte[msgLength];
        dis.readFully(messageBytes);

        int sigLength = dis.readInt();
        byte[] signature = new byte[sigLength];
        dis.readFully(signature);

        // Korrigiert: Signatur verifizieren, bevor Daten vertraut werden
        Signature sig = Signature.getInstance("SHA256withRSA");
        sig.initVerify(verifyKey);
        sig.update(messageBytes);

        if (!sig.verify(signature)) {
            throw new SecurityException("Nachrichtensignaturverifizierung fehlgeschlagen!");
        }

        return parseMessage(new String(messageBytes, "UTF-8"));
    }
}
# Korrigiert: Software-Update mit kryptographischer Verifizierung
import urllib.request
import hashlib
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding

class FixedUpdater:

    def __init__(self, public_key_pem):
        self.public_key = serialization.load_pem_public_key(public_key_pem)

    def download_update(self, url, signature_url, expected_hash):
        # Update herunterladen
        response = urllib.request.urlopen(url)
        update_data = response.read()

        # Korrigiert: Hash verifizieren
        actual_hash = hashlib.sha256(update_data).hexdigest()
        if actual_hash != expected_hash:
            raise SecurityError("Update-Hash stimmt nicht überein!")

        # Signatur herunterladen
        sig_response = urllib.request.urlopen(signature_url)
        signature = sig_response.read()

        # Korrigiert: Digitale Signatur verifizieren
        try:
            self.public_key.verify(
                signature,
                update_data,
                padding.PSS(
                    mgf=padding.MGF1(hashes.SHA256()),
                    salt_length=padding.PSS.MAX_LENGTH
                ),
                hashes.SHA256()
            )
        except Exception as e:
            raise SecurityError(f"Update-Signaturverifizierung fehlgeschlagen: {e}")

        # Signatur gültig, sicher zu installieren
        self.install_update(update_data)

    def install_update(self, data):
        with open('/opt/myapp/update.bin', 'wb') as f:
            f.write(data)
        # Update ausführen...
// Korrigiert: API mit Request/Response-Signierung
const crypto = require('crypto');

class SecureApiClient {
    constructor(apiKey, secretKey) {
        this.apiKey = apiKey;
        this.secretKey = secretKey;
    }

    async makeRequest(endpoint, data) {
        const timestamp = Date.now().toString();
        const nonce = crypto.randomBytes(16).toString('hex');

        const payload = JSON.stringify({
            data,
            timestamp,
            nonce
        });

        // Korrigiert: Request signieren
        const signature = crypto
            .createHmac('sha256', this.secretKey)
            .update(payload)
            .digest('hex');

        const response = await fetch(endpoint, {
            method: 'POST',
            body: payload,
            headers: {
                'Content-Type': 'application/json',
                'X-Api-Key': this.apiKey,
                'X-Signature': signature,
                'X-Timestamp': timestamp,
                'X-Nonce': nonce
            }
        });

        const responseBody = await response.text();
        const responseSignature = response.headers.get('X-Response-Signature');

        // Korrigiert: Response-Signatur verifizieren
        const expectedSignature = crypto
            .createHmac('sha256', this.secretKey)
            .update(responseBody)
            .digest('hex');

        if (responseSignature !== expectedSignature) {
            throw new Error('Response-Integritätsverifizierung fehlgeschlagen!');
        }

        return JSON.parse(responseBody);
    }
}

Verwandte CWEs

  • CWE-345: Insufficient Verification of Data Authenticity (Eltern)
  • CWE-354: Improper Validation of Integrity Check Value (verwandt)
  • CWE-494: Download of Code Without Integrity Check (verwandt)
  • CWE-353: Missing Support for Integrity Check (verwandt)

Referenzen

  1. MITRE Corporation. "CWE-924: Improper Enforcement of Message Integrity During Transmission in a Communication Channel." https://cwe.mitre.org/data/definitions/924.html
  2. OWASP. "Cryptographic Failures." OWASP Top Ten 2021.
  3. NIST. "Guidelines for the Selection and Use of Transport Layer Security (TLS) Implementations."