Zum Inhalt springen

5. Benutzer und Rechte

Zu Zen-Modus wechseln

Benutzer- und Rechteverwaltung in relationalen Datenbankmanagementsystemen

Abschnitt betitelt „Benutzer- und Rechteverwaltung in relationalen Datenbankmanagementsystemen“

Relationale Datenbanksysteme (RDBMS) wie PostgreSQL und MySQL sind nicht nur „Datenspeicher”. Sie sind Mehrbenutzersysteme, in denen viele Menschen und Anwendungen gleichzeitig auf dieselben Daten zugreifen.

Echte Datenbanken enthalten oft kritische Informationen:

  • Kundendaten
  • Schuldaten (Schüler/Noten)
  • Systemprotokolle
  • Bestellungen und Rechnungen

Ohne Rechteverwaltung könnte jeder Benutzer:

  • vertrauliche Daten lesen
  • wichtige Datensätze verändern oder löschen
  • die Datenbankstruktur zerstören (DROP TABLE)
  • versehentlich (oder absichtlich) Schaden anrichten

Deshalb braucht es:

  • Benutzerverwaltung
  • Rechteverwaltung (Privilegien)

Authentifizierung = „Wer ist der Benutzer?”

Das ist der Login-Schritt. Die Datenbank prüft, ob der Benutzer sich verbinden darf, über:

  • Benutzername + Passwort
  • Zertifikate
  • SSO / Kerberos / AD-Login (je nach Konfiguration)

Nach der Authentifizierung weiß die Datenbank: „Der Benutzer ist app_user.”

Autorisierung = „Was darf der Benutzer tun?”

Nach dem Login entscheidet die Datenbank, welche Aktionen erlaubt sind:

  • Darf der Benutzer die Tabelle students lesen?
  • Darf er neue Noten einfügen?
  • Darf er Zeilen löschen?
  • Darf er Tabellen löschen?

Autorisierung ist die Rechteprüfung.

Jeder Benutzer erhält nur die minimal nötigen Rechte.

Warum?

  • Wird ein Konto gehackt, bleibt der Schaden begrenzt.
  • Hat eine Anwendung einen Fehler (etwa SQL-Injection), können Angreifer nicht „die ganze Datenbank übernehmen”.
  • Versehen richten weniger Schaden an.

DML – Data Manipulation Language (Datenoperationen)

Diese Rechte steuern die Arbeit an Tabellendaten:

  • SELECT → Daten lesen
  • INSERT → neue Zeilen hinzufügen
  • UPDATE → bestehende Zeilen ändern
  • DELETE → Zeilen entfernen

DDL – Data Definition Language (Strukturoperationen)

Diese Rechte steuern Schema und Struktur:

  • CREATE → Tabellen, Views usw. anlegen
  • ALTER → Tabellen ändern (Spalten hinzufügen, Typen ändern)
  • DROP → Objekte entfernen (gefährlich!)

DDL-Rechte gehören meist Administratorinnen oder Migrations-Benutzern.

EXECUTE – Gespeicherte Logik ausführen

  • EXECUTE → Stored Procedures oder Functions ausführen

Admin

  • Vollzugriff
  • verwaltet Benutzer, Rechte, Backups, Schemaänderungen

Anwendungsbenutzer („Service-Account”)

  • wird von einem Backend-Dienst genutzt (FastAPI, Django usw.)
  • sollte nur die nötigen CRUD-Rechte haben
  • sollte keine Admin- oder Schema-Änderungsrechte haben

Nur-Lese-/Reporting-Benutzer

  • nur SELECT
  • für Dashboards und Statistiken

Entwickler-Benutzer (nur DEV/TEST)

  • in der Entwicklung sind manchmal mehr Rechte erlaubt
  • in der Produktion nicht empfohlen

Die Rechte in PostgreSQL sind geschichtet. Man kann sie sich wie ein Gebäude mit Räumen und Türen vorstellen:

  1. Datenbanktür (~ Eingang des Gebäudes)
  2. Schematür (~ Eingang eines Stockwerks)
  3. Objekttür (Tabelle/Function usw.)

Ist irgendeine Tür auf dem Weg zum Raum verschlossen, folgt permission denied.

