PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL-Berechtigungen und -Sicherheit – Sperren des öffentlichen Schemas

Einführung

In einem früheren Artikel haben wir die Grundlagen zum Verständnis von PostgreSQL-Schemas, die Mechanik des Erstellens und Löschens vorgestellt und mehrere Anwendungsfälle besprochen. Dieser Artikel erweitert diese Grundlagen und untersucht die Verwaltung von Berechtigungen in Bezug auf Schemas.

Mehr Terminologieüberladung

Aber es gibt eine Vorsache, die einer Klärung bedarf. Erinnern Sie sich daran, dass wir im vorherigen Artikel auf einen möglichen Punkt der Verwirrung im Zusammenhang mit der Überladung des Begriffs „Schema“ eingegangen sind. Die spezielle Bedeutung dieses Begriffs im Zusammenhang mit PostgreSQL-Datenbanken unterscheidet sich von der allgemeinen Verwendung in relationalen Datenbankverwaltungssystemen. Wir haben eine andere ähnliche mögliche Terminologiekerfuffle für das vorliegende Thema, die sich auf das Wort „öffentlich“ bezieht.

Bei der anfänglichen Datenbankerstellung enthält die neu erstellte Postgresql-Datenbank ein vordefiniertes Schema namens „public“. Es ist ein Schema wie jedes andere, aber das gleiche Wort wird auch als Schlüsselwort verwendet, das „alle Benutzer“ in Kontexten bezeichnet, in denen ansonsten ein tatsächlicher Rollenname verwendet werden könnte, wie z. B. ... warten Sie darauf ... Schema-Berechtigungsverwaltung . Die Bedeutung und zwei unterschiedliche Verwendungen werden in den folgenden Beispielen verdeutlicht.

Schemaberechtigungen abfragen

Bevor wir dies mit Beispielcode zum Erteilen und Widerrufen von Schemaberechtigungen konkretisieren, müssen wir überprüfen, wie Schemaberechtigungen untersucht werden. Unter Verwendung der psql-Befehlszeilenschnittstelle listen wir die Schemata und die zugehörigen Berechtigungen mit dem Befehl \dn+ auf. Für eine neu erstellte sampledb-Datenbank sehen wir diesen Eintrag für das öffentliche Schema:

sampledb=# \dn+ 
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description      
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =UC/postgres         |
(1 row)

Die ersten beiden und die vierte Spalte sind ziemlich einfach:Wie bereits erwähnt, zeigen sie das standardmäßig erstellte Schema mit dem Namen „public“, das als „standardmäßiges öffentliches Schema“ beschrieben wird und der Rolle „postgres“ gehört. (Der Schemabesitz wird, sofern nicht anders angegeben, auf die Rolle festgelegt, die das Schema erstellt.) Die dritte Spalte, die die Zugriffsrechte auflistet, ist hier von Interesse. Das Format der Berechtigungsinformationen stellt drei Elemente bereit:den Berechtigten, die Berechtigungen und den Berechtigungsgeber im Format „grantee=privileges/grantor“, d. h. links vom Gleichheitszeichen befindet sich die Rolle, die die Berechtigung(en) erhält, Unmittelbar rechts neben dem Gleichheitszeichen befindet sich eine Gruppe von Buchstaben, die das (die) bestimmte(n) Privileg(en) angeben, und schließlich nach dem Schrägstrich die Rolle, die dem (den) Privileg(en) verliehen wurde. Es kann mehrere solcher Berechtigungsinformationen geben, die durch ein Pluszeichen getrennt aufgeführt sind, da Berechtigungen additiv sind.

Für Schemas gibt es zwei mögliche Privilegien, die separat gewährt werden können:U für „USAGE“ und C für „CREATE“. Ersteres ist erforderlich, damit eine Rolle in der Lage ist, Datenbankobjekte wie Tabellen und Ansichten nachzuschlagen, die im Schema enthalten sind; Letztere Berechtigung ermöglicht es einer Rolle, Datenbankobjekte im Schema zu erstellen. Es gibt andere Buchstaben für andere Privilegien, die sich auf verschiedene Arten von Datenbankobjekten beziehen, aber für Schemata gelten nur U und C.

Um die obige Berechtigungsliste zu interpretieren, teilt uns die erste Spezifikation mit, dass dem Postgres-Benutzer die Aktualisierungs- und Erstellungsberechtigungen für das öffentliche Schema selbst gewährt wurden.

Beachten Sie, dass für die zweite Spezifikation oben links vom Gleichheitszeichen eine leere Zeichenfolge angezeigt wird. So werden Privilegien bezeichnet, die allen Benutzern durch das zuvor erwähnte Schlüsselwort PUBLIC gewährt werden.

