Schutz sensibler Informationen mit sicheren UDFs und gespeicherten Prozeduren

Um sicherzustellen, dass sensible Informationen vor Benutzern verborgen bleiben, die keinen Zugriff darauf haben sollten, können Sie beim Erstellen einer benutzerdefinierten Funktion (UDF) oder einer gespeicherten Prozedur das Schlüsselwort SECURE verwenden.

Unter diesem Thema werden folgende Aktionen beschrieben:

Unter diesem Thema:

Begrenzen der Sichtbarkeit der Definition einer UDF oder Prozedur

Für eine UDF oder gespeicherte Prozedur können Sie verhindern, dass Benutzern die Definitionsspezifikationen offengelegt werden. Wenn Sie angeben, dass die UDF oder Prozedur sicher ist, sind diese Details nur für autorisierte Benutzer sichtbar, d. h. für Benutzer, denen eine Rolle zugewiesen wurde, die Eigentümer der Funktion ist.

Bei einer sicheren Funktion oder Prozedur bleiben nicht autorisierten Benutzern beispielsweise folgende Informationen verborgen:

  • Textkörper bzw. Body (Handler-Code mit der Verarbeitungslogik)

  • Liste der Importe

  • Handler-Name

  • Liste der Pakete

Nicht autorisierte Benutzer können immer noch folgende Informationen einsehen:

  • Parametertypen

  • Rückgabetyp

  • Sprache des Handlers

  • Behandlung von Nullwerten

  • Volatilität

Weitere Informationen zum Zuweisen von Rollen finden Sie unter GRANT ROLE und Übersicht zur Zugriffssteuerung.

Bei einer sicheren Funktion oder Prozedur wird einem nicht autorisierten Benutzer, dem keine Eigentümerrolle der Funktion oder Prozedur zugewiesen wurde, die Funktions- bzw. Prozedurdefinition bei folgenden Optionen nicht angezeigt:

Beachten Sie, dass Funktionen und Prozeduren, deren Handler in Java, Python oder Scala geschrieben sind, die IMPORTS-Klausel zulassen, mit der Code- oder Datendateien aus Snowflake-Stagingbereichen importiert werden können. Die Verwendung des Schlüsselworts SECURE hat keine Auswirkung auf die Sichtbarkeit oder den Zugriff auf diese Stagingbereiche.

Darüber hinaus wird bei Funktionen und Prozeduren, deren Handler in Java, Python oder Scala geschrieben sind, durch den Schutz der Funktionen und Prozeduren sichergestellt, dass diese in separaten Sandboxen ausgeführt werden, sodass Ressourcen exklusiv genutzt werden.

Weitere Informationen zur Verwendung des Schlüsselworts SECURE finden Sie unter Erstellen einer sicheren UDF oder einer sicheren gespeicherten Prozedur.

Begrenzen der Sichtbarkeit der sensiblen Daten einer UDF

Bei UDFs können Sie verhindern, dass Benutzer Daten sehen, die verborgen sein sollten, indem Sie die UDF explizit schützen. Dazu verwenden Sie beim Erstellen oder Ändern der UDF das Schlüsselwort SECURE.

Definieren Sie eine UDF als „sicher“, wenn sie speziell für den Datenschutz bestimmt ist (d. h. um den Zugriff auf vertrauliche Daten einzuschränken, die nicht allen Benutzern der zugrunde liegenden Tabellen zugänglich sein sollen).

Sie sollten eine UDF nicht als „sicher“ definieren, wenn sie zur Vereinfachung von Abfragen definiert ist, d. h. wenn sie beispielsweise zur Vereinfachung der Abfrage von Daten erstellt wurden, für die Benutzer die zugrunde liegende Datendarstellung nicht verstehen müssen. Dies liegt daran, dass der Snowflake-Abfrageoptimierer beim Auswerten von sicheren UDFs die für reguläre UDFs verwendeten Optimierungen umgeht. Dies kann die Abfrageleistung für sichere UDFs reduzieren.

Um die Sichtbarkeit der zugrunde liegenden Daten einer UDF einzuschränken, verwenden Sie beim Erstellen oder Ändern der UDF das Schlüsselwort SECURE. Weitere Informationen dazu finden Sie unter Erstellen einer sicheren UDF oder einer sicheren gespeicherten Prozedur.

Wie Daten offengelegt werden könnten

Einige der internen Optimierungen für UDFs, wie z. B. die Pushdown-Optimierung, erfordern den Zugriff auf die zugrunde liegenden Daten in den Basistabellen. Durch diesen Zugriff können Daten, die für Benutzer der UDF verborgen sind, indirekt über programmatische Methoden verfügbar gemacht werden. In bestimmten Situationen kann ein Benutzer möglicherweise Informationen über Zeilen ableiten, die der Benutzer nicht direkt sehen kann.

Sichere UDFs verwenden diese Optimierungen nicht. Dadurch wird sichergestellt, dass Benutzer auch nicht indirekt auf die zugrunde liegenden Daten zugreifen können. Weitere Informationen zur Pushdown-Optimierung finden Sie unter Pushdown-Optimierung und Datensichtbarkeit.

Tipp

Bei der Entscheidung, ob Sie eine sichere UDF verwenden möchten, sollten Sie den Zweck der UDF berücksichtigen und den Kompromiss zwischen Datenschutz/Sicherheit und Abfrageleistung abwägen.

