動的なデータ マスキング

適用対象: はいSQL Server 2016 (13.x) 以降 はいAzure SQL データベース はいAzure SQL Managed Instance はいAzure Synapse Analytics

動的データ マスク

動的データ マスク (DDM) では、機密データをマスクすることにより、特権のないユーザーへの機密データの公開を制限します。 DDM を使用すると、アプリケーションのセキュリティの設計とコーディングを大幅に簡略化することができます。

動的データ マスクでは、公開する機密データの量を指定することで、そのようなデータに対する未承認のアクセスを防ぎ、アプリケーション レイヤーへの影響が最小限に抑えられます。 DDM は、指定されたデータベース フィールドで、クエリの結果セットに含まれる機密データを隠蔽するように構成できます。 DDM によって、データベース内のデータが変更されることはありません。 DDM は、クエリの結果にマスク ルールが適用されるため、既存のアプリケーションで簡単に使用できます。 多くのアプリケーションは、既存のクエリを変更せずに、デリケートなデータをマスクすることができます。

  • 中央のデータ マスク ポリシーは、データベースの機密フィールドに対して直接動作します。
  • 機密データに対するアクセス権を持つ特権のあるユーザーまたはロールを指定します。
  • DDM には、フル マスク関数と部分マスク関数、および数値データ用のランダム マスクがあります。
  • 単純な Transact-SQL コマンドで、マスクを定義し、管理します。

動的データ マスクの目的は、アクセスすべきではないユーザーがデータを閲覧することを防ぎ、デリケートなデータの公開を制限することにあります。 動的データ マスクは、ユーザーが直接データベースに接続し、徹底的なクエリを実行して、デリケートなデータの漏えいを防ぐことを目的としてはいません。 動的データ マスクは、その他の SQL Server セキュリティ機能 (監査、暗号化、行レベルのセキュリティなど) を補完します。データベース内の機密データの保護をより強化するために、これを連携して使用することをお勧めします。

動的データ マスクは SQL Server 2016 (13.x) と Azure SQL データベースで使用できます。 Transact-SQL をコマンドを使用して構成します。 Azure portal で動的データ マスクを構成する方法の詳細については、SQL Database 動的データ マスクの使用 (Azure ポータル)に関するページを参照してください。

動的データ マスクを定義する

マスク ルールは、列のデータを難読化するために、テーブル内の列で定義することがあります。 4 種類のマスクを利用できます。

機能 説明
Default 指定のフィールドのデータ型に応じたフル マスク。

文字列データ型 (charncharvarcharnvarchartextntext) のフィールドのサイズが 4 文字未満の場合は、XXXX またはそれ未満の数の X を使用します。

数値データ型 (bigintbitdecimalintmoneynumericsmallintsmallmoneytinyintfloatreal) の場合は値 0 を使用します。

日付/時刻のデータ型 (datedatetime2datetimedatetimeoffsetsmalldatetimetime) の場合は、01.01.1900 00:00:00.0000000 を使用します。

バイナリ データ型 (binaryvarbinaryimage) の場合は、ASCII 値 0 のシングル バイトを使用します。
列定義の構文例: Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL

ALTER 構文例: ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()')
Email メール アドレスの最初の 1 文字と定数サフィックスの ".com" をメール アドレスのフォームで公開するマスク方法。 aXXX@XXXX.com. 定義の構文例: Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL

ALTER 構文例: ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()')
ランダム ランダム マスク関数は任意の数字型に使用でき、指定した範囲内で生成したランダムな値でオリジナルの値をマスクします。 定義の構文例: Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])')

ALTER 構文例: ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)')
カスタム文字列 間にカスタム埋め込み文字列を追加し、最初と最後の文字を公開するマスク方法。 prefix,[padding],suffix

注:元の文字列が全体をマスクするには短すぎる場合、プレフィックスまたはサフィックスの一部は公開されません。
定義の構文例: FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL

ALTER 構文例: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)')

その他の例:

ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(5,"XXXXXXX",0)')

アクセス許可

動的データ マスクでテーブルを作成するのに特別なアクセス許可は要りません。スキーマ アクセス許可に対する CREATE TABLEALTER のみ必要です。

列のマスクを追加、置換、削除するには、 ALTER ANY MASK アクセス許可と、テーブルに対する ALTER アクセス許可が必要です。 セキュリティの責任者には、 ALTER ANY MASK の付与が適切です。

