Erweiterte Sicherheit auf Spaltenebene

Dieses Thema bietet eine Einführung in zwei erweiterte Konzepte im Zusammenhang mit Maskierungsrichtlinien für Sicherheit auf Spaltenebene:

  1. Rollenhierarchie.

  2. Verwenden mehrerer Kontextfunktionen.

Kontextfunktionen und Rollenhierarchie

Sicherheit auf Spaltenebene ermöglicht die Verwendung von Kontextfunktionen im Bedingungstext von Maskierungsrichtlinien, um zu erzwingen, dass ein Benutzer zum Anzeigen von Daten entsprechend berechtigt ist. Um festzustellen, ob einem Benutzer Daten einer bestimmten SQL-Anweisung angezeigt werden dürfen, ist Folgendes zu berücksichtigen:

Die aktuelle Sitzung

Bedingungen in Maskierungsrichtlinien, die CURRENT_ROLE verwenden, zielen auf die Rolle ab, die für die aktuelle Sitzung verwendet wird.

Die ausführende Rolle

Bedingungen in Maskierungsrichtlinien, die INVOKER_ROLE verwenden, zielen auf die ausführende Rolle einer SQL-Anweisung ab.

Rollenhierarchie

Wenn die Rollenhierarchie in den Richtlinienbedingungen erforderlich ist, verwenden Sie IS_ROLE_IN_SESSION.

Ermitteln Sie, ob die in einer Maskierungsrichtlinienbedingung angegebene Rolle (z. B. die kundenspezifische analyst-Rolle) eine Rolle auf niedriger Berechtigungsstufe in der Rollenhierarchie von CURRENT_ROLE oder INVOKER_ROLE ist. Wenn ja, erbt die von der Funktion CURRENT_ROLE bzw. INVOKER_ROLE zurückgegebene Rolle die Berechtigungen der angegebenen Rolle. Weitere Informationen zur Rollenhierarchie und zur Vererbung von Berechtigungen finden Sie unter:

Die folgende Tabelle zeigt allgemeine Kontextfunktionen für Maskierungsrichtlinien, die auf die aktuelle Sitzung, die ausführende Rolle und die Rollenhierarchie abzielen.

Kontextfunktion

Beschreibung

CURRENT_ROLE

Gibt den Namen der Rolle zurück, die für die aktuelle Sitzung verwendet wird.

IS_ROLE_IN_SESSION

Gibt TRUE zurück, wenn die aktuelle Rolle des Benutzers in der Sitzung (d. h. die von CURRENT_ROLE zurückgegebene Rolle) die Berechtigungen der angegebenen Rolle erbt.

INVOKER_ROLE

Gibt den Namen der ausführenden Rolle zurück.

IS_GRANTED_TO_INVOKER_ROLE

Gibt TRUE zurück, wenn die von der Funktion INVOKER_ROLE zurückgegebene Rolle die Berechtigungen der im Argument angegebenen Rolle auf Basis des Kontextes erbt, in dem die Funktion aufgerufen wird.

INVOKER_SHARE

Gibt den Namen der Freigabe zurück, die direkt auf die Tabelle oder die Ansicht zugegriffen hat, wo die INVOKER_SHARE-Funktion aufgerufen wurde.

Verwenden von CURRENT_ROLE und IS_ROLE_IN_SESSION

Eine Maskierungsrichtlinienbedingung mit CURRENT_ROLE zielt auf die aktuelle Sitzung ab und wird vom Ausführungskontext der SQL-Anweisung nicht beeinflusst.

Wenn Rollenaktivierung und Rollenhierarchie in den Richtlinienbedingungen erforderlich sind, verwenden Sie IS_ROLE_IN_SESSION.

Betrachten Sie den folgenden Maskierungsrichtlinientext:

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN CURRENT_ROLE() IN ('ANALYST') THEN val
  ELSE '********'
END;
Copy

Führen Sie die folgenden Schritte aus, um festzustellen, ob ein bestimmter Benutzer die Autorisierung zur Anzeige von Daten einer bestimmten Spalte hat, auf der diese Maskierungsrichtlinie festgelegt ist:

  1. Prüfen Sie die Bedingungen der Maskierungsrichtlinie.

  2. Stellen Sie fest, ob sich die angegebene Rolle in der CURRENT_ROLE-Hierarchie befindet.

  3. Führen Sie zur Überprüfung eine Testabfrage aus.

Schritt 1: Bedingungen der Maskierungsrichtlinie prüfen

In der folgenden Tabelle sind die Konsequenzen der Bedingungen des Maskierungsrichtlinientextes zusammengefasst.