flowchart TB
  subgraph S["PostgreSQL Server/Cluster"]
    direction TB

    subgraph D["Database: schooldb"]
      direction TB

      subgraph PRIV["Schema: private"]
        direction TB
        PRbox["Private Tables<br/>(e.g. audit_log, students_private)"]
      end

      subgraph API["Schema: api"]
        direction TB
        APIbox["API Functions<br/>(e.g. get_students(), add_grade())"]
      end

      subgraph REP["Schema: reporting"]
        direction TB
        REPbox["Views<br/>Materialized Views"]
      end

      subgraph PUB["Schema: public"]
        direction TB
        PUBbox["Tables<br/>Views<br/>Sequences<br/>Functions / Procedures<br/>Triggers"]
      end
    end

    subgraph R["Roles / Users"]
      direction TB
      Rbox["app_user<br/>report_user<br/>db_admin"]
    end

    subgraph OWN["Ownership"]
      direction TB
      OWNbox["Each object has 1 owner<br/>Owner can ALTER/DROP<br/>ALTER ... OWNER TO ..."]
    end

    subgraph G["Privileges (Permissions)"]
      direction TB
      Gbox["CONNECT (Database)<br/>USAGE (Schema)<br/>SELECT/INSERT/UPDATE/DELETE (Tables/Views)<br/>EXECUTE (Functions/Procedures)<br/>USAGE/SELECT (Sequences)"]
    end

    D -.-> R
    D -.-> G
    D -.-> OWN
  end

  linkStyle 0 stroke:transparent,stroke-width:0px;
  linkStyle 1 stroke:transparent,stroke-width:0px;
  linkStyle 2 stroke:transparent,stroke-width:0px;

In PostgreSQL ist fast alles eine ROLE.

  • Eine ROLE mit LOGIN ist ein echter Benutzer.
  • Eine ROLE ohne LOGIN ist eine Gruppenrolle (für die Rechteverwaltung).

Beispielrollen:

  • app_user → Backend-/API-Zugriff
  • report_user → Nur-Lese-Reporting
  • db_admin → volle Kontrolle

Warum Rollen? Weil sich Rechte damit leichter verwalten lassen:

  • eine Rolle ändern → alle Benutzer dieser Rolle sind aktualisiert

Benutzer anlegen (Rollen mit LOGIN)

CREATE ROLE app_user WITH LOGIN PASSWORD 'pw';
CREATE ROLE report_user WITH LOGIN PASSWORD 'pw';

Eine Gruppenrolle anlegen (kein LOGIN)

CREATE ROLE app_rw;

GRANT

Eine Gruppenrolle wird an einen Benutzer gehängt:

GRANT app_rw TO app_user;

Bedeutung:

  • app_user „erbt” die Rechte von app_rw

So lassen sich die Rechte einer Gruppe (oder einer ganzen Gruppenhierarchie) ändern, ohne die einzelnen Benutzer anzufassen.

GRANT SELECT ON public.students TO app_rw;

REVOKE

Um eine Gruppenrolle von einem Benutzer zu entfernen:

REVOKE app_rw FROM app_user;

Wenn ein Benutzer Rechte an andere weitergeben durfte:

GRANT SELECT ON public.students TO app_user WITH GRANT OPTION;

lässt sich ihm nur das Weitergaberecht wieder entziehen:

REVOKE GRANT OPTION FOR SELECT ON public.students FROM app_user;

Ergebnis:

  • app_user darf weiterhin SELECT
  • kann SELECT aber nicht mehr an andere vergeben

Mächtige Rollenattribute

Manche Rollenattribute verleihen admin-ähnliche Macht:

  • CREATEDB → darf Datenbanken anlegen
  • CREATEROLE → darf Rollen anlegen und die Rollenzugehörigkeit verwalten
  • SUPERUSER → volle Kontrolle

Beispiel:

CREATE ROLE db_admin WITH LOGIN PASSWORD 'pw' SUPERUSER;

Wichtig: In echten Projekten SUPERUSER nur für echte Administratorinnen vergeben.

Mehr Details in der CREATE ROLE-Referenz: https://www.postgresql.org/docs/current/user-manag.html

In PostgreSQL hat jedes Datenbankobjekt genau einen Eigentümer.

Beispiele für Objekte mit Eigentümer:

  • Datenbank (schooldb)
  • Schema (public, api, reporting, …)
  • Tabellen (students)
  • Views / Materialized Views
  • Sequences
  • Functions / Procedures

Üblicherweise wird die Erstellerin eines Objekts automatisch zur Eigentümerin.

Rechte vs. Ownership

Rechte (GRANT/REVOKE) steuern Aktionen wie:

  • SELECT, INSERT, UPDATE, DELETE
  • EXECUTE
  • USAGE
  • CONNECT

