Anwendungsdatensicherheit mit parametrisierten sicheren AlloyDB-Ansichten verwalten

Mit parametrisierten sicheren Ansichten in AlloyDB for PostgreSQL können Sie den Zeilenzugriff anhand von anwendungsspezifischen benannten Parametern wie Anmeldedaten von Anwendungsnutzern einschränken. Diese Ansichten erweitern PostgreSQL-Ansichten, um Ihre Datenbank beim Ausführen nicht vertrauenswürdiger Abfragen zu schützen. Dazu werden automatisch Einschränkungen für jede Abfrage erzwungen.

Weitere Informationen finden Sie unter Übersicht über parametrisierte sichere Ansichten und Zugriff auf Anwendungsdaten mit parametrisierten sicheren Ansichten sichern und steuern.

Hinweis

Auf dieser Seite wird davon ausgegangen, dass Sie einen AlloyDB-Cluster und eine AlloyDB-Instanz erstellt haben. Weitere Informationen finden Sie unter Datenbank erstellen.

Bevor Sie parametrisierte sichere Ansichten verwenden können, müssen Sie Folgendes tun:

  1. Aktivieren Sie das Datenbank-Flag parameterized_views.enabled, mit dem die erforderlichen Erweiterungsbibliotheken geladen werden. Sie müssen dieses Flag aktivieren, auch wenn es zuvor vom AlloyDB-Team aktiviert wurde. Weitere Informationen zum Aktivieren des Datenbank-Flags finden Sie unter Datenbank-Flags einer Instanz konfigurieren.

  2. Verwenden Sie AlloyDB Studio oder psql, um die Erweiterung parameterized_views in jeder Datenbank zu erstellen, in der Sie eine parametrisierte Ansicht erstellen möchten:

    -- Requires parameterized_views.enabled set to true
    CREATE EXTENSION parameterized_views;
    

    Wenn die Erweiterung erstellt wird, erstellt das System auch ein Schema mit dem Namen parameterized_views. So sind die APIs im Namespace dieses Schemas enthalten und geraten nicht mit vorhandenen APIs in Konflikt.

Parametrisierte sichere Ansicht erstellen

So erstellen Sie eine parametrisierte sichere Ansicht:

  1. Führen Sie den DDL-Befehl CREATE VIEW aus, wie im folgenden Beispiel gezeigt:

    CREATE VIEW secure_checked_items WITH (security_barrier) AS
    SELECT bag_id, timestamp, location
    FROM checked_items t
    WHERE customer_id = $@app_end_userid;
    

    Im vorherigen Beispiel ermöglicht die parametrisierte sichere Ansicht den Zugriff auf drei Spalten aus einer Tabelle mit dem Namen checked_items. In der Ansicht werden die Ergebnisse auf Zeilen beschränkt, in denen checked_items.customer_id mit einem erforderlichen Parameter übereinstimmt.

    Verwenden Sie die folgenden Attribute:

    • Erstellen Sie die Ansicht mit der Option security_barrier.
    • Wenn Sie Anwendungsnutzer so einschränken möchten, dass sie nur die Zeilen sehen können, auf die sie zugreifen dürfen, fügen Sie die erforderlichen Parameter in der Ansichtsdefinition mit der Syntax $@PARAMETER_NAME hinzu. Ein häufiger Anwendungsfall ist die Prüfung des Werts einer Spalte in der WHERE-Klausel mit COLUMN = $@PARAMETER_NAME.
    • $@PARAMETER_NAME gibt einen benannten Ansichtsparameter an. Der Wert wird angegeben, wenn Sie die execute_parameterized_query API verwenden. Für benannte Ansichtsparameter gelten die folgenden Anforderungen:
      • Benannte Ansichtsparameter müssen mit einem Buchstaben (a–z) beginnen.
      • Sie können Buchstaben mit diakritischen Zeichen und nicht lateinische Buchstaben sowie einen Unterstrich (_) verwenden.
      • Nachfolgende Zeichen können Buchstaben, Unterstriche oder Ziffern (0–9) sein.
      • Benannte Ansichtsparameter dürfen keine $ enthalten.
      • Bei benannten Ansichtsparametern wird zwischen Groß- und Kleinschreibung unterschieden. $@PARAMETER_NAME wird beispielsweise anders interpretiert als $@parameter_name.
  2. Gewähren Sie allen Datenbanknutzern, die die Ansicht abfragen dürfen, SELECT für die Ansicht.

  3. Gewähren Sie allen Datenbanknutzern, die die Ansicht abfragen dürfen, USAGE für das Schema, das die in der Ansicht definierten Tabellen enthält.

