Verwenden von sicheren Ansichten

Unter diesem Thema werden Konzepte und Syntax zum Definieren von sicheren Ansichten und materialisierten Ansichten behandelt.

Unter diesem Thema:

Übersicht zu sicheren Ansichten

Welchem Zweck dienen sichere Ansichten?

  • Bei einer nicht sicheren Ansicht können interne Optimierungen indirekt zur Offenlegung von Daten führen.

    Einige der internen Optimierungsmethoden für Ansichten erfordern Zugriff auf die zugrunde liegenden Daten in den Basistabellen der Ansicht. Dieser Zugriff führt möglicherweise dazu, dass Daten, die für Benutzer der Ansicht eigentlich verborgen sind, durch Benutzercode, z. B. benutzerdefinierte Funktionen oder andere programmgesteuerte Methoden, zur Anzeige gebracht werden. Bei sicheren Ansichten werden diese Optimierungsmethoden nicht verwendet, sodass sichergestellt ist, dass Benutzer keinen Zugriff auf die zugrunde liegenden Daten haben.

  • Bei einer nicht sicheren Ansicht ist die Ansichtsdefinition für andere Benutzer sichtbar.

    Standardmäßig ist der Abfrageausdruck, der zum Erstellen einer Standardansicht (auch als Ansichtsdefinition oder Ansichtstext bezeichnet) verwendet wird, in verschiedenen Befehlen und Schnittstellen für Benutzer sichtbar. Weitere Details dazu finden Sie unter Interagieren mit sicheren Ansichten (unter diesem Thema).

    Aus Sicherheits- oder Datenschutzgründen möchten Sie möglicherweise nicht, dass die zugrunde liegenden Tabellen oder internen strukturellen Details einer Ansicht verfügbar sind. Bei sicheren Ansichten sind Ansichtsdefinition und Details nur für berechtigte Benutzer sichtbar, d. h. für Benutzer, denen die Rolle zugewiesen wurde, der die Ansicht gehört.

Wann sollten sichere Ansichten verwendet werden?

Ansichten sollten als sicher definiert werden, wenn sie speziell für den Datenschutz bestimmt sind, d. h. um den Zugriff auf vertrauliche Daten zu beschränken, die nicht allen Benutzern der zugrunde liegenden Tabelle(n) zugänglich sein sollen.

Sichere Ansichten sollten nicht für Ansichten verwendet werden, die ausschließlich zur Abfragevereinfachung definiert wurden, z. B. Ansichten zum Vereinfachen von Abfragen, für die Benutzer die zugrunde liegende Datenrepräsentation nicht verstehen müssen. Die Ausführung von sichern Ansichten kann länger dauern als die Ausführung von nicht sicheren Ansichten.

Tipp

Bei der Entscheidung, ob eine sichere Ansicht verwendet werden soll, sollten Sie den Zweck der Ansicht berücksichtigen und zwischen Datenschutz/Sicherheit und Abfrageleistung abwägen.

Wie werden Daten durch nicht sichere Ansichten offengelegt?

Betrachten Sie anhand des folgenden Widget-Beispiels einen Benutzer, der nur Zugriff auf die roten Widgets hat. Der Benutzer fragt sich, ob ein violetter Widget vorhanden ist, und führt die folgende Abfrage aus:

SELECT *
    FROM widgets_view
    WHERE 1/iff(color = 'Purple', 0, 1) = 1;

Wenn violette Widgets vorhanden sind, gibt der IFF()-Ausdruck den Wert 0 zurück. Die Division scheitert dann aufgrund eines Fehlers bei der Division durch Null, woraus der Benutzer schließen kann, dass mindestens ein violettes Widget existiert.

Erstellen von sicheren Ansichten

Eine sichere Ansicht wird erstellt, indem beim Definieren der Ansicht mit Standard-DDL das Schlüsselwort SECURE verwendet wird:

  • Geben Sie zum Erstellen einer sicheren Ansicht das Schlüsselwort SECURE im Befehl CREATE VIEW oder CREATE MATERIALIZED VIEW an.

  • Um eine vorhandene Ansicht in eine sichere Ansicht bzw. zurück in eine reguläre Ansicht zu konvertieren, müssen Sie das Schlüsselwort SECURE im Befehl ALTER VIEW oder ALTER MATERIALIZED VIEW angeben bzw. entfernen.

Interagieren mit sicheren Ansichten

Anzeigen der Definition von sicheren Ansichten