Ownership steuert die strukturelle Macht über ein Objekt:

  • ALTER ... (Struktur/Definition ändern)
  • DROP ... (Objekt löschen)

Wichtig: ALTER und DROP sind keine normalen GRANT-Rechte.

Sie sind Eigentümerrechte.

Das heißt:

Das Recht, ein Objekt zu ändern oder zu zerstören, steckt darin, sein Eigentümer zu sein.

Ownership-Macht lässt sich also nicht mit REVOKE „reparieren”.

  • app_user besitzt die Tabelle public.students
  • alle Rechte werden entzogen
REVOKE ALL PRIVILEGES ON public.students FROM app_user;

Auch danach kann app_user noch:

DROP TABLE public.students;
ALTER TABLE public.students ADD COLUMN test int;

Die Fähigkeit zu ALTER und DROP kommt aus der Ownership, nicht aus den GRANT-Rechten.

Das ist der Kerngedanke:

  • GRANT/REVOKE steuert „mit Daten arbeiten”
  • OWNER steuert „das Objekt selbst kontrollieren”

Es ist eine gute Praxis, zu trennen:

Owner-/Migrations-Rolle (starke Rechte, DDL)

  • db_admin oder migration_user
  • besitzt Schemata und Tabellen
  • führt Migrationen aus (CREATE/ALTER/DROP)

Anwendungsrolle (minimale Rechte, nur DML)

  • app_user
  • kann nur CRUD (SELECT/INSERT/UPDATE/DELETE)
  • sollte keine Tabellen besitzen

Reporting-Rolle

  • report_user
  • überwiegend SELECT

Das verhindert katastrophalen Schaden, falls ein Anwendungsbenutzer kompromittiert wird (SQL-Injection, geleaktes Passwort usw.).

Ownership lässt sich übertragen:

ALTER TABLE public.students OWNER TO db_admin;
ALTER SCHEMA public OWNER TO db_admin;
ALTER DATABASE schooldb OWNER TO db_admin;

Das kommt häufig nach einem ersten Setup vor, bei dem Tabellen mit der falschen Rolle angelegt wurden.

Legen in einem Team mehrere Entwicklerinnen Tabellen mit ihren eigenen Konten an, landet die Datenbank bei gemischter Ownership:

  • Tabelle A gehört dev1
  • Tabelle B gehört dev2
  • View C gehört dev3

Das macht später Probleme:

  • Migrationen können wegen fehlender Ownership scheitern
  • Rechte werden inkonsistent
  • ALTER DEFAULT PRIVILEGES verhält sich unerwartet, weil es rollenspezifisch ist

Best Practice:

Alle Schemaänderungen mit einer eigenen Rolle ausführen (migration_user / db_admin).

Mehr zu Rechten und Ownership: https://www.postgresql.org/docs/18/ddl-priv.html

Datenbankebene: CONNECT

Um die Datenbank schooldb zu nutzen, muss eine Rolle sich verbinden dürfen:

CONNECT auf die Datenbank

Bedeutung:

„Der Benutzer darf diese Datenbank betreten.”

Ohne CONNECT kann der Benutzer die DB nicht wirklich nutzen (selbst wenn der Login klappt).

Schemaebene: USAGE

PostgreSQL-Datenbanken enthalten mehrere Schemata (Namensräume), zum Beispiel:

  • public → Standardschema für gewöhnliche Tabellen
  • reporting → Views / Materialized Views für Dashboards
  • api → gespeicherte Funktionen, die wie eine API-Schicht wirken
  • private → interne Tabellen, nicht für normale Benutzer gedacht

Um Objekte in einem Schema zu nutzen, ist nötig:

USAGE auf dieses Schema

Bedeutung:

„Der Benutzer darf diesen Bereich/Namensraum betreten.”

Das ist ein häufiger Anfängerfehler in PostgreSQL: Ein Benutzer hat Tabellenrechte, scheitert aber trotzdem, weil das USAGE auf dem Schema fehlt.

Objektrechte: Tabellen und Views

Sind CONNECT und USAGE in Ordnung, sind trotzdem noch Rechte auf den eigentlichen Objekten nötig:

Typische Anwendungsrechte:

  • SELECT, INSERT, UPDATE
  • eventuell DELETE

Die meisten Reporting-Benutzer brauchen nur:

  • SELECT

Beispielhafte Überlegung aus dem Diagramm:

  • app_user → CRUD im Schema public
  • report_user → SELECT im Schema reporting