Weitere Informationen finden Sie unter Zugriff auf Anwendungsdaten mit parametrisierten sicheren Ansichten sichern und steuern.

Sicherheit für Ihre Anwendung konfigurieren

So konfigurieren Sie die Sicherheit für Ihre Anwendungen mit parametrisierten sicheren Ansichten:

  1. Erstellen Sie die sicheren parametrisierten Ansichten als Nutzer mit Administratorzugriff. Dieser Nutzer ist ein AlloyDB-Datenbanknutzer, der administrative Vorgänge für die Anwendung ausführt, einschließlich Datenbankeinrichtung und Sicherheitsverwaltung.

  2. Erstellen Sie eine neue Datenbankrolle zum Ausführen von Abfragen für parametrisierte sichere Ansichten. Dies ist eine AlloyDB-Datenbankrolle, die von der Anwendung verwendet wird, um eine Verbindung zur Datenbank herzustellen, sich anzumelden und Abfragen für parametrisierte Ansichten auszuführen.

    1. Der neuen Rolle Berechtigungen für sichere Ansichten gewähren, was in der Regel SELECT-Berechtigungen für die Ansichten und USAGE für die Schemas umfasst.

    2. Beschränken Sie die Objekte, auf die diese Rolle zugreifen kann, auf die minimal erforderlichen öffentlichen Funktionen und Objekte, die die Anwendung benötigt. Gewähren Sie keinen Zugriff auf Schemas und Tabellen, die nicht öffentlich sind.

    3. Um Sicherheitsrisiken zu minimieren, sollten Sie den Zugriff dieser Rolle auf alle sensiblen Schemas oder Objekte widerrufen, die nicht unbedingt für die Rolle erforderlich sind.

    Wenn Sie die Ansichten abfragen, stellt die Anwendung die Werte der erforderlichen Ansichtsparameter bereit, die an die Identität des Anwendungsnutzers gebunden sind.

    Weitere Informationen zum Erstellen von Datenbanknutzern finden Sie unter Datenbanknutzer erstellen.

Parametrisierte sichere Ansicht abfragen

Verwenden Sie eine der folgenden Optionen, die Ihren Anwendungsfall am besten unterstützt, um eine parametrisierte sichere Ansicht abzufragen:

  • JSON-basiert: Verwenden Sie diese API, um die Abfrage in einem Durchgang auszuführen und JSON-Zeilen zurückzugeben.

  • CURSOR-basiert: Verwenden Sie diese API, wenn Sie Abfragen mit längerer Laufzeit oder große Abfragen haben und das Ergebnis in Batches abrufen möchten. Die Funktion execute_parameterized_query, die von der Erweiterung parameterized_views bereitgestellt wird, akzeptiert einen Cursornamen.

  • PREPARE EXECUTE-Anweisung: Verwenden Sie diese für vorbereitete Anweisungen, die mehrmals mit unterschiedlichen Parameterwerten ausgeführt werden können.

Wenn Sie parametrisierte sichere Ansichten abfragen möchten, verwenden Sie die Funktion execute_parameterized_query(), die von der Erweiterung parameterized_views bereitgestellt wird.

JSON API

Führen Sie die Funktion execute_parameterized_query() aus, die die folgende Syntax hat:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => SQL_QUERY,
    param_names => ARRAY [PARAMETER_NAMES],
    param_values => ARRAY [PARAMETER_VALUES]
)