Die Definition einer sicheren Ansicht ist nur für berechtigte Benutzer verfügbar (d. h. für Benutzer, denen die Rolle zugewiesen wurde, der die Ansicht gehört). Wenn ein nicht autorisierter Benutzer einen der folgenden Befehle oder eine der folgenden Schnittstellen verwendet, wird die Definition nicht angezeigt:

Ermitteln, ob eine Ansicht sicher ist

Bei nicht materialisierten Ansichten gibt die Spalte IS_SECURE in Information Schema- und Account Usage-Ansichten an, ob eine Ansicht sicher ist. Beispiel für eine Ansicht mit dem Namen MYVIEW in der Datenbank mydb:

Information Schema:

select table_catalog, table_schema, table_name, is_secure
    from mydb.information_schema.views
    where table_name = 'MYVIEW';

Account Usage:

select table_catalog, table_schema, table_name, is_secure
    from snowflake.account_usage.views
    where table_name = 'MYVIEW';

(Allgemeine Informationen zu den Unterschieden zwischen INFORMATION_SCHEMA-Ansichten und ACCOUNT_USAGE-Ansichten finden Sie unter Unterschiede zwischen Account Usage und Information Schema).

Alternativ können Sie den Befehl SHOW VIEWS verwenden, um ähnliche Informationen anzuzeigen (beachten Sie, dass bei dem Anzeigenamen die Groß-/Kleinschreibung nicht berücksichtigt wird):

SHOW VIEWS LIKE 'myview';

Verwenden Sie bei nicht materialisierten Ansichten den Befehl SHOW MATERIALIZED VIEWS, um festzustellen, ob eine Ansicht sicher ist. Beispiel:

SHOW MATERIALIZED VIEWS LIKE 'my_mv';

Anzeigen von Details der sicheren Ansicht in Query Profile

Die internen Details einer sicheren Ansicht werden nicht in Query Profile (auf der Weboberfläche) angezeigt. Dies gilt sogar für den Eigentümer der sicheren Ansichten, da Nicht-Eigentümer möglicherweise auf das Query Profile eines Eigentümers zugreifen können.

Verwenden von sicheren Ansichten mit der Snowflake-Zugriffssteuerung

Die Sicherheit für Ansichten kann einem Snowflake-Benutzer bzw. einer Snowflake-Rolle mit den Kontextfunktionen CURRENT_ROLE und CURRENT_USER hinzugefügt werden. Das folgende Beispiel veranschaulicht die Verwendung von Rollen zum Steuern des Zugriffs auf die Zeilen einer Tabelle. Neben der Tabelle mit den Daten (widgets) wird im Beispiel auch eine Zugriffstabelle (widget_access_rules) verwendet, um zu verfolgen, welche Rollen Zugriff auf welche Zeilen in der Datentabelle haben:

CREATE TABLE widgets (
    id NUMBER(38,0) DEFAULT widget_id_sequence.nextval, 
    name VARCHAR,
    color VARCHAR,
    price NUMBER(38,0),
    created_on TIMESTAMP_LTZ(9));
CREATE TABLE widget_access_rules (
    widget_id NUMBER(38,0),
    role_name VARCHAR);
CREATE OR REPLACE SECURE VIEW widgets_view AS
    SELECT w.*
        FROM widgets AS w
        WHERE w.id IN (SELECT widget_id
                           FROM widget_access_rules AS a
                           WHERE upper(role_name) = CURRENT_ROLE()
                      )
    ;

Die WHERE-Klausel schränkt ein, welche Widgets jeder Rolle angezeigt werden.

Angenommen, ein Benutzer, der nur Zugriff auf rote Widgets hat, führt die oben gezeigte Abfrage aus:

SELECT *
    FROM widgets_view
    WHERE 1/iff(color = 'Purple', 0, 1) = 1;

Die WHERE-Klausel der sicheren Ansicht wird vor jeder WHERE-Klausel in der Abfrage des Benutzers ausgeführt. Da violette Widgets von der Ansicht ausgeschlossen sind, führt die Abfrage des Benutzers nie zu einem Fehler aufgrund einer Division durch Null.

Wenn die Ansicht nicht sicher wäre, könnte der Snowflake-Optimierer die Prädikate in den WHERE-Klauseln neu anordnen. Dies könnte dazu führen, dass das Prädikat in der Abfrage des Benutzers zuerst ausgeführt wird, was einen Fehler aufgrund einer Division durch Null zur Folge hätte.

Best Practices für die Verwendung von sicheren Ansichten

Sichere Ansichten verhindern, dass Benutzern möglicherweise Daten aus Tabellenzeilen offengelegt werden, die von der Ansicht gefiltert werden. Es gibt jedoch immer noch Möglichkeiten, dass ein Dateneigentümer versehentlich Informationen über die zugrunde liegenden Daten preisgibt, wenn Ansichten nicht sorgfältig konstruiert sind. In diesem Abschnitt werden einige mögliche Gefahren erläutert, die vermieden werden müssen.