Objektrechte: Functions / Procedures (EXECUTE)

Im Schema api lassen sich Funktionen ablegen wie:

  • get_students()
  • add_grade(student_id, grade)

Dann lässt sich die Anwendung so entwerfen:

  • der App-Benutzer darf Funktionen aufrufen (EXECUTE)
  • der App-Benutzer darf aber nicht direkt auf private Tabellen zugreifen

Ausführungsrechte und Sicherheitskontext

Functions und Procedures können in zwei Sicherheitskontexten laufen:

  1. Security Invoker (Standard) Standardmäßig laufen Functions und Procedures mit den Rechten des aufrufenden Benutzers.

  2. Security Definer

    Wird eine Function oder Procedure mit dem Schlüsselwort SECURITY DEFINER definiert, läuft sie mit den Rechten der Eigentümerin der Function/Procedure, nicht der Aufruferin. So kann ein Benutzer mit wenig Rechten eine Operation ausführen, die normalerweise mehr Rechte braucht — auf kontrollierte Weise.

In PostgreSQL wirkt

GRANT ... ON ALL TABLES IN SCHEMA public

nur auf bestehende Tabellen.

Wird später eine neue Tabelle angelegt, werden die Rechte nicht automatisch vergeben.

Lösung: ALTER DEFAULT PRIVILEGES. Das ist etwa für Teamarbeit und langlaufende Projekte wichtig.

z. B. Tabellenrechte:

\dp public.students

Beispielergebnis:

Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+----------+-------+----------------------------+-------------------+----------
public | students | table | db_admin=arwdDxt/db_admin +| |
| | | app_user=arwd/db_admin +| |
| | | report_user=r/db_admin | |
(1 row)

Bedeutung der Buchstaben (die häufigsten)

  • r = SELECT
  • a = INSERT
  • w = UPDATE
  • d = DELETE
  • D = TRUNCATE
  • x = REFERENCES
  • t = TRIGGER

Also:

  • app_user=arwd → CRUD
  • report_user=r → nur SELECT
  • db_admin=arwdDxt → im Grunde alles

(/db_admin am Zeilenende bedeutet: der Rechtevergeber war die Rolle/der Benutzer db_admin)

Tabellen-/View-Details

\dt+ public.*

Schema-Details

\dn+

Datenbank-Details

\l+

(= wer hat welche Rechte auf einem bestimmten Datenbankobjekt?)

z. B. auf Tabelle mytable:

SELECT
grantee,
privilege_type
FROM information_schema.role_table_grants
WHERE table_schema = 'public'
AND table_name = 'mytable'
ORDER BY grantee, privilege_type;

Beispielergebnis:

granteeprivilege_type
db_adminDELETE
db_adminINSERT
db_adminREFERENCES
db_adminSELECT
db_adminTRIGGER
db_adminTRUNCATE
db_adminUPDATE
app_userDELETE
app_userINSERT
app_userSELECT
app_userUPDATE
report_userSELECT

(= wer ist Eigentümer eines bestimmten Datenbankobjekts?)

z. B. auf Tabelle mytable:

SELECT
n.nspname AS table_schema,
c.relname AS table_name,
pg_get_userbyid(c.relowner) AS owner
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
AND c.relname = 'mytable';

Beispielergebnis:

table_schematable_nameowner
publicmytabledb_admin
  • fehlendes CONNECT
  • fehlendes USAGE auf dem Schema
  • neue Tabellen ohne Rechte → keine Default Privileges gesetzt
  • Ownership-Verwirrung: Benutzer ist Eigentümer → kann trotz REVOKE weiter ALTER/DROP
  • Rechte an eine Rolle vergeben, aber Rolle nicht zugewiesen (oder Mitgliedschaft entzogen) → „warum hat der Benutzer noch/nicht Zugriff?”
  • search_path-Probleme: Benutzer fragt students ab, die Tabelle liegt aber in einem anderen Schema → public.students verwenden oder search_path anpassen

MySQL hat eine einfachere „Form” als PostgreSQL.

Server → Database → Objekte

Es hat innerhalb einer Datenbank nicht die zusätzliche Schema-Schicht wie PostgreSQL.

  • MySQL ~ einfacher Bungalow
  • PostgreSQL ~ Gebäude mit mehreren Stockwerken
