Fehlerhafte Autorisierung

Beschreibung

Fehlerhafte Autorisierung tritt auf, wenn ein Produkt eine Autorisierungsprüfung durchführt, wenn ein Akteur versucht, auf eine Ressource zuzugreifen oder eine Aktion auszuführen, aber die Prüfung fehlerhaft implementiert ist. Anders als bei CWE-862 (Fehlende Autorisierung), wo keine Prüfung existiert, beinhaltet CWE-863 eine Prüfung, die existiert aber nicht ordnungsgemäß funktioniert. Häufige Probleme umfassen: Prüfung des falschen Benutzers oder der falschen Rolle, Verwendung falscher Vergleichslogik, Nichtberücksichtigung von Grenzfällen, Race Conditions bei Autorisierungsprüfungen, Caching-Probleme, die widerrufene Berechtigungen nicht widerspiegeln, und Autorisierungsumgehung durch Parametermanipulation.

Risiko

Fehlerhafte Autorisierung wird konstant in den CWE Top 25 geführt. CVE-2025-64707 in Frappe LMS demonstriert einen Caching-Fehler, bei dem Rollenwiderrufungen nicht sofort durchgesetzt werden, wodurch Benutzer nach der Admin-Entfernung vorübergehend Berechtigungen behalten können. Aktuelle Schwachstellen betreffen GitLab CE/EE, OpenStack Keystone (Kritisch), JumpServer, Authlib, Adobe Commerce/Magento und Kubernetes Apiserver. Diese Schwachstellen sind besonders gefährlich, weil sie Sicherheitsaudits bestehen können, die nur das Vorhandensein von Autorisierungscode prüfen, nicht dessen Korrektheit.

Lösung

Implementieren Sie Autorisierung mit gut getesteten Frameworks anstatt benutzerdefiniertem Code. Verwenden Sie zentralisierte Autorisierungsdienste. Invalidieren Sie Caches sofort, wenn sich Berechtigungen ändern. Implementieren Sie Defense-in-Depth mit mehreren Autorisierungsprüfungen. Testen Sie Autorisierungslogik gründlich, einschließlich Grenzfällen und Race Conditions. Verwenden Sie positive Autorisierung (explizites Erlauben) anstatt negative (bestimmte Fälle verweigern). Protokollieren Sie alle Autorisierungsentscheidungen für Audits. Implementieren Sie Fail-Secure-Standardwerte - verweigern Sie den Zugriff, wenn die Autorisierungsprüfung fehlschlägt.

Häufige Auswirkungen

AuswirkungDetails
ZugriffskontrolleBereich: Privilegieneskalation

Benutzer erhalten Zugriff auf Ressourcen oder Aktionen über ihre Autorisierungsebene hinaus.
IntegritätBereich: Unbefugte Änderung

Angreifer können Daten ändern, auf die sie aufgrund fehlerhafter Prüfungen keinen Zugriff haben sollten.
VertraulichkeitBereich: Datenoffenlegung

Fehlerhafte Autorisierung legt sensible Daten für unbefugte Benutzer offen.

Beispielcode + Lösungscode

Verwundbarer Code

# VERWUNDBAR: Falscher Vergleichsoperator
def check_admin(user):
    # Sollte == sein, aber verwendet = (Zuweisung in einigen Sprachen)
    # In Python ist dies ein Syntaxfehler, aber Logikfehler sind häufig
    return user.role = 'admin'  # SyntaxError, zeigt aber das Konzept

# VERWUNDBAR: Groß-/Kleinschreibung-sensitiver Vergleich schlägt fehl
def is_authorized(user_role, required_role):
    # "Admin" != "admin" - Benutzer umgeht durch Verwendung anderer Schreibweise
    return user_role == required_role

# VERWUNDBAR: Prüfung des falschen Benutzerobjekts
@app.route('/api/admin/users/<user_id>')
@login_required
def admin_get_user(user_id):
    target_user = User.query.get(user_id)
    # BUG: Prüft die Rolle von target_user statt current_user!
    if target_user.is_admin:  # Sollte current_user.is_admin sein
        return jsonify(target_user.to_dict())
    return 'Verboten', 403