Ersetzen Sie Folgendes:

  • SQL_QUERY: Eine SQL-Abfrage, deren FROM-Klausel auf eine oder mehrere parametrisierte sichere Ansichten verweist.

  • PARAMETER_NAMES: Eine Liste von Parameternamen, die als Strings übergeben werden sollen.

  • PARAMETER_VALUES: Eine Liste der zu übergebenden Parameterwerte.

    • Diese Liste muss dieselbe Größe wie die Liste param_names haben, wobei die Reihenfolge der Werte der Reihenfolge der Namen entspricht.

    • Der genaue Typ der Werte wird aus der Abfrage und der Definition der parametrisierten Ansicht abgeleitet. Typkonvertierungen werden bei Bedarf und wenn möglich für den angegebenen Parameterwert durchgeführt. Bei einer Typabweichung wird ein Fehler ausgegeben.

Die Funktion gibt eine Tabelle mit JSON-Objekten zurück. Jede Zeile in der Tabelle entspricht dem ROW_TO_JSON()-Wert der ursprünglichen Abfrageergebniszeile.

Verwenden Sie das folgende Beispiel, um eine parametrisierte sichere Ansicht abzufragen:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => 'SELECT * FROM secure_checked_items',
    param_names => ARRAY ['app_end_userid'],
    param_values => ARRAY ['40']
)

Bei Verwendung dieser API wird die Größe des Ergebnisses durch die Größe in Kilobyte (kB) der Ergebnisse und durch die Anzahl der Zeilen begrenzt. Sie können diese Limits mit den Flags parameterized_views.json_results_max_size und parameterized_views.json_results_max_rows konfigurieren.

CURSOR API

Diese API hat Einschränkungen, da sie einen Cursor für die angegebene Abfrage deklariert. Daher muss die Abfrage mit PostgreSQL-Cursorn kompatibel sein. Die CURSOR API unterstützt beispielsweise keine DO- oder SHOW-Anweisungen.

Diese API schränkt die Ergebnisse auch nicht nach Größe oder Anzahl der zurückgegebenen Zeilen ein.

Führen Sie die Funktion execute_parameterized_query() aus, die einen transaktionsbezogenen CURSOR erstellt und zurückgibt, mit dem Sie Abfrageergebnisse abrufen können:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => SQL_QUERY,
    cursor_name => CURSOR_NAME,
    param_names => ARRAY [PARAMETER_NAMES],
    param_values => ARRAY [PARAMETER_VALUES]
)

Ersetzen Sie Folgendes:

  • SQL_QUERY: Eine SQL-Abfrage, deren FROM-Klausel auf eine oder mehrere parametrisierte sichere Ansichten verweist.

  • CURSOR_NAME: der Name des zu deklarierenden Cursors.

  • PARAMETER_NAMES: Eine Liste von Parameternamen, die als Strings übergeben werden sollen.

  • PARAMETER_VALUES: Eine Liste der zu übergebenden Parameterwerte. Diese Liste muss dieselbe Größe wie die Liste param_names haben, wobei die Reihenfolge der Werte der Reihenfolge der Namen entspricht. Der genaue Typ der Werte wird aus der Abfrage und der parametrisierten Ansichtsdefinition abgeleitet. Typkonvertierungen werden bei Bedarf und wenn möglich für den angegebenen Parameterwert durchgeführt. Bei einer Typabweichung wird ein Fehler ausgegeben.

Verwenden Sie das folgende Beispiel, um eine parametrisierte sichere Ansicht abzufragen:

  -- Start a transaction, which is the default lifetime of a CURSOR
  BEGIN;
  -- Create a cursor called 'mycursor'
  SELECT * FROM parameterized_views.execute_parameterized_query(
   query => 'SELECT * FROM secure_checked_items',
   cursor_name => 'mycursor',
   param_names => ARRAY ['app_end_userid'],
   param_values => ARRAY ['40']
  );

  -- Fetch the results
  FETCH ALL FROM mycursor;
  -- End the transaction, which cleans up the cursor
  END;