Um diese Gefahren zu veranschaulichen, verwenden wir die in den vorherigen Beispielen unter diesem Thema definierten widgets-Beispieltabellen und die Ansicht.

Sequenzgenerierte Spalten

Eine gängige Praxis zum Generieren von Ersatzschlüsseln ist die Verwendung einer Sequenz oder einer Spalte mit automatischer Inkrementierung. Wenn diese Schlüssel für Benutzer verfügbar sind, die keinen Zugriff auf alle zugrunde liegenden Daten haben, kann ein Benutzer möglicherweise Details der zugrunde liegenden Datenverteilung ableiten. Beispielsweise legt widgets_view die Spalte ID offen. Wenn ID aus einer Sequenz generiert wird, kann ein Benutzer von widgets_view die Gesamtanzahl der erstellten Widgets ableiten, die zwischen den Erstellungszeitstempeln von zwei Widgets erstellt wurden, auf die der Benutzer Zugriff hat. Betrachten Sie die folgende Abfrage und ihr Ergebnis:

select * from widgets_view order by created_on;

------+-----------------------+-------+-------+-------------------------------+
  ID  |         NAME          | COLOR | PRICE |          CREATED_ON           |
------+-----------------------+-------+-------+-------------------------------+
...
 315  | Small round widget    | Red   | 1     | 2017-01-07 15:22:14.810 -0700 |
 1455 | Small cylinder widget | Blue  | 2     | 2017-01-15 03:00:12.106 -0700 |
...

Basierend auf dem Ergebnis könnte der Benutzer vermuten, dass zwischen 7. Januar und 15. Januar 1.139 Widgets (1455 - 315) erstellt wurden. Wenn diese Information zu sensibel ist, um sie Benutzern offenzulegen, können Sie eine der folgenden Alternativen verwenden:

  • Legen Sie die sequenzgenerierte Spalte nicht als Teil der Ansicht offen.

  • Verwenden Sie anstelle der sequenzgenerierten Werte zufällige Bezeichner (z. B. generiert durch UUID_STRING).

  • Programmieren Sie eine Verschleierung der Bezeichner.

Größe der gescannten Daten

Für Abfragen, die sichere Ansichten enthalten, legt Snowflake weder den Umfang der gescannten Daten (in Byte oder in Mikropartitionen) noch die Gesamtdatenmenge offen. Dies dient zum Schutz der Informationen vor Benutzern, die nur Zugriff auf eine Teilmenge der Daten haben. Benutzer sind jedoch möglicherweise weiterhin in der Lage, anhand der Performance der Abfragen Rückschlüsse auf den Umfang der zugrunde liegenden Daten zu ziehen. Beispielsweise kann eine Abfrage, die doppelt so lange ausgeführt wird, doppelt so viele Daten verarbeiten. Während solche Beobachtungen bestenfalls Annäherungen sind, kann es in manchen Fällen unerwünscht sein, dass sogar diese Art von Informationen offengelegt wird.

In solchen Fällen ist es am besten, Daten pro Benutzer/Rolle zu materialisieren, anstatt den Benutzern Ansichten der Basisdaten anzuzeigen. Im Fall der Tabelle widgets würde für jede Rolle, die Zugriff auf Widgets hat, eine Tabelle erstellt werden, die nur die Widgets enthält, auf die diese Rolle zugreifen kann, und der Rolle würde Zugriff auf ihre Tabelle gewährt werden. Dies ist viel umständlicher als die Verwendung einer einzelnen Ansicht, kann jedoch in extrem hochsicheren Situationen gerechtfertigt sein.

Sichere Ansichten und Data Sharing

Bei Verwendung sicherer Ansichten mit Sicheres Freigeben von Daten in Snowflake kann die Funktion CURRENT_ACCOUNT verwendet werden, um Benutzer eines bestimmten Kontos für den Zugriff auf Zeilen einer Basistabelle zu autorisieren.

Bemerkung

Wenn Sie die Funktionen CURRENT_ROLE und CURRENT_USER mit sicheren Ansichten verwenden, die für Snowflake-Konten freigegeben sind, gibt Snowflake einen NULL-Wert für diese Funktionen zurück. Der Grund dafür ist, dass der Eigentümer der freigegebenen Daten in der Regel nicht die Kontrolle über die Benutzer oder Rollen in dem Konto hat, für das die Ansicht freigegeben ist.

Zurück zum Anfang