Diese letztgenannte Spezifikation, allen Benutzern Nutzungs- und Erstellungsrechte für das öffentliche Schema zu gewähren, wird von einigen als möglicherweise im Widerspruch zu allgemeinen bewährten Verfahren für Sicherheitsprinzipien angesehen, bei denen man es vorziehen könnte, mit standardmäßig eingeschränktem Zugriff zu beginnen, sodass der Datenbankadministrator dies ausdrücklich erteilen muss und minimal notwendige Zugriffsrechte. Diese liberalen Privilegien für das öffentliche Schema sind absichtlich im System als Bequemlichkeit und für die Kompatibilität mit älteren Versionen konfiguriert.

Beachten Sie auch, dass abgesehen von den permissiven Berechtigungseinstellungen die einzige andere Besonderheit des öffentlichen Schemas darin besteht, dass es auch im Suchpfad aufgeführt ist, wie wir im vorherigen Artikel besprochen haben. Dies dient in ähnlicher Weise der Bequemlichkeit:Die search_path-Konfiguration und liberale Privilegien führen zusammen dazu, dass eine neue Datenbank verwendet werden kann, als ob es kein solches Konzept wie Schemata gäbe.

Historischer Hintergrund des öffentlichen Schemas

Diese Kompatibilitätsbedenken stammen von vor etwa fünfzehn Jahren (vor PostgreSQL-Version 7.3, vgl. Versionshinweise zu Version 7.3), als die Schema-Funktion nicht Teil von PostgreSQL war. Die Konfiguration des öffentlichen Schemas mit liberalen Privilegien und das Vorhandensein von search_path bei der Einführung von Schemas in Version 7.3 ermöglichte die Kompatibilität älterer Anwendungen, die kein Schema erkennen, um unverändert mit der aktualisierten Datenbankfunktion zu funktionieren.

Ansonsten ist das öffentliche Schema nichts Besonderes:Einige DBAs löschen es, wenn ihr Anwendungsfall keine Notwendigkeit dafür darstellt; andere sperren es, indem sie die Standardrechte widerrufen.

Zeig mir den Code – Widerrufen von Berechtigungen

Lassen Sie uns etwas Code erstellen, um das bisher Besprochene zu veranschaulichen und zu erweitern.

Schemaberechtigungen werden mit den Befehlen GRANT und REVOKE verwaltet, um Berechtigungen hinzuzufügen bzw. zu entziehen. Wir werden einige spezifische Beispiele zum Sperren des öffentlichen Schemas ausprobieren, aber die allgemeine Syntax lautet:

REVOKE [ GRANT OPTION FOR ]
    { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
    ON SCHEMA schema_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

Lassen Sie uns als erstes Beispiel für die Sperrung das Erstellungsrecht aus dem öffentlichen Schema entfernen. Beachten Sie, dass sich in diesen Beispielen das kleingeschriebene Wort „öffentlich“ auf das Schema bezieht und durch jeden anderen gültigen Schemanamen ersetzt werden kann, der möglicherweise in der Datenbank vorhanden ist. Der Großbuchstabe „PUBLIC“ ist das spezielle Schlüsselwort, das „alle Benutzer“ impliziert und stattdessen durch einen bestimmten Rollennamen oder eine durch Kommas getrennte Liste von Rollennamen für eine genauere Zugriffskontrolle ersetzt werden könnte.

sampledb=# REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE
sampledb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =U/postgres          | 
(1 row)

Der einzige Unterschied in dieser Auflistung von Schemaberechtigungen zur ersten ist das Fehlen des „C“ in der zweiten Berechtigungsspezifikation, was bestätigt, dass unser Befehl wirksam war:andere Benutzer als der Postgres-Benutzer dürfen keine Tabellen, Ansichten oder andere Objekte mehr in erstellen das öffentliche Schema.

Beachten Sie, dass der obige Befehl zum Widerrufen von Erstellungsberechtigungen aus dem öffentlichen Schema die empfohlene Risikominderung für eine kürzlich veröffentlichte Schwachstelle, CVE-2018-1058, darstellt, die sich aus der Standardeinstellung für Berechtigungen im öffentlichen Schema ergibt.

Eine weitere Ebene der Sperrung könnte darin bestehen, den Suchzugriff auf das Schema vollständig zu verweigern, indem das Nutzungsrecht entfernt wird:

sampledb=# REVOKE USAGE ON SCHEMA public FROM PUBLIC;
REVOKE
sampledb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres | standard public schema
(1 row)

Da alle verfügbaren Schema-Berechtigungen für Benutzer, die keine Eigentümer sind, widerrufen wurden, verschwindet die gesamte zweite Berechtigungsspezifikation in der obigen Auflistung.

Was wir mit zwei getrennten Befehlen gemacht haben, hätte auch mit einem einzigen Befehl erreicht werden können, der alle Privilegien wie folgt angibt:

sampledb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC;
REVOKE

Darüber hinaus ist es auch möglich, dem Schemabesitzer Berechtigungen zu entziehen:

sampledb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM postgres;
REVOKE
sampledb=# \dn+
                        List of schemas
  Name  |  Owner   | Access privileges |      Description       
--------+----------+-------------------+------------------------
 public | postgres |                   | standard public schema
(1 row)

aber das bringt nicht wirklich etwas Praktisches, da der Schemaeigentümer die vollen Privilegien für eigene Schemas behält, unabhängig von der expliziten Zuweisung einfach aufgrund des Eigentums.

Die liberale Berechtigungszuweisung für das öffentliche Schema ist ein spezielles Artefakt, das mit der anfänglichen Datenbankerstellung verbunden ist. Nachträglich erstellte Schemas in einer vorhandenen Datenbank entsprechen der Best Practice, ohne zugewiesene Berechtigungen zu starten. Beispielsweise zeigt die Untersuchung der Schemaberechtigungen nach dem Erstellen eines neuen Schemas mit dem Namen „privat“, dass das neue Schema keine Berechtigungen hat:

sampledb=# create schema private;
CREATE SCHEMA
sampledb=# \dn+
                          List of schemas
  Name   |  Owner   |  Access privileges   |      Description       
---------+----------+----------------------+------------------------
 private | postgres |                      | 
 public  | postgres |                      | standard public schema
(2 rows)
Laden Sie noch heute das Whitepaper PostgreSQL-Verwaltung und -Automatisierung mit ClusterControl herunterErfahren Sie, was Sie wissen müssen, um PostgreSQL bereitzustellen, zu überwachen, zu verwalten und zu skalierenLaden Sie das Whitepaper herunter

Zeig mir den Code – Gewähren von Privilegien

Die allgemeine Form des Befehls zum Hinzufügen von Berechtigungen lautet:

GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
    ON SCHEMA schema_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]