Der zurückgegebene Cursor ist ein NO SCROLL-Cursor WITHOUT HOLD. Sie können den Cursor nicht verwenden, um Zeilen nicht sequenziell abzurufen, z. B. in umgekehrter Richtung. Sie können den Cursor nicht außerhalb der Transaktion verwenden, in der er erstellt wurde.

PREPARE-Anweisung

Verwenden Sie den Befehl PREPARE .. AS RESTRICTED, um ein vorbereitetes Statement zu erstellen, das auf parametrisierte Ansichten verweist. Diese vorbereiteten Anweisungen unterstützen Positionsparameter und erzwingen verschiedene Einschränkungen, wenn Sie sie ausführen. Weitere Informationen dazu, wie parametrisierte sichere Ansichten die Sicherheit erzwingen, finden Sie unter Sicherheitsmechanismus.

Diese Funktion erweitert die Befehle PREPARE und EXECUTE, um benannte Ansichtsparameter zu unterstützen. Verwenden Sie vorbereitete Anweisungen, um den Aufwand für das Parsen, Analysieren und Neuschreiben bei jeder Ausführung der Anweisung zu vermeiden. Dies kann zu erheblichen Leistungssteigerungen führen, insbesondere bei häufig ausgeführten oder komplexen Abfragen. Eine vorbereitete Anweisung ist ein serverseitiges Objekt, das die Leistung optimieren kann, indem eine parametrisierte SQL-Anweisung für die spätere Ausführung vorkompiliert und gespeichert wird.

Diese API hat Einschränkungen, da die Anweisung in einer PREPARE-Anweisung zulässig sein muss. Das bedeutet, dass nur SELECT- und VALUES-Anweisungen unterstützt werden.

Diese API schränkt die Ergebnisse auch nicht nach Größe oder Anzahl der zurückgegebenen Zeilen ein.

Führen Sie den Befehl PREPARE .. AS RESTRICTED aus, um ein vorbereitetes Statement zu erstellen, das auf parametrisierte Ansichten verweist:

PREPARE pquery (POSITIONAL_PARAM_TYPES)
        AS RESTRICTED SQL_QUERY;
EXECUTE pquery (POSITIONAL_PARAM_VALUES)
      WITH VIEW PARAMETERS (VIEW_PARAM_NAME1 = VIEW_PARAM_VALUE1[, ...]);

Ersetzen Sie Folgendes:

  • POSITIONAL_PARAM_TYPES: ein oder mehrere Datentypen für Positionsparameter, die in der RESTRICTED-Abfrage verwendet werden.

  • SQL_QUERY: Eine SQL-Abfrage, die auf parametrisierte Ansichten verweisen kann.

  • POSITIONAL_PARAM_VALUES: Die tatsächlichen Werte, die für die in der PREPARE-Anweisung definierten Positionsparameter eingesetzt werden.

  • VIEW_PARAM_NAME: Der Name des Parameters, der von den parametrisierten Ansichten erwartet wird, auf die in der RESTRICTED-Abfrage verwiesen wird.

  • VIEW_PARAM_VALUE: Die tatsächlichen Werte, die an die entsprechenden VIEW_PARAM_NAME-Parameter der parametrisierten Ansichten übergeben werden.

Wenn Sie Parameter in eine vorbereitete Anweisung einfügen möchten, geben Sie in der PREPARE-Anweisung eine Liste von Datentypen an. In der Anweisung, die Sie vorbereiten, verweisen Sie auf die Parameter nach Position, z. B. mit $1 und $2.

Verwenden Sie den Befehl EXECUTE .. WITH VIEW PARAMETERS, um eine zuvor vorbereitete Anweisung auszuführen, die Sie mit dem Befehl PREPARE .. AS RESTRICTED erstellt haben. Wenn in der PREPARE-Anweisung, mit der die Anweisung erstellt wurde, Positionsparameter angegeben wurden, müssen Sie einen kompatiblen Satz von Parametern an die EXECUTE-Anweisung übergeben. Sie müssen alle benannten Ansichtsparameter, die für parametrisierte Ansichten erforderlich sind, in der WITH VIEW PARAMETERS-Klausel übergeben.