Kontext

Anzeige nicht maskierter Daten

Anzeige maskierter Daten

CURRENT_ROLE = kundenspezifische ANALYST-Rolle.

CURRENT_ROLE ist in der Hierarchie der kundenspezifischen ANALYST-Rolle.

CURRENT_ROLE ist nicht in der Hierarchie der kundenspezifischen ANALYST-Rolle.

Bewerten Sie als Nächstes die Rollenhierarchie.

Schritt 2: Ermitteln, ob sich die angegebene Rolle in der CURRENT_ROLE-Hierarchie befindet

Angenommen, CURRENT_ROLE ist nicht die kundenspezifische ANALYST-Rolle, dann müssen Sie prüfen, ob CURRENT_ROLE die Berechtigungen erbt, die der kundenspezifischen ANALYST-Rolle erteilt wurden.

Führen Sie die folgende Anweisung aus:

SELECT IS_ROLE_IN_SESSION('ANALYST');
Copy
+-------------------------------+
| IS_ROLE_IN_SESSION('ANALYST') |
+-------------------------------+
| FALSE                         |
+-------------------------------+

Da Snowflake FALSE zurückgibt, erbt CURRENT_ROLE keine der Berechtigungen, die der benutzerdefinierten ANALYST-Rolle erteilt wurden. Auf Basis des in diesem Beispiel verwendeten Maskierungsrichtlinientextes sollte dem Benutzer daher ein fest definierter Maskenwert angezeigt werden.

Schritt 3: Testabfrage zur Überprüfung ausführen

Führen Sie eine Abfrage auf der Spalte aus, auf die die Maskierungsrichtlinie in diesem Beispiel angewendet wurde, um zu überprüfen, ob dem Benutzer ein fest definierter Maskenwert angezeigt wird.

USE ROLE analyst;

SELECT * FROM mydb.mysch.mytable;
Copy

Verwenden von INVOKER_ROLE

Eine Maskierungsrichtlinienbedingung unter Verwendung von INVOKER_ROLE zielt auf den Ausführungskontext der SQL-Anweisung ab.

In der folgenden Tabelle sind der Ausführungskontext und der Wert zusammengefasst, den INVOKER_ROLE in einer Maskierungsrichtlinienbedingung zurückgibt:

Kontext

Bewertete Rolle

Benutzer

CURRENT_ROLE

Tabelle

CURRENT_ROLE

Ansicht

Rolle des Eigentümers der Ansicht

UDF

Rolle des Eigentümers der UDF

Gespeicherte Prozedur mit Aufruferrechten

CURRENT_ROLE

Gespeicherte Prozedur mit Eigentümerrechten

Rolle des Eigentümers der gespeicherten Prozedur

Aufgabe

Rolle des Eigentümers der Aufgabe

Stream

Die Rolle, die einen bestimmten Stream abfragt.

Betrachten Sie den folgenden Maskierungsrichtlinientext, der auf eine einzelne Ansicht einer Tabelle angewendet wird:

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN INVOKER_ROLE() IN ('ANALYST') THEN val
  ELSE '********'
END;
Copy

Führen Sie die folgenden Schritte aus, um festzustellen, ob ein bestimmter Benutzer, der eine Abfrage auf der Spalte ausführt, zum Anzeigen von Daten berechtigt ist:

  1. Prüfen Sie die Bedingungen der Maskierungsrichtlinie.

  2. Stellen Sie fest, ob die angegebene Rolle Eigentümer der Ansicht ist.

  3. Führen Sie zur Überprüfung eine Testabfrage aus.

Schritt 1: Bedingungen der Maskierungsrichtlinie prüfen

In der folgenden Tabelle sind die Konsequenzen der Bedingungen des Maskierungsrichtlinientextes zusammengefasst, die auf eine Ansichtsspalte angewendet werden.

Kontext

Anzeige nicht maskierter Daten

Anzeige maskierter Daten

Die kundenspezifische analyst-Rolle ist die Rolle des Eigentümers der Ansicht.

Die kundenspezifische analyst-Rolle ist nicht die Rolle des Eigentümers der Ansicht.

Stellen Sie als Nächstes fest, ob die kundenspezifische ANALYST-Rolle Eigentümer der Ansicht ist.

Schritt 2: Ermitteln, ob ANALYST Eigentümer der Ansicht ist

Führen Sie die folgende Anweisung aus, um festzustellen, ob die kundenspezifische ANALYST-Rolle Eigentümer der Ansicht ist:

SHOW GRANTS OF ROLE analyst;
Copy