where role_specification can be:
  [ GROUP ] role_name
  | PUBLIC
  | CURRENT_USER
  | SESSION_USER

Mit diesem Befehl können wir beispielsweise allen Rollen erlauben, Datenbankobjekte im privaten Schema nachzuschlagen, indem wir das Nutzungsrecht mit

hinzufügen
sampledb=# GRANT USAGE ON SCHEMA private TO PUBLIC;
GRANT
sampledb=# \dn+
                          List of schemas
  Name   |  Owner   |  Access privileges   |      Description       
---------+----------+----------------------+------------------------
 private | postgres | postgres=UC/postgres+| 
         |          | =U/postgres          | 
 public  | postgres |                      | standard public schema
(2 rows)

Beachten Sie, wie die UC-Berechtigungen für den Postgres-Eigentümer als erste Spezifikation angezeigt werden, nachdem wir dem Schema jetzt andere als die Standardberechtigungen zugewiesen haben. Die zweite Spezifikation, =U/postgres, entspricht dem GRANT-Befehl, den wir gerade als Benutzer postgres aufgerufen haben, der allen Benutzern Nutzungsrechte gewährt (wobei, erinnern Sie sich, die leere Zeichenfolge links vom Gleichheitszeichen impliziert „alle Benutzer“).

Einer bestimmten Rolle, beispielsweise mit dem Namen „user1“, können sowohl Erstellungs- als auch Nutzungsrechte für das private Schema erteilt werden mit:

sampledb=# GRANT ALL PRIVILEGES ON SCHEMA private TO user1;
GRANT
sampledb=# \dn+
                          List of schemas
  Name   |  Owner   |  Access privileges   |      Description       
---------+----------+----------------------+------------------------
 private | postgres | postgres=UC/postgres+| 
         |          | =U/postgres         +| 
         |          | user1=UC/postgres    | 
 public  | postgres |                      | standard public schema
(2 rows)

Wir haben die „WITH GRANT OPTION“-Klausel des allgemeinen Befehlsformulars noch nicht erwähnt. So wie es sich anhört, erlaubt diese Klausel einer gewährten Rolle die Befugnis, selbst das angegebene Privileg anderen Benutzern zu gewähren, und es wird in der Privilegienliste durch Sternchen gekennzeichnet, die an das spezifische Privileg angehängt werden:

sampledb=# GRANT ALL PRIVILEGES ON SCHEMA private TO user1 WITH GRANT OPTION;
GRANT
sampledb=# \dn+
                          List of schemas
  Name   |  Owner   |  Access privileges   |      Description       
---------+----------+----------------------+------------------------
 private | postgres | postgres=UC/postgres+| 
         |          | =U/postgres         +| 
         |          | user1=U*C*/postgres  | 
 public  | postgres |                      | standard public schema
(2 rows)

Schlussfolgerung

Damit ist das Thema für heute abgeschlossen. Als letzte Anmerkung sollten Sie jedoch daran denken, dass wir nur Schema-Zugriffsrechte besprochen haben. Während das USAGE-Privileg die Suche nach Datenbankobjekten in einem Schema ermöglicht, um tatsächlich auf die Objekte für bestimmte Operationen wie Lesen, Schreiben, Ausführen usw. zuzugreifen, muss die Rolle auch über entsprechende Privilegien für diese Operationen an diesen spezifischen Datenbankobjekten verfügen.