Verwenden Sie das folgende Beispiel, um eine parametrisierte sichere Ansicht abzufragen:

PREPARE pquery (timestamp) AS RESTRICTED SELECT * FROM secure_checked_items WHERE timestamp > $1;

EXECUTE pquery (current_date - 1) WITH VIEW PARAMETERS (app_end_userid = 40);
EXECUTE pquery (current_date - 30) WITH VIEW PARAMETERS (app_end_userid = 40);

Erzwungene Einschränkungen für Abfragen

Im Folgenden sind die eingeschränkten Vorgänge für Abfragen aufgeführt, die Sie mit den unter Parametrisierte sichere Ansicht abfragen beschriebenen Optionen ausführen:

  • Der rekursive Aufruf von APIs – execute_parameterized_query oder mithilfe von EXECUTE .. WITH VIEW PARAMETERS – ist verboten, sodass nur die von der Anwendung angegebenen Werte verwendet werden. Diese Einschränkung verhindert auch, dass die Abfrage verwendet wird, um die Sicherheitsumgebung der angegebenen Parameterwerte zu umgehen.

  • Einige Erweiterungen, die eine neue Hintergrundsitzung starten, sind nicht zulässig, darunter die Erweiterungen dblink, pg_cron und pg_background.

  • Die folgenden Abfragekonstrukte sind zulässig oder eingeschränkt:

    • Schreibgeschützte SELECT-Anweisungen sind zulässig.

    • Schreibgeschützte SHOW-Anweisungen, CALL-Anweisungen und DO-Anweisungen sind zulässig.

    • DML-Anweisungen wie INSERT, UPDATE und DELETE sind nicht zulässig.

    • DDL-Anweisungen wie CREATE TABLE und ALTER TABLE sind nicht zulässig.

    • Andere Anweisungstypen wie LOAD, SET, CLUSTER, LOCK, CHECKPOINT und EXPLAIN sind nicht zulässig.

  • EXPLAIN-Anweisungen sind standardmäßig nicht zulässig, um die Möglichkeit von Angriffen über verdeckte Kanäle mithilfe von Abfrageplänen zu vermeiden. Weitere Informationen finden Sie unter Verdeckter Kanal. Zum Ausführen von EXPLAIN-Anweisungen kann jedoch jeder Datenbanknutzer mit AlloyDB-Superuser-Berechtigungen die GUC parameterized_views.enable_explain auf Sitzungsebene auf on setzen.

  • Parametrisierte sichere Ansichten bieten Einstellungen, mit denen Sie Ressourcen verwalten können, die von den APIs zum Abfragen parametrisierter Ansichten verwendet werden, z. B. parameterized_views.statement_timeout. Weitere Informationen finden Sie unter Unterstützte Datenbank-Flags.

Alle parametrisierten Ansichten auflisten

Verwenden Sie die Erweiterung parameterized_views, um alle parametrisierten Ansichten in der Datenbank mithilfe der Ansicht all_parameterized_views aufzulisten. Die Ausgabe dieser Ansicht ist mit der Katalogansicht pg_views identisch, aber all_parameterized_views listet nur Ansichten mit benannten Ansichtsparametern auf.

Führen Sie die folgende Abfrage aus, um parametrisierte Ansichten aufzulisten:

SELECT * FROM parameterized_views.all_parameterized_views;

Die Ausgabe sieht etwa so aus:

schemaname |       viewname       | viewowner |                       definition
-----------+----------------------+-----------+---------------------------------------------------------
public     | secure_checked_items | postgres  |  SELECT checked_items.bag_id,                          +
           |                      |           |     checked_items."timestamp",                         +
           |                      |           |     checked_items.location                             +
           |                      |           |    FROM checked_items                                  +
           |                      |           |   WHERE (checked_items.customer_id = $@app_end_userid);

Wenn Sie eine parametrisierte Ansicht in all_parameterized_views auflisten möchten, muss die parametrisierte Ansicht mindestens einen benannten Ansichtsparameter in ihrer Definition enthalten.

Nächste Schritte