# VERWUNDBAR: Race Condition bei Berechtigungsprüfung
class PermissionService:
    def __init__(self):
        self.permission_cache = {}

    def check_permission(self, user_id, resource):
        # Cache zuerst prüfen
        cache_key = f"{user_id}:{resource}"
        if cache_key in self.permission_cache:
            return self.permission_cache[cache_key]

        # DB-Prüfung
        has_permission = self.db_check(user_id, resource)
        self.permission_cache[cache_key] = has_permission
        return has_permission

    # Wenn Berechtigung widerrufen wird, wird Cache nicht invalidiert!
    def revoke_permission(self, user_id, resource):
        self.db_revoke(user_id, resource)
        # Fehlt: del self.permission_cache[f"{user_id}:{resource}"]

Sicherer Code

# SICHER: Korrekte Vergleich mit Validierung
def check_admin_safe(user):
    if user is None:
        return False
    return user.role == 'admin'

# SICHER: Groß-/Kleinschreibung-unabhängiger Vergleich
def is_authorized_safe(user_role, required_role):
    if not user_role or not required_role:
        return False
    return user_role.lower() == required_role.lower()

# SICHER: Korrekten Benutzer prüfen und Grenzfälle behandeln
@app.route('/api/admin/users/<user_id>')
@login_required
def admin_get_user_safe(user_id):
    # AKTUELLEN Benutzer-Admin-Status prüfen, nicht Zielbenutzer
    if not current_user.is_admin:
        audit_log.warning(f"Nicht-Admin {current_user.id} versuchte Admin-Zugriff")
        return 'Verboten', 403

    target_user = User.query.get_or_404(user_id)
    audit_log.info(f"Admin {current_user.id} hat auf Benutzer {user_id} zugegriffen")
    return jsonify(target_user.to_dict())

# SICHER: Cache-Invalidierung bei Berechtigungsänderungen
class SecurePermissionService:
    def __init__(self):
        self._cache = {}
        self._lock = threading.Lock()

    def check_permission(self, user_id, resource):
        cache_key = f"{user_id}:{resource}"

        with self._lock:
            if cache_key in self._cache:
                cached = self._cache[cache_key]
                if cached['expires'] > time.time():
                    return cached['value']

            has_permission = self._db_check(user_id, resource)

            self._cache[cache_key] = {
                'value': has_permission,
                'expires': time.time() + 60  # Kurze TTL
            }
            return has_permission

    def revoke_permission(self, user_id, resource):
        self._db_revoke(user_id, resource)

        # Cache sofort invalidieren
        cache_key = f"{user_id}:{resource}"
        with self._lock:
            self._cache.pop(cache_key, None)

        # Auch verwandte Caches invalidieren
        self._invalidate_user_cache(user_id)

Ausgenutzt in der Praxis

Frappe LMS Rollen-Caching-Fehler (Frappe, 2025)

CVE-2025-64707 in Frappe LMS 2.0.0-2.41.0 ermöglicht Benutzern, Berechtigungen nach Rollenwiderrufung aufgrund von Caching-Mechanismen zu behalten, die die Durchsetzung von Berechtigungsänderungen verzögern, behoben durch Implementierung sofortiger Cache-Invalidierung.

OpenStack Keystone Autorisierungsumgehung (OpenStack, 2025)

Kritische fehlerhafte Autorisierungsschwachstelle in OpenStack Keystone ermöglicht Angreifern die Umgehung von Zugriffskontrollen durch fehlerhafte Autorisierungslogik.

Kubernetes API Server Privilegieneskalation (Kubernetes, 2025)

Fehlerhafte Autorisierung im Kubernetes Apiserver ermöglicht Privilegieneskalation durch fehlerhafte Autorisierungsprüfungen.


Tools zum Testen/Ausnutzen


CVE-Beispiele


Referenzen

  1. MITRE. "CWE-863: Incorrect Authorization." https://cwe.mitre.org/data/definitions/863.html

  2. OWASP. "Access Control Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Access_Control_Cheat_Sheet.html