テーブルに対して SELECT アクセス許可を持つユーザーは、テーブル データを閲覧できます。 マスク済みとして定義されている列には、マスクされたデータが表示されます。 UNMASK アクセス許可を付与されたユーザーは、マスクが定義された列から、マスクを解除したデータを取得できます。

データベースに対する CONTROL アクセス許可には、 ALTER ANY MASKUNMASK の両方のアクセス許可が含まれます。

注意

UNMASK の権限は、メタデータの可視性に影響しません。UNMASK だけを許可しても、メタデータは開示されません。 UNMASK が作用するには、常に SELECT 権限が付随する必要があります。 例: データベース スコープに対する UNMASK の許可と個々のテーブルに対する SELECT の許可によって、そのユーザーのみが選択できる個々のテーブルのメタデータのみが表示されるようになります。 「メタデータ表示の構成」も参照してください。

ベスト プラクティスと一般的なユース ケース

  • 列にマスクを作成しても、その列に対する更新を妨げることはありません。 マスクされた列にクエリを実行すると、ユーザーはマスクされたデータを受け取りますが、書き込みアクセス許可があるユーザーは、データを更新できます。 更新する許可を制限するために、適切なアクセス制御ポリシーを使用する必要があります。

  • SELECT INTO または INSERT INTO を使用して、マスクされた列を別のテーブルにコピーすると、対象のテーブルにマスクされたデータが表示されます。

  • 動的データ マスクは、 SQL Server インポートとエクスポートを実行すると適用されます。 マスクされた列を含むデータベースは、マスクされたデータを含むエクスポートされたデータ ファイルを生成し (UNMASK 特権がないユーザーがエクスポートしたことを前提とします)、インポートされたデータベースは、マスクされたデータを静的に格納します。

マスクされた列に対してクエリを実行する

sys.masked_columns ビューを使用して、マスク関数が適用されたテーブルの列に対してクエリを実行します。 このビューが継承、 sys.columns ビューです。 sys.columns ビューのすべての列と、 is_masked 列および masking_function 列を返して、マスクされた列かどうかを示し、マスクされた列の場合は、どのようなマスキング関数が定義されているかを示します。 これは、列があるマスキング関数が適用されるは表示のみを表示します。

SELECT c.name, tbl.name as table_name, c.is_masked, c.masking_function  
FROM sys.masked_columns AS c  
JOIN sys.tables AS tbl   
    ON c.[object_id] = tbl.[object_id]  
WHERE is_masked = 1;  

制限事項と制約事項

次の列の型には、マスク ルールを定義することはできません。

  • 暗号化された列 (常に暗号化されます)

  • FILESTREAM

  • COLUMN_SET、または列セットの一部であるスパース列

  • マスクは計算列に構築できません。ただし、計算列が MASK を所有する列に依存する場合は、計算列がマスクされたデータを返します。

  • データ マスクを持つ列を FULLTEXT インデックスのキーにすることはできません。

  • PolyBase 外部テーブル内の列。

UNMASK アクセス許可のないユーザーの場合、非推奨とされている READTEXTUPDATETEXT、および WRITETEXT ステートメントは、動的データ マスク用に構成された列で適切に動作しません。

動的データ マスクの追加は基になっているテーブルでのスキーマ変更として実装されるため、依存関係を持つ列では実行できません。 この制限を回避するには、最初に依存関係を削除してから、動的データ マスクを追加した後、依存関係を再作成します。 たとえば、依存関係がその列に依存するインデックスによるものである場合は、インデックスを削除し、マスクを追加してから、依存するインデックスを再作成します。

データ マスキング関数が定義されている列を参照する式を射影するたびに、式もマスクされます。 参照される列をマスクするために使用される関数 (既定、電子メール、ランダム、カスタム文字列) に関係なく、結果として得られる式は常に既定の関数でマスクされます。

セキュリティに関する注意:推論またはブルートフォース手法を使用してマスクをバイパスする

動的データ マスクは、アプリケーションに使用される事前定義されたクエリ セットのデータ公開を制限することで、アプリケーション開発を単純化するために設計されています。 動的データ マスクは、実稼働データベースに直接アクセスするときに機密データが誤って公開されることを防ぐためにも有効ですが、アドホック クエリ アクセス許可を持つ特権のないユーザーが、実際のデータに対するアクセス権を得る手法を適用する可能性にも注意する必要があります。 このようなアドホック アクセス権を付与する必要がある場合、すべてのデータベース操作を監視し、このシナリオを軽減するために監査を使用することをお勧めします。

