Unzureichende Granularität der Zugriffskontrolle

Beschreibung

Unzureichende Granularität der Zugriffskontrolle tritt auf, wenn ein Produkt keine ausreichend feinkörnige Zugriffskontrolle implementiert, die es ermöglichen würde, verschiedene Benutzer, Prozesse oder Agenten basierend auf dem Prinzip der geringsten Rechte selektiv einzuschränken. Grob gekörnter Zugriff gewährt Alles-oder-Nichts-Berechtigungen und zwingt dazu, vollständigen Zugriff zu gewähren, obwohl nur eingeschränkter Zugriff benötigt wird. Dies verstößt gegen das Prinzip der geringsten Rechte und erweitert die Angriffsfläche.

Risiko

Grob gekörnter Zugriff schafft erhebliche Sicherheitsrisiken. Übermäßige Berechtigungen vergrößern die Angriffsfläche. Kompromittierte Komponenten haben breiteren Zugriff. Privilegieneskalation wird einfacher. Datenlecks sind wahrscheinlicher. Sicherheitsisolation ist unwirksam. Die Einhaltung des Prinzips der geringsten Rechte ist unmöglich. Laterale Bewegung nach einem Einbruch ist einfacher.

Lösung

Implementieren Sie Zugriffskontrolle mit ausreichender Granularität, um verschiedenen Entitäten unterschiedliche Berechtigungen zuzuweisen. Definieren Sie separate Berechtigungen für Lesen, Schreiben und Ausführen. Erstellen Sie unterschiedliche Zugriffsebenen für verschiedene Ressourcen. Implementieren Sie rollenbasierte Zugriffskontrolle mit feinkörnigen Rollen. Wenden Sie das Prinzip der geringsten Rechte konsequent an. Überprüfen und minimieren Sie regelmäßig die Berechtigungen.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Unautorisiertes Lesen - Grob gekörnter Zugriff kann mehr Daten offenlegen als notwendig.
IntegritätBereich: Integrität

Unautorisierte Modifikation - Übermäßige Schreibberechtigungen ermöglichen unbeabsichtigte Änderungen.
ZugriffskontrolleBereich: Zugriffskontrolle

Prinzip der geringsten Rechte verletzt - Entitäten haben mehr Berechtigungen als erforderlich.

Beispielcode und Lösung

Verwundbarer Code

// Verwundbar: Registerschutz ohne Bit-Level-Granularität

