Richtlinien

Authentifizierung und Autorisierung

Das Thema Authentifizierung (AuthN) und Autorisierung (AuthZ) ist von enormer Bedeutung, da Schwachstellen in diesen Bereichen überaus häufig auftreten. Da sie so regelmäßig vorkommen, herrscht oft Unsicherheit darüber, was genau sie bedeuten oder was ihre Ursachen sind.

Zur Erinnerung: Die Begriffe decken Folgendes ab:

  • Authentifizierung: Wer ist der Benutzer?
  • Autorisierung: Worauf sollte der Benutzer Zugriff haben?

Wir betrachten beide Punkte im Folgenden getrennt.

Authentifizierung (Identifizierungs- und Authentifizierungsfehler)

Eine fehlerhafte Authentifizierung kann eine Vielzahl von Schwachstellen umfassen, wie zum Beispiel:

  • Fehlende Authentifizierung auf einer bestimmten Seite oder einem Endpunkt
  • Mangelnder Schutz gegen Brute-Force-Angriffe (Credential Stuffing)
  • Unsichere Prozesse zur Kontowiederherstellung oder Passwortzurücksetzung
  • Unsichere Generierung, Validierung, Ablaufsteuerung, Übertragung oder Speicherung von Authentifizierungs-Tokens
  • Fehlerhafte oder fehlende Überprüfung, ob sich der Benutzer mit 2FA authentifiziert hat (sofern zutreffend)

Der erste Punkt auf der Liste (fehlende Authentifizierung) ist das mit Abstand häufigste Problem in der Praxis. Oft müssen Entwickler explizit angeben oder konfigurieren, welche Authentifizierungsstufe für eine Seite oder einen Endpunkt erforderlich ist – ein Schritt, der leicht übersehen werden kann.

Es ist bewährte Praxis, sicherzustellen, dass ein System geschlossen ausfällt, anstatt offen. Anstatt jeden Endpunkt einzeln mit der Information zu versehen, dass eine authentifizierte Benutzersitzung erforderlich ist, sollte standardmäßig gelten, dass alle Routen eine authentifizierte Sitzung erfordern, sofern dies nicht explizit anders konfiguriert wurde. Dies kann die Fehleranfälligkeit drastisch reduzieren.

Autorisierung (fehlerhafte Zugriffskontrolle)

Autorisierungsprobleme treten häufig in verschiedenen Formen auf:

  • Insecure Direct Object References (IDOR)
  • Fehlende Zugriffskontrolle auf Funktionsebene (fehlende AuthZ)
  • Privilegieneskalation (horizontal oder vertikal)

Unsichere direkte Objektverweise (IDOR)

Objekte verfügen in der Regel über eindeutige Identifikatoren (IDs), die als Referenzschlüssel dienen. Wenn ein Benutzer eine Anfrage stellt, um eine Bestellung, ein Konto oder Ähnliches einzusehen, enthält diese meist die entsprechende ID. Eine „unsichere direkte Objektverknüpfung“ liegt vor, wenn die Anwendung nicht überprüft, ob der Benutzer (oder ein nicht authentifizierter Nutzer) Zugriff auf dieses spezifische Objekt haben sollte.

Fehlende Zugriffskontrolle auf Funktionsebene

Eine weitere sehr häufige Schwachstelle ist das Fehlen von Autorisierungsprüfungen für eine Seite oder einen Endpunkt (im Gegensatz zu einem Objekt).

Je nach verwendetem Framework müssen Entwickler die Autorisierung entweder im Handler prüfen oder den Endpunkt mit Anmerkungen versehen, um die Anforderungen für den Aufruf festzulegen.

Leider werden diese zusätzlichen Schritte oft vergessen, was häufig erklärt, wie es zu bestimmten Autorisierungsschwachstellen kommt.

Empfehlungen

Standardmäßig geschlossen statt offen

Sowohl bei der Authentifizierung als auch bei der Autorisierung ist das Prinzip, standardmäßig geschlossene statt offene Systeme zu verwenden, von großer Bedeutung.

Je nach Sprache oder Framework ist es bewährte Praxis, sicherzustellen, dass für alle Routen in Ihre Anwendung standardmäßig eine authentifizierte Sitzung mit den höchstmöglichen Rollen oder Berechtigungen erforderlich ist. Dies zwingt Entwickler dazu, die Anforderungen für die jeweilige Route explizit zu überschreiben.

cs

// Sicherstellen, dass Anfragen standardmäßig authentifiziert werden und Admin-Rechte geprüft werden
[Authenticate]
[Authorize("Admin")]
public class SecureController : Controller
{

}

public class MyController : SecureController
{

    // Überschreibt das geerbte Authorize-Attribut, um jedem Benutzer Zugriff auf die Seite zu gewähren
    [Authorize("User")]
    public Page ShowUserProfile() {
        
    }   

    // Kann nur von einem Admin-Benutzer aufgerufen werden
    public Page ShowAdminPage() { 

   }

    // Überschreibt das Authenticate- und Authorize-Attribut, um MIR Zugriff zu gewähren
    [AllowAnonymous]
    public Page ShowLoginPage() {
       
    } 

}

Autorisierungsprüfungen in Diensten erzwingen

Beim Datenzugriff ist es äußerst wichtig, sicherzustellen, dass alle Zugriffe relevante Zugriffs- und Autorisierungsprüfungen einheitlich durchsetzen. Dies wird im Allgemeinen durch die Verwendung von Domänendiensten erreicht.

Weitere Beispiele

Nachfolgend finden Sie eine kurze Sammlung von Beispielen, die den Unterschied zwischen sicherer und unsicherer Authentifizierung und Autorisierung verdeutlichen.

C# - unsicher

Fehlende Authentifizierung

public class AdminController : Controller
{

    // UNSICHER: Prüft nicht, ob der Benutzer angemeldet ist, bevor eine Admin-Seite angezeigt wird
    public Page ShowAdminPage() {

    }

}

Fehlende Autorisierung

[Authenticate]
public class AdminController : Controller
{

    // UNSICHER: Prüft nicht die Autorisierung des Benutzers, bevor eine Admin-Seite angezeigt wird public Page ShowAdminPage() {

    }
‍
}

C# - sicher

[Authenticate]
[Authorize("Admin")]
public class AdminController : Controller
{
‍
    // SICHER: Prüft sowohl, ob der Benutzer angemeldet ist, als auch, ob er die Admin-Rolle besitzt
    public Page ShowAdminPage() {

    }

}
Slogan

Sichere Programmierung in der Praxis

Entdecken Sie Richtlinien für sicheres Programmieren, um Schwachstellen wie die OWASP Top 10 zu verstehen und zu beheben, und tauchen Sie in geführte Trainingsmissionen ein, um diese in realistischen Anwendungssimulationen zu üben.

Weitere Richtlinien
Demo buchen