flowchart TB
  subgraph S["MySQL Server"]
    direction TB

    subgraph D["Database (Schema): schooldb"]
      direction TB
      Dbox["Tables<br/>Views<br/>Functions<br/>Procedures<br/>Triggers<br/>Events (Scheduler)"]
    end

    subgraph U["Users (user@host)"]
      direction TB
      Ubox["'app_user'@'localhost'<br/>'report_user'@'%'<br/>'root'@'localhost'"]
    end

    subgraph G["Privileges (Permissions)"]
      direction TB
      Gbox["SELECT/INSERT/UPDATE/DELETE<br/>CREATE/ALTER/DROP<br/>EXECUTE"]
    end
  end

Benutzer

MySQL-Benutzer enthalten immer einen Host: user@host

Ein Konto ist definiert als:

  • 'app_user'@'localhost'
  • 'app_user'@'192.168.1.%'
  • 'app_user'@'%'

Bedeutung:

  • der Host ist Teil der Identität
  • derselbe Benutzername kann mehrfach mit verschiedenen Hosts existieren

In PostgreSQL:

  • die Rolle ist einfach app_user
  • erlaubte Hosts werden anderswo gesteuert (pg_hba.conf, Firewall, Cloud-Einstellungen)

Rollen

MySQL unterstützt ebenfalls Rollen:

CREATE ROLE 'app_rw';
GRANT SELECT, INSERT, UPDATE ON schooldb.* TO 'app_rw';
GRANT 'app_rw' TO 'app_user'@'localhost';

Aber verglichen mit PostgreSQL:

  • sind Rollen im Alltag weniger zentral
  • viele MySQL-Tutorials lehren noch „direkt an den Benutzer vergeben”
  • in größeren Setups sind sie trotzdem nützlich und empfohlen

Rollen aktivieren

In MySQL kann eine Rolle vergeben, aber in Sitzungen nicht automatisch aktiv sein, solange sie nicht gesetzt wird.

Eine Rolle für die aktuelle Sitzung aktivieren

SET ROLE 'app_rw';

Rollen beim Login automatisch aktivieren (empfohlen)

SET DEFAULT ROLE 'app_rw' TO 'app_user'@'localhost';
SET DEFAULT ROLE 'reporting_ro' TO 'report_user'@'localhost';

In MySQL ist SCHEMA im Grunde dasselbe wie DATABASE.

MySQL hat also nicht mehrere Schemata wie public, reporting, api innerhalb einer Datenbank, wie PostgreSQL es hat.

In einer MySQL-Datenbank gibt es üblicherweise:

  • Tabellen
  • Views
  • Stored Procedures / Functions
  • Trigger

Die Rechtevergabe ist einfacher und folgt diesem gängigen Muster:

CREATE ROLE 'role_reporting';
GRANT SELECT ON schooldb.* TO 'role_reporting';
GRANT 'role_reporting' TO 'report_user'@'localhost';

Nicht vergessen, die Rolle beim Login automatisch zu aktivieren (wichtig!)

SET DEFAULT ROLE 'role_reporting' TO 'report_user'@'localhost';

Oder Rechte direkt an den Benutzer ohne Rolle vergeben (nicht empfohlen):

GRANT SELECT ON schooldb.* TO 'app_user'@'localhost';

In PostgreSQL sind meist mehrere Grants nötig:

  • CONNECT
  • USAGE auf das Schema
  • Tabellenrechte
  • Default Privileges für künftige Objekte

Grants für einen bestimmten Benutzer anzeigen

SHOW GRANTS FOR 'app_user'@'localhost';

Beispielergebnis:

+-------------------------------------------------------------------------------------------+
| Grants for app_user@localhost |
+-------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `app_user`@`localhost` |
| GRANT `role_app`@`%` TO `app_user`@`localhost` |
| SET DEFAULT ROLE `role_app`@`%` TO `app_user`@`localhost` |
+-------------------------------------------------------------------------------------------+
  • app_user selbst hat im Grunde keine direkten Rechte (USAGE)
  • bekommt seine Rechte aber über die Rolle role_app
  • und die Rolle wird durch SET DEFAULT ROLE ... automatisch aktiviert

Wir müssen also die Grants für role_app nachschauen:

SHOW GRANTS FOR 'role_app';

Eine mögliche Ausgabe wäre:

+-------------------------------------------------------------------------------------------+
| Grants for role_app@% |
+-------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `role_app`@`%` |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `schooldb`.* TO `role_app`@`%` |
| GRANT EXECUTE ON `schooldb`.* TO `role_app`@`%` |
+-------------------------------------------------------------------------------------------+