Wenn die kundenspezifische analyst-Rolle Eigentümer der Ansicht ist, sollte eine Abfrage auf der Ansichtsspalte zu nicht maskierten Daten führen.

Wenn die kundenspezifische analyst-Rolle kein Eigentümer der Ansicht ist, sollten maskierte Daten angezeigt werden.

Schritt 3: Testabfrage zur Überprüfung ausführen

Führen Sie eine Abfrage auf der Ansichtsspalte aus, um festzustellen, ob der kundenspezifischen ANALYST-Rolle maskierte oder nicht maskierte Daten angezeigt werden.

USE ROLE analyst;

SELECT * FROM mydb.mysch.myview;
Copy

Verwenden von IS_GRANTED_TO_INVOKER_ROLE

Die Funktion IS_GRANTED_TO_INVOKER_ROLE kann als Teil einer Bedingung an einen Maskierungsrichtlinientext übergeben werden. Wenn die Funktion TRUE ergibt, ist die im Funktionsargument angegebene Rolle in der INVOKER_ROLE-Hierarchie enthalten.

Betrachten Sie den folgenden Maskierungsrichtlinientext, der auf eine Ansichtsspalte mit Sozialversicherungsnummern (SSNs) angewendet wird:

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN IS_GRANTED_TO_INVOKER_ROLE('PAYROLL') THEN val
  WHEN IS_GRANTED_TO_INVOKER_ROLE('ANALYST') THEN REGEXP_REPLACE(val, '[0-9]', '*', 7)
  ELSE '*******'
END;
Copy

Führen Sie die folgenden Schritte aus, um festzustellen, ob ein bestimmter Benutzer, der eine Abfrage auf der Ansichtsspalte ausführt, zum Anzeigen von Daten berechtigt ist:

  1. Prüfen Sie die Bedingungen der Maskierungsrichtlinie.

  2. Stellen Sie fest, ob sich die angegebene Rolle in der Hierarchie der Aufruferrolle befindet. Wenn die Richtlinie beispielsweise für eine Ansicht festgelegt wird, muss sich die angegebene Rolle in der Rollenhierarchie des Eigentümers der Ansicht befinden, damit TRUE zurückgegeben wird. Weitere Informationen dazu finden Sie in den Nutzungshinweisen.

  3. Führen Sie zur Überprüfung eine Testabfrage aus.

Schritt 1: Bedingungen der Maskierungsrichtlinie prüfen

In der folgenden Tabelle sind die Konsequenzen der Bedingungen des Maskierungsrichtlinientextes zusammengefasst, die auf eine Ansichtsspalte angewendet werden.

Kontext

Nicht maskierte Daten

Teilweise maskierte Daten

Maskierte Daten

Die kundenspezifische payroll-Rolle befindet sich in der Hierarchie der Ansichtseigentümerrolle.

Die kundenspezifische analyst-Rolle befindet sich in der Hierarchie der Ansichtseigentümerrolle.

Weder die kundenspezifische payroll-Rolle noch die analyst-Rolle befinden sich in der Hierarchie der Ansichtseigentümerrolle.

Schritt 2: Ermitteln, ob sich die angegebene Rolle in der Rollenhierarchie des Ansichtseigentümers befindet.

Wenn sich entweder die benutzerdefinierte payroll-Rolle oder die benutzerdefinierte analyst-Rolle in der Hierarchie des Ansichtseigentümers befinden, kann durch Ausführen eines SHOW GRANTS-Befehls auf der Ansichtseigentümerrolle die Rollenhierarchie überprüft werden. Beispiel:

SHOW GRANTS TO ROLE view_owner_role;
Copy

In den Ausgaben der SQL-Anweisung wird angegeben, ob der Ansichtseigentümerrolle entweder die benutzerdefinierte payroll-Rolle oder die benutzerdefinierte analyst-Rolle zugewiesen wurde.

Schritt 3: Testabfrage zur Überprüfung ausführen

Führen Sie eine Abfrage auf der Spalte aus, auf die die Maskierungsrichtlinie in diesem Beispiel angewendet wurde, um zu überprüfen, wie dem Benutzer die Daten in der Ansichtsspalte angezeigt werden.

USE ROLE payroll;

SELECT * FROM mydb.mysch.myview;

USE ROLE analyst;

SELECT * FROM mydb.mysch.myview;
Copy

Kombinieren von CURRENT_ROLE und INVOKER_ROLE in Maskierungsrichtlinien