module vulnerable_register_access (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [3:0] register_select,
    input wire privileged_access,
    output reg [31:0] read_data
);

    // Steuerregister-Layout:
    // [0]     - Feature aktivieren (benutzerzugänglich)
    // [1]     - Debug-Modus (sollte geschützt sein!)
    // [7:2]   - Konfiguration (benutzerzugänglich)
    // [8]     - Sicherheitsumgehung (sollte geschützt sein!)
    // [15:9]  - Weitere Konfiguration (benutzerzugänglich)
    // [31:16] - Reserviert

    reg [31:0] control_register;
    reg register_locked;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            control_register <= 32'h0;
            register_locked <= 1'b0;
        end
        else if (write_enable && register_select == 4'b0001) begin
            // VERWUNDBAR: Alles-oder-nichts-Schutz
            // Entweder ist das gesamte Register beschreibbar oder nicht
            if (!register_locked) begin
                // Benutzer kann ALLE Bits beschreiben, einschließlich sicherheitskritischer
                control_register <= write_data;
            end
            // Wenn gesperrt, können KEINE Bits geschrieben werden - zu restriktiv
        end
    end

    // Keine Bit-Level-Zugriffskontrolle
    // Sensible Bits gemischt mit benutzerzugänglichen Bits

endmodule

// Verwundbar: Gemeinsames Register mit gemischten Sensitivitätsstufen
module vulnerable_mixed_register (
    input wire clk,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire user_access,
    output reg [31:0] config_register
);

    // Gemischtes Register:
    // [3:0]   - Benutzerkonfiguration
    // [4]     - Rechteeskalations-Bit (KRITISCH!)
    // [7:5]   - Benutzereinstellungen
    // [8]     - Sicherheitsprüfungen deaktivieren (KRITISCH!)
    // [31:9]  - Benutzerdaten

    always @(posedge clk) begin
        if (write_enable) begin
            // VERWUNDBAR: Keine Unterscheidung zwischen Benutzer- und kritischen Bits
            if (user_access) begin
                // Benutzer kann alles schreiben, einschließlich kritischer Sicherheitsbits!
                config_register <= write_data;
            end
        end
    end

endmodule
// Verwundbar: Firmware mit grober Zugriffskontrolle

#define CONFIG_REG_ADDR 0x40001000

// Registerbits (gemischte Sensitivität)
#define CFG_FEATURE_ENABLE   (1 << 0)   // Benutzerzugänglich
#define CFG_DEBUG_MODE       (1 << 1)   // Sollte geschützt sein!
#define CFG_USER_SETTING     (0x3F << 2) // Benutzerzugänglich
#define CFG_SECURITY_BYPASS  (1 << 8)   // Sollte geschützt sein!

// Verwundbar: Alles-oder-nichts-Sperre
bool register_locked = false;

void write_config_register(uint32_t value) {
    // VERWUNDBAR: Gesamtes Register gesperrt oder entsperrt
    // Keine Bit-Level-Granularität
    if (!register_locked) {
        *(volatile uint32_t*)CONFIG_REG_ADDR = value;
    }
}

// Benutzer kann sicherheitskritische Bits setzen!
void user_configure(uint32_t user_settings) {
    // Benutzer liefert vollen 32-Bit-Wert
    // Nichts verhindert das Setzen von CFG_SECURITY_BYPASS oder CFG_DEBUG_MODE
    write_config_register(user_settings);
}

Sichere Lösung

// Sicher: Bit-Level-Zugriffskontroll-Granularität

module secure_register_access (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [3:0] register_select,
    input wire privileged_access,
    output reg [31:0] read_data
);

    // Steuerregister mit Bit-Level-Schutz:
    // [0]     - Feature aktivieren (benutzerzugänglich)
    // [1]     - Debug-Modus (nur privilegiert)
    // [7:2]   - Konfiguration (benutzerzugänglich)
    // [8]     - Sicherheitsumgehung (nur privilegiert)
    // [15:9]  - Weitere Konfiguration (benutzerzugänglich)
    // [31:16] - Reserviert (als Null lesen)

    reg [31:0] control_register;

    // Bitmasken für Zugriffskontrolle
    localparam USER_WRITABLE_MASK = 32'h0000FEFD;  // Bits die Benutzer schreiben kann
    localparam PRIV_WRITABLE_MASK = 32'h0000FFFF;  // Bits die Privilegierte schreiben können
    localparam PROTECTED_BITS     = 32'h00000102;  // Debug-Modus + Sicherheitsumgehung

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            control_register <= 32'h0;
        end
        else if (write_enable && register_select == 4'b0001) begin
            if (privileged_access) begin
                // Privilegiert: kann alle implementierten Bits schreiben
                control_register <= (control_register & ~PRIV_WRITABLE_MASK) |
                                   (write_data & PRIV_WRITABLE_MASK);
            end else begin
                // Benutzer: kann nur nicht-geschützte Bits schreiben
                control_register <= (control_register & ~USER_WRITABLE_MASK) |
                                   (write_data & USER_WRITABLE_MASK);
                // Geschützte Bits [1] und [8] werden NICHT modifiziert
            end
        end
    end

    // Lesen gibt tatsächlichen Wert zurück (oder könnte geschützte Bits für Benutzer maskieren)
    always @(*) begin
        if (privileged_access) begin
            read_data = control_register;
        end else begin
            // Optional geschützte Bits vor unprivilegierten Lesezugriffen verbergen
            read_data = control_register & USER_WRITABLE_MASK;
        end
    end

endmodule

// Sicher: Separate Register für verschiedene Schutzstufen
module secure_separated_registers (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [3:0] register_select,
    input wire privileged_access,
    output reg [31:0] read_data
);

    // Register nach Sensitivität trennen
    reg [31:0] user_config_register;      // Adresse 0x00 - benutzerbeschreibbar
    reg [31:0] security_config_register;  // Adresse 0x04 - nur privilegiert
    reg [31:0] debug_config_register;     // Adresse 0x08 - privilegiert + Debug-Auth

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            user_config_register <= 32'h0;
            security_config_register <= 32'h0;
            debug_config_register <= 32'h0;
        end
        else if (write_enable) begin
            case (register_select)
                4'b0000: begin
                    // Benutzerkonfiguration - immer beschreibbar
                    user_config_register <= write_data;
                end
                4'b0001: begin
                    // Sicherheitskonfiguration - nur privilegiert
                    if (privileged_access) begin
                        security_config_register <= write_data;
                    end
                    // Unprivilegierte Schreibvorgänge stillschweigend ignorieren
                end
                4'b0010: begin
                    // Debug-Konfiguration - erfordert erhöhte Privilegien
                    if (privileged_access && debug_authenticated) begin
                        debug_config_register <= write_data;
                    end
                end
            endcase
        end
    end

endmodule
// Sicher: Firmware mit Bit-Level-Zugriffskontrolle

#define CONFIG_REG_ADDR 0x40001000

// Benutzerzugängliche Bits
#define CFG_FEATURE_ENABLE   (1 << 0)
#define CFG_USER_SETTING     (0x3F << 2)
#define CFG_USER_DATA        (0x7FFFFF << 9)

// Geschützte Bits (nur privilegierter Zugriff)
#define CFG_DEBUG_MODE       (1 << 1)
#define CFG_SECURITY_BYPASS  (1 << 8)

// Zugriffsmasken
#define USER_WRITABLE_MASK   (CFG_FEATURE_ENABLE | CFG_USER_SETTING | CFG_USER_DATA)
#define PROTECTED_MASK       (CFG_DEBUG_MODE | CFG_SECURITY_BYPASS)

void write_config_register_user(uint32_t value) {
    // Aktuellen Wert lesen
    uint32_t current = *(volatile uint32_t*)CONFIG_REG_ADDR;

    // Geschützte Bits beibehalten, nur benutzerbeschreibbare Bits aktualisieren
    uint32_t new_value = (current & ~USER_WRITABLE_MASK) |
                         (value & USER_WRITABLE_MASK);

    *(volatile uint32_t*)CONFIG_REG_ADDR = new_value;
}

void write_config_register_privileged(uint32_t value, bool is_privileged) {
    if (!is_privileged) {
        // Unprivilegiert: Benutzerpfad verwenden
        write_config_register_user(value);
        return;
    }

    // Privilegiert: kann alle Bits schreiben
    *(volatile uint32_t*)CONFIG_REG_ADDR = value;
}

// Sichere Benutzerkonfigurationsfunktion
void user_configure(uint32_t user_settings) {
    // Maskiert automatisch geschützte Bits aus
    write_config_register_user(user_settings);

    // Selbst wenn Benutzer versucht SECURITY_BYPASS zu setzen, funktioniert es nicht
    // Das Bit wird vor dem Schreiben ausmaskiert
}

// Validierungsfunktion
bool validate_access_control_granularity(void) {
    uint32_t original = *(volatile uint32_t*)CONFIG_REG_ADDR;

    // Versuchen geschützte Bits über Benutzerschnittstelle zu setzen
    write_config_register_user(0xFFFFFFFF);

    uint32_t after_user_write = *(volatile uint32_t*)CONFIG_REG_ADDR;

    // Verifizieren dass geschützte Bits unverändert sind
    if ((after_user_write & PROTECTED_MASK) != (original & PROTECTED_MASK)) {
        log_error("Zugriffskontroll-Granularitätsfehler!");
        return false;
    }

    // Original wiederherstellen
    *(volatile uint32_t*)CONFIG_REG_ADDR = original;
    return true;
}

Ausgenutzt in der Praxis

Cloud-Berechtigungsfehlkonfigurationen (verschiedene)

Zahlreiche Cloud-Datenlecks resultierten aus übermäßig freizügigen IAM-Richtlinien, bei denen Dienstkonten volle Admin-Berechtigungen erhielten, anstatt nur die minimalen erforderlichen Berechtigungen.


Tools zum Testen und Ausnutzen

  • Prowler — AWS-Sicherheits-Best-Practices-Assessment.

  • ScoutSuite — Multi-Cloud-Sicherheits-Auditing.


CVE-Beispiele

  • CVE-2020-8555 — Kubernetes-Berechtigung erlaubte umfassenden Netzwerkzugriff statt granularer Kontrolle.

Referenzen

  1. MITRE Corporation. "CWE-1220: Insufficient Granularity of Access Control." https://cwe.mitre.org/data/definitions/1220.html

  2. NIST SP 800-53. "Access Control Policies."

  3. OWASP. "Principle of Least Privilege."