Tabellenrechte über information_schema prüfen (= wer hat welche Rechte auf einer bestimmten Tabelle?)

z. B. auf Tabelle mytable:

SELECT
GRANTEE,
PRIVILEGE_TYPE
FROM information_schema.TABLE_PRIVILEGES
WHERE TABLE_SCHEMA = 'schooldb'
AND TABLE_NAME = 'mytable'
ORDER BY GRANTEE, PRIVILEGE_TYPE;

Beispielergebnis:

GRANTEEPRIVILEGE_TYPE
'app_user'@'localhost'DELETE
'app_user'@'localhost'INSERT
'app_user'@'localhost'SELECT
'app_user'@'localhost'UPDATE
'report_user'@'localhost'SELECT
'role_app'@'%'DELETE
'role_app'@'%'INSERT
'role_app'@'%'SELECT
'role_app'@'%'UPDATE

Rechte auf Schemaebene prüfen (schooldb.*)

SELECT
GRANTEE,
PRIVILEGE_TYPE
FROM information_schema.SCHEMA_PRIVILEGES
WHERE TABLE_SCHEMA = 'schooldb'
ORDER BY GRANTEE, PRIVILEGE_TYPE;

Beispielergebnis:

GRANTEEPRIVILEGE_TYPE
'app_user'@'localhost'CREATE
'app_user'@'localhost'DROP
'app_user'@'localhost'REFERENCES
'report_user'@'localhost'SELECT
'role_app'@'%'SELECT
'role_app'@'%'INSERT
'role_app'@'%'UPDATE
'role_app'@'%'DELETE

In MySQL lassen sich Rechte mit REVOKE wieder entfernen.

Ein Recht entfernen:

REVOKE SELECT ON schooldb.mytable FROM 'app_user'@'localhost';

Mehrere Rechte entfernen:

REVOKE INSERT, UPDATE, DELETE ON schooldb.mytable FROM 'app_user'@'localhost';

Rechte auf eine ganze Datenbank entfernen:

REVOKE SELECT ON schooldb.* FROM 'report_user'@'localhost';

Wenn einem Benutzer eine Rolle vergeben wurde:

GRANT 'app_rw' TO 'app_user'@'localhost';

lässt sich die Rolle wieder entfernen:

REVOKE 'app_rw' FROM 'app_user'@'localhost';

Wenn eine Rolle als Default gesetzt wurde:

SET DEFAULT ROLE 'app_rw' TO 'app_user'@'localhost';

betrifft das neue Sitzungen des Benutzers (nach dem nächsten Login).

Wird die Rollenmitgliedschaft entzogen, behalten bestehende Sitzungen ihre aktuell aktiven Rollen unter Umständen bis zum erneuten Verbinden oder bis SET ROLE erneut ausgeführt wird.

Aktuelle Rechte prüfen:

SHOW GRANTS FOR 'app_user'@'localhost';

MySQL hat kein zentrales Konzept von Objekt-Ownership wie PostgreSQL, wo jede Tabelle/jeder View/jede Function genau einen Eigentümer mit impliziter ALTER/DROP-Macht hat.

In MySQL beruht die Zugriffssteuerung vor allem auf:

  • Rechten über GRANT (an Benutzer und/oder Rollen)
  • Objekttypen (Tabellen, Views, Routinen, Trigger, Events)
  • der Identität user@host

Für Tabellen wird also typischerweise alles mit GRANT / REVOKE (und Rollen) verwaltet.

Manche Objekte (Views, Procedures, Functions, Trigger, Events) speichern einen DEFINER (user@host).

Der DEFINER legt den Sicherheitskontext fest (SQL SECURITY DEFINER vs. INVOKER) → mit wessen Rechten das Objekt läuft.

Beim DEFINER geht es vor allem um Ausführungsrechte, nicht darum, „wer das Objekt löschen/ändern darf”.

  • Anwendung läuft als root
  • zu offener Host 'user'@'%'
  • zu mächtige Grants wie GRANT ALL ON *.*
  • Rolle vergeben, aber nicht aktiv (die Sitzung hat keine Rechte, bis SET ROLE / SET DEFAULT ROLE)
  • WITH GRANT OPTION in der Produktion (Benutzer können sich still selbst erweitern, indem sie an andere vergeben)
  • REVOKE ausgeführt, aber Zugriff besteht weiter, weil die Rechte über eine Rolle kommen (auch SHOW GRANTS für Rollen prüfen)