Wenn Ihre Daten so sensibel sind, dass Sie entscheiden, dass Zugriffe über einen Objekttyp (wie UDFs) sicher sein sollen, sollten Sie unbedingt dafür sorgen, dass Zugriffe über andere Objekttypen (z. B. Ansichten) ebenfalls sicher sind.

Wenn Sie zum Beispiel nur die sicheren UDFs für den Zugriff auf eine bestimmte Tabelle zulassen, sollten alle Ansichten, die Sie für den Zugriff auf dieselbe Tabelle zulassen, wahrscheinlich ebenfalls sicher sein.

Wie sichere UDFs Daten schützen

Wie unter Pushdown-Optimierung und Datensichtbarkeit beschrieben, kann die Pushdown-Optimierung die Filter neu anordnen, die bestimmen, wie eine Abfrage verarbeitet wird. Wenn die Optimierung die Filter so anordnet, dass ein allgemeiner Filter ausgeführt werden kann, bevor die zum Schutz der Daten verwendeten Filter angewendet werden, könnten die zugrunde liegenden Details offengelegt werden. Daher besteht die Lösung darin, zu verhindern, dass der Optimierer bestimmte Filtertypen hineindrückt (im Allgemeinen, um zu verhindern, dass der Optimierer bestimmte Arten von Optimierungen verwendet, insbesondere den Filter-Pushdown), wenn diese Optimierungen nicht sicher sind.

Wenn Sie eine UDF als „sicher“ deklarieren, wird das Optimierungsprogramm angewiesen, bestimmte Filter nicht hineinzudrücken (allgemeiner ausgedrückt, bestimmte Optimierungen nicht zu verwenden). Das Verhindern bestimmter Arten von Optimierungen kann sich jedoch auf die Leistung auswirken.

Best Practices beim Schutz des Zugangs zu sensiblen Daten

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

Offenlegung von sequenzgenerierten Spaltenwerten vermeiden

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.

Angenommen, wir haben eine Funktion get_widgets_function(), die die Spalte ID verfügbar macht. Wenn ID aus einer Sequenz generiert wird, kann ein Benutzer von get_widgets_function() 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 table(get_widgets_function()) 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 |
...
Copy

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

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

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

  • Programmieren Sie eine Verschleierung der Bezeichner.

Sichtbarkeit der Größe der gescannten Daten begrenzen

Für Abfragen, die sichere Funktionen 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 sollten Sie Daten pro Benutzer/Rolle materialisieren, anstatt den Benutzern Funktionen in den Basisdaten anzuzeigen. Im Fall der in diesem Thema beschriebenen Tabelle widgets würde für jede Rolle, die Zugriff auf Widgets hat, eine eigene Tabelle erstellt werden. Jede dieser Tabellen würde nur die Widgets enthalten, auf die die jeweilige Rolle Zugriff hat, und dann würde der Rolle der Zugriff auf die eigene Tabelle gewährt. Dies ist viel umständlicher als die Verwendung einer einzelnen Funktion. In extrem hochsicheren Situationen kann dies jedoch gerechtfertigt sein.

Zugriff auf Basistabelle für Benutzer von einem bestimmten Konto aus autorisieren

Bei Verwendung sicherer UDFs mit Data Sharing kann die Funktion CURRENT_ACCOUNT verwendet werden, um Benutzer eines bestimmten Kontos für den Zugriff auf Zeilen in einer Basistabelle zu autorisieren.

Bemerkung

Wenn Sie die Funktionen CURRENT_ROLE und CURRENT_USER mit sicheren UDFs 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 UDF freigegeben ist.

Sichere UDFs und Maskierungsrichtlinien

Wenn Sie eine UDF, egal ob sichere UDF oder nicht, in einer Maskierungsrichtlinie verwenden, müssen Sie sicherstellen, dass die Datentypen von Spalte, UDF und Maskierungsrichtlinie übereinstimmen.

Weitere Informationen dazu finden Sie unter Benutzerdefinierte Funktionen in einer Maskierungsrichtlinie.

Erstellen einer sicheren UDF oder einer sicheren gespeicherten Prozedur

Sie können eine UDF oder Prozedur als „sicher“ definieren, indem Sie beim Erstellen oder Ändern das Schlüsselwort SECURE verwenden.

Um einen UDF zu erstellen oder umzuwandeln, sodass sie sicher ist, geben Sie SECURE an, wenn Sie Folgendes verwenden:

Um eine Prozedur so zu erstellen, dass sie sicher ist, geben Sie SECURE an, wenn Sie Folgendes verwenden:

Feststellen, ob eine UDF oder Prozedur sicher ist

Sie können feststellen, ob eine Funktion oder Prozedur sicher ist, indem Sie den Befehl SHOW FUNCTIONS oder SHOW PROCEDURES verwenden. Die Befehle geben eine Tabelle mit einer Spalte IS_SECURE zurück, deren Wert Y für „sicher“ und N für „nicht sicher“ steht.

Der Code im folgenden Beispiel gibt eine Tabelle mit den Eigenschaften der Funktion MYFUNCTION zurück.

show functions like 'MYFUNCTION';
Copy

Anzeigen von Details der sicheren Funktion in Query Profile

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