たとえば、データベースに対してアドホック クエリを実行する十分な特権を持つデータベース プリンシパルがいて、基になるデータを ’推測’ し、最終的には実際の値を推測しようと試みているとします。 管理者は [Employee].[Salary] 列に対してマスクを定義しましたが、このユーザーはデータベースに直接接続し、値の推測を開始し、最終的には従業員セットの [Salary] 値を推測します。

SELECT ID, Name, Salary FROM Employees
WHERE Salary > 99999 and Salary < 100001;
Id 名前 Salary
62543 Jane Doe 0
91245 John Smith 0

この例は、データベースに対してアドホック クエリを実行するユーザーから、機密データをセキュリティで完全に保護する唯一の手段として動的データ マスクを使用すべきではないことを示しています。 動的データ マスクは偶発的な機密データの公開を防ぐ場合に適していますが、基になるデータを推測する悪意のある攻撃を防ぐためのものではありません。

データベースのアクセス許可を適切に管理し、必要最小限のアクセス許可の原則に常に従うことが重要です。 また、データベースに対して実行されるすべてのアクティビティを追跡するために、必ず監査を有効にしてください。

動的データ マスクを作成する

次の例では、3 種類の動的データ マスクでテーブルを作成します。 この例ではテーブルを作成し、結果を表示するように選びます。


-- schema to contain user tables
CREATE SCHEMA Data;
GO

-- table with masked columns
CREATE TABLE Data.Membership(
    MemberID        int IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
    FirstName        varchar(100) MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)') NULL,
    LastName        varchar(100) NOT NULL,
    Phone            varchar(12) MASKED WITH (FUNCTION = 'default()') NULL,
    Email            varchar(100) MASKED WITH (FUNCTION = 'email()') NOT NULL,
    DiscountCode    smallint MASKED WITH (FUNCTION = 'random(1, 100)') NULL
    );

-- inserting sample data
INSERT INTO Data.Membership (FirstName, LastName, Phone, Email, DiscountCode)
VALUES   
('Roberto', 'Tamburello', '555.123.4567', 'RTamburello@contoso.com', 10),  
('Janice', 'Galvin', '555.123.4568', 'JGalvin@contoso.com.co', 5),  
('Shakti', 'Menon', '555.123.4570', 'SMenon@contoso.net', 50),  
('Zheng', 'Mu', '555.123.4569', 'ZMu@contoso.net', 40);  

新しいユーザーが作成され、テーブルが属しているスキーマに対する SELECT アクセス許可が付与されます。 MaskingTestUser ビューのマスクされたデータとして、クエリが実行されます。

CREATE USER MaskingTestUser WITHOUT LOGIN;  

GRANT SELECT ON SCHEMA::Data TO MaskingTestUser;  
  
  -- impersonate for testing:
EXECUTE AS USER = 'MaskingTestUser';  

SELECT * FROM Data.Membership;  

REVERT;  

次のようにデータが変更された結果によって、マスクが示されます。

1 Roberto Tamburello 555.123.4567 RTamburello@contoso.com 10

変更前:

1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91

DiscountCode の番号は、すべてのクエリ結果に対してランダムになります

既存の列のマスクを追加または編集する

ALTER TABLE ステートメントを使用して、テーブル内の既存の列にマスクを追加したり、その列のマスクを編集したりします。
次の例では、LastName 列にマスク関数を追加します。

ALTER TABLE Data.Membership  
ALTER COLUMN LastName ADD MASKED WITH (FUNCTION = 'partial(2,"xxxx",0)');  

次の例では、 LastName 列のマスク関数を変更します。

ALTER TABLE Data.Membership  
ALTER COLUMN LastName varchar(100) MASKED WITH (FUNCTION = 'default()');  

アクセス許可を付与して、マスクが解除されたデータを表示する

UNMASK アクセス許可が付与されると、 MaskingTestUser は、マスクが解除されたデータを閲覧できるようになります。

GRANT UNMASK TO MaskingTestUser;  

EXECUTE AS USER = 'MaskingTestUser';  

SELECT * FROM Data.Membership;  

REVERT;    
  
-- Removing the UNMASK permission  
REVOKE UNMASK TO MaskingTestUser;  

動的データ マスクをドロップする

次のステートメントは、先ほどの例で作成された LastName 列のマスクをドロップします。

ALTER TABLE Data.Membership   
ALTER COLUMN LastName DROP MASKED;  

参照

CREATE TABLE (Transact-SQL)
ALTER TABLE (Transact-SQL)
column_definition (Transact-SQL)
sys.masked_columns (Transact-SQL)
SQL Database 動的データ マスクの使用 (Azure portal)