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?

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.

Außerdem ist standardmäßig 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 für die Abfrageerleichterung definiert sind, z. B. Ansichten zum Vereinfachen der Abfrage von Daten, für die Benutzer die zugrunde liegende Datenrepräsentation nicht verstehen müssen. Dies liegt daran, dass der Snowflake-Abfrageoptimierer beim Auswerten von sicheren Ansichten bestimmte, für reguläre Ansichten verwendete Optimierungen umgeht. Dies kann Auswirkungen auf die Abfrageleistung von sicheren Ansichten haben.

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 eine kleine Teilmenge von Widgets hat. Alle Widgets sind rot. 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 widgets_view keine sichere Ansicht ist, generiert diese Abfrage bei Vorhandensein eines violetten Widgets möglicherweise einen Fehler, obwohl der aktuelle Benutzer keinen Zugriff auf dieses Widget hat. Beachten Sie, dass die Fehlergenerierung davon abhängt, ob der Abfrageoptimierer den Filter des Benutzers vor oder nach dem Autorisierungsprädikat (in der IN-Unterabfrage) auswertet. Wenn widgets_view eine sichere Ansicht ist, wertet der Abfrageoptimierer den Filter des Benutzers erst nach dem Autorisierungsprädikat aus.

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:

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

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

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:

Bemerkung

In diesem Beispiel wird davon ausgegangen, dass die Tabellen widgets und widget_access_rules bereits vorhanden sind. Das Beispiel enthält keine Syntax zum Erstellen der Tabellen oder zum Auffüllen dieser mit Daten.

desc table widgets;

------------+-------------------+--------+-------+---------+-------------+------------+--------+------------+---------+
    name    |       type        |  kind  | null? | default | primary key | unique key | check  | expression | comment |
------------+-------------------+--------+-------+---------+-------------+------------+--------+------------+---------+
 ID         | NUMBER(38,0)      | COLUMN | Y     | [NULL]  | N           | N          | [NULL] | [NULL]     | [NULL]  |
 NAME       | VARCHAR(16777216) | COLUMN | Y     | [NULL]  | N           | N          | [NULL] | [NULL]     | [NULL]  |
 COLOR      | VARCHAR(16777216) | COLUMN | Y     | [NULL]  | N           | N          | [NULL] | [NULL]     | [NULL]  |
 PRICE      | NUMBER(38,0)      | COLUMN | Y     | [NULL]  | N           | N          | [NULL] | [NULL]     | [NULL]  |
 CREATED_ON | TIMESTAMP_LTZ(9)  | COLUMN | Y     | [NULL]  | N           | N          | [NULL] | [NULL]     | [NULL]  |
------------+-------------------+--------+-------+---------+-------------+------------+--------+------------+---------+

desc table widget_access_rules;

-----------+-------------------+--------+-------+---------+-------------+------------+--------+------------+---------+
   name    |       type        |  kind  | null? | default | primary key | unique key | check  | expression | comment |
-----------+-------------------+--------+-------+---------+-------------+------------+--------+------------+---------+
 WIDGET_ID | NUMBER(38,0)      | COLUMN | Y     | [NULL]  | N           | N          | [NULL] | [NULL]     | [NULL]  |
 ROLE_NAME | VARCHAR(16777216) | COLUMN | Y     | [NULL]  | N           | N          | [NULL] | [NULL]     | [NULL]  |
-----------+-------------------+--------+-------+---------+-------------+------------+--------+------------+---------+

create or replace secure view widgets_view as
select w.*
from widgets w
where w.id in (select widget_id
               from widget_access_rules a
               where upper(role_name) = CURRENT_ROLE());

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

Snowflake empfiehlt, CURRENT_ROLE und CURRENT_USER nicht in sicheren Ansichten zu verwenden, die für andere Konten freigegeben werden, da der Eigentümer der freigegebenen Daten normalerweise nicht die Rollen und Benutzer des Kontos kontrollieren kann, für das sie freigegeben wurden.