Snowflake unterstützt die Erstellung einer einzigen Maskierungsrichtlinie, um die für die Sitzung, die eine Abfrage ausführt (d. h. CURRENT_ROLE), verwendete Rolle und den Objektbesitzer, der eine Abfrage ausführt (z. B. Besitzer der Ansicht, INVOKER_ROLE), zu unterscheiden. Anwendungsfälle dieser Art sind in der Regel komplizierter als die einfache Bestimmung einer Menge von zu maskierenden Werten und einer relativ kleinen Zielgruppe (z. B. Benutzer mit der benutzerdefinierten Rolle analyst), die nicht maskierte Werte sehen kann.

Hashing-, Kryptographie- und Verschlüsselungsfunktionen in Maskierungsrichtlinien

Hashing und Kryptografie/Prüfsumme können in Maskierungsrichtlinien verwendet werden, um sensible Daten zu maskieren.

Bevor Sie eine dieser Funktionen in einer Maskierungsrichtlinie verwenden, ist es wichtig zu prüfen, ob Ihr Anwendungsfall mit diesen Funktionen auch JOIN-Operationen umfasst. Bei bestimmten Implementierungen von Maskierungsrichtlinien können kreative JOIN-Operationen, die Tabellen und Ansichten beinhalten, dazu führen, dass der maskierte Wert auf der Grundlage der folgenden Einschränkung auf seinen wahren Wert zurückgeführt wird:

  • Es ist möglich, dass es zu Kollisionen kommt, weil es möglicherweise keine 1:1-Darstellung des tatsächlichen Werts (d. h. der Eingabe) und des Hash-Werts, des kryptografischen Werts oder des Prüfsummenwerts auf der Grundlage der Gesamtzahl der zu transformierenden Werte (d. h. der Ausgabe, des Wertebereichs) gibt.

Eine 1:1-Darstellung ist wahrscheinlicher, bis die Gesamtzahl der Eingabewerte die Quadratwurzel der zu transformierenden Ausgabewerte erreicht.

Wenn der Ausgabewert für den Hash beispielsweise 144 ist, kann erwartet werden, dass die ersten 12 Werte (d. h. 144^(1/2) – die Quadratwurzel aus 144) eindeutig sind und dass bei den restlichen 132 Werten Kollisionen auftreten können. Da diese Einschränkung und deren Konsequenz möglich ist, ist es ratsam, niemals Hashing-, Kryptografie- oder Prüfsummenfunktionen in Maskierungsrichtlinien zu verwenden, deren Werte in JOIN-Operationen verwendet werden können.

Tipp

Wenn der Anwendungsfall der Maskierungsrichtlinie so eingestellt ist, dass zur Erhöhung der Sicherheit der Kollisionsvermeidung Vorrang eingeräumt wird, implementieren Sie die externe Tokenisierung. Die Tokenisierung führt nicht zu Kollisionen, da es immer eine 1:1-Darstellung der Ein- und Ausgabewerte gibt.

Wenn eine Tokenisierung nicht möglich ist, besteht eine mögliche Abhilfe darin, eine Maskierungsrichtlinie zu implementieren, um zwischen der Sitzungsrolle, die eine Abfrage ausführt (d. h. CURRENT_ROLE), und dem Objekteigentümer, der eine Abfrage ausführt (d. h. INVOKER_ROLE), zu unterscheiden.

Zum Beispiel nimmt die folgende Maskierungsrichtlinie zwei verschiedene benutzerdefinierte Rollen, CSR_EMPL_INFO und DBA_EMPL_INFO, an, um den Zugang zu Mitarbeiterinformationen zu regeln.

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
    WHEN CURRENT_ROLE() IN ('CSR_EMPL_INFO') THEN HASH(val)
    WHEN INVOKER_ROLE() IN ('DBA_EMPL_INFO') THEN val
    ELSE null
END;
Copy

Wenn die Richtlinie auf die Tabelle angewendet wird, wird die Richtlinie auf jede aus der Tabelle erstellte Ansicht vererbt. Wenn die benutzerdefinierte Rolle dba_empl_info Eigentümer der aus dieser Tabelle erstellten Ansicht ist (d. h. die Rolle hat die Berechtigung OWNERSHIP für die Ansicht), dann werden nur Benutzern mit dieser benutzerdefinierten Rolle bei Abfrage der Ansicht die tatsächlichen Werte angezeigt. Benutzern mit der benutzerdefinierten Rolle csr_empl_info wird immer ein gehashter Wert angezeigt, unabhängig davon, ob die Abfrage auf der Tabelle oder auf der Ansicht ausgeführt wird. Allen anderen Benutzern wird NULL angezeigt.