元數據可見性設定

適用於:SQL ServerAzure SQL 資料庫Azure SQL 受控執行個體Azure Synapse AnalyticsMicrosoft Fabric 中的 SQL 資料庫

中繼資料的可見性僅限於使用者所擁有的安全性實體,或已對使用者授與某些權限的安全性實體。

例如,如果使用者在資料表SELECT上授予像是INSERT或myTable的許可,下列查詢會傳回資料列。

SELECT name, object_id
FROM sys.tables
WHERE name = N'myTable';
GO

不過,如果使用者沒有許可權 myTable,查詢會傳回空的結果集。

元數據可見性設定的範圍和影響

元數據可見性設定僅適用於下列安全性實體:

  • 目錄檢視
  • 公開內建函數的中繼資料
  • 相容性檢視
  • 資料庫引擎 sp_help 預存程式
  • 資訊結構描述檢視
  • 擴充屬性

元數據可見性設定不適用於下列安全性實體:

  • 「記錄傳送」系統資料表
  • 資料庫維護計畫系統資料表
  • 複寫系統資料表
  • SQL Server Agent 系統資料表
  • 備份系統資料表
  • 復寫和 SQL Server Agent sp_help 預存程式

中繼資料存取受限表示如下:

  • 對系統檢視查詢可能只會傳回資料列的子集,或有時候傳回空的結果集。
  • 能夠發出元數據的內建函式,例如 OBJECTPROPERTYEX 可能會傳回 NULL。
  • 資料庫引擎 sp_help 預存程序可能只會傳回部分資料列,或 NULL。
  • 因此,依賴 公用 中繼資料存取的應用程式會受到影響。

SQL 模組(例如預存程序和觸發程序)會在呼叫者的安全性內容下執行,因此對中繼資料的存取能力有限。 例如,在下列的程式碼中,當預存程序嘗試存取資料表 myTable 的中繼資料而呼叫者對此資料表沒有任何權限時,將會傳回空的結果集。 在較早版本的 SQL Server 中,會傳回一個資料列。

CREATE PROCEDURE assumes_caller_can_access_metadata
BEGIN
SELECT name, object_id
FROM sys.objects
WHERE name = N'myTable';
END;
GO

若要允許呼叫端檢視中繼資料,您可以授與呼叫端 VIEW DEFINITION 權限,或在 SQL Server 2022 (16.x) 和更新版本中,於適當的範圍(例如物件層級、資料庫層級或伺服器層級)授與 VIEW SECURITY DEFINITION 或 VIEW PERFORMANCE DEFINITION 權限。 因此,在上一個範例中,如果呼叫端具有 VIEW DEFINITION 的 myTable權限,則預存程序會傳回一列。 欲了解更多資訊,請參閱GRANT資料庫GRANT權限。

您也可以修改預存程序,使其在擁有者的認證下執行。 當預存程序擁有者與資料表擁有者為同一人時,便會套用擁有權鏈結,而預存程序擁有者的安全性脈絡即可存取 myTable 的中繼資料。 在此情況下,下列程式碼會將一列中繼資料傳回給呼叫端。

注意

下列範例使用 sys.objects 目錄檢視,而非 sys.sysobjects 相容性檢視。

CREATE PROCEDURE does_not_assume_caller_can_access_metadata
WITH EXECUTE AS OWNER
AS
BEGIN
    SELECT name, object_id
    FROM sys.objects
    WHERE name = N'myTable';
END
GO

注意

您可以使用 EXECUTE AS 來暫時切換至呼叫端的安全性內容。 如需詳細資訊,請參閱EXECUTE AS。

元數據可見性設定的優點和限制

中繼資料可見性設定可在您的整體安全性計畫中扮演重要角色。 但在某些情況中,技術純熟又執意操作的使用者還是能夠強制洩漏某些中繼資料。 我們建議您將中繼資料權限實施為多層縱深防禦措施之一。

理論上,可以藉由調整查詢中述詞評估的順序,強制在錯誤訊息中發出元數據。 這類 試驗和錯誤攻擊 的可能性並不專屬於 SQL Server。 這隱含於關係代數中允許的關聯與交換轉換。 您可以限制錯誤訊息所傳回的資訊來減輕此風險。 若要以此方式進一步限制中繼資料的可見性,您可以用追蹤旗標 3625 來啟動伺服器。 此追蹤旗標限制錯誤訊息所顯示的資訊量。 而這有助於防止強制洩漏。 取捨是錯誤訊息很簡潔,而且可能難以用於偵錯目的。 如需詳細資訊,請參閱 資料庫引擎服務啟動選項 和 追蹤旗標。

下列元數據不受限於強制洩漏:

  • 此值儲存在 provider_string 的 sys.servers 資料行中。 沒有 ALTER ANY LINKED SERVER 權限的使用者會在此資料行中看到值 NULL 。

  • 使用者自訂物件 (例如預存程序或觸發程序) 的來源定義。 只有在下列其中一個條件成立時,原始程式碼才會顯示:

    • 使用者具有 VIEW DEFINITION 物件的權限。

    • 使用者尚未被拒絕VIEW DEFINITION物件的權限,且具有CONTROLALTERTAKE OWNERSHIP物件的權限。 所有其他使用者都會看到 NULL。

  • 在下列目錄檢視中找到的定義資料行:

    • sys.all_sql_modules
    • sys.server_sql_modules
    • sys.default_constraints
    • sys.numbered_procedures
    • sys.sql_modules
    • sys.check_constraints
    • sys.computed_columns
  • ctext 相容性檢視中的 syscomments 資料行。

  • sp_helptext 程序的輸出。

  • 資訊結構描述檢視中的下列資料行:

    • INFORMATION_SCHEMA.CHECK_CONSTRAINTS.CHECK_CLAUSE
    • INFORMATION_SCHEMA.DOMAINS.DOMAIN_DEFAULT
    • INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITION
    • INFORMATION_SCHEMA.COLUMNS.COLUMN_DEFAULT
    • INFORMATION_SCHEMA.ROUTINE_COLUMNS.COLUMN_DEFAULT
    • INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION
  • OBJECT_DEFINITION() 函數

  • 此值儲存在 password_hash 的 sys.sql_logins 資料行中。 沒有 CONTROL SERVER 的使用者,或在 SQL Server 2022 (16.x)及更新版本中沒有 VIEW ANY CRYPTOGRAPHICALLY SECURED DEFINITION 權限的使用者,會在此資料行中看到NULL值。

內建系統程序及函數的 SQL 定義會透過型錄視圖、sys.system_sql_modules儲存程序及sp_helptext函數公開可見。

注意

Azure Synapse Analytics 不支援系統預存程式 sp_helptext 。 請改用 sys.sql_modules 物件目錄檢視。

元數據可見性的一般原則

以下是有關中繼資料可見性時需考量的一些一般原則:

  • 固定角色的隱含權限
  • 權限範圍
  • 優先順序 DENY
  • 子元件中繼資料的可見性

固定角色和隱含許可權

固定角色可以存取的中繼資料取決於其對應的隱含權限。

權限範圍

在某個範圍內的權限,表示可檢視該範圍及其下所有包含範圍的中繼資料。 例如, SELECT 結構描述的許可權表示授與者 SELECT 具有該結構描述所包含之所有安全性實體的許可權。 因此,授與 SELECT 綱目權限可讓使用者查看綱目的中繼資料,以及其中的所有表格、檢視、函數、程序、佇列、同義字、類型及 XML 綱目集合。 如需範圍的詳細資訊,請參閱權限階層 (資料庫引擎)。

注意

UNMASK權限不會影響中繼資料的可見度:僅授予UNMASK不會揭露任何中繼資料。 UNMASK 總是需要附有 SELECT 許可才能產生任何效果。 範例:在資料庫範圍上授 UNMASK 及在個別資料表上授與 SELECT,結果是使用者只能看到他們可以從中選取的個別資料表的中繼資料,而無法看到其他的資料表。

優先順序 DENY

DENY 通常優先於其他權限。 例如,如果資料庫使用者已獲 EXECUTE 授與結構描述的權限,但已拒絕 EXECUTE 該結構描述中預存程序的權限,則使用者無法檢視該預存程序的中繼資料。

此外,如果使用者被拒絕 EXECUTE 結構描述的權限,但已獲得 EXECUTE 該結構描述中預存程序的權限,則使用者無法檢視該預存程序的中繼資料。

另一個範例是,如果使用者因為透過您各種角色成員資格而同時被授予和拒絕EXECUTE存儲程序的許可權,那麼DENY設定會優先,導致使用者無法檢視存儲程序的中繼資料。

子元件中繼資料的可見性

子元件可見度,例如索引、檢查條件約束和觸發程式,取決於父系的許可權。 這些子元件沒有可授與的許可權。 例如,如果某個使用者被授與了某個資料表的部分權限,該使用者就能檢視資料表、資料行、索引、檢查條件約束、觸發程序和其他子元件的中繼資料。 另一個範例是僅對給定資料表的個別資料行授予SELECT:這允許受授權者檢視整個資料表的中繼資料,包括所有資料行。 一種想法是,權限 VIEW DEFINITION 僅適用於實體層級(在本例中為資料表),不適用於子實體清單(例如資料行或安全性運算式)。

下列程式碼將示範此行為:

CREATE TABLE t1
(
    c1 INT,
    c2 VARCHAR
);
GO

CREATE USER testUser WITHOUT LOGIN;
GO

EXECUTE AS USER = 'testUser';

SELECT OBJECT_SCHEMA_NAME(object_id),
       OBJECT_NAME(object_id),
       name
FROM sys.columns;

SELECT * FROM sys.tables;
-- this returns no data, as the user has no permissions

REVERT;
GO

-- granting SELECT on only 1 column of the table:
GRANT SELECT ON t1 (c1) TO testUser;
GO

EXECUTE AS USER = 'testUser';

SELECT OBJECT_SCHEMA_NAME(object_id),
       OBJECT_NAME(object_id),
       name
FROM sys.columns;

SELECT * FROM sys.tables;
-- this returns metadata for all columns of the table and the table itself
;

REVERT;
GO

DROP TABLE t1;
DROP USER testUser;

可供所有資料庫用戶存取的元數據

在特定資料庫中,某些中繼資料必須可由所有使用者存取。 例如,檔案群組沒有可授與的許可權;因此,用戶無法獲授與檢視檔案群組元數據的許可權。 不過,任何可以建立資料表的使用者都必須能夠存取檔案群組中繼資料,才能使用ON <filegroup>陳述式的 TEXTIMAGE_ON <filegroup> or CREATE TABLE 子句。

由DB_ID()和DB_NAME()函數傳回的中繼資料對所有使用者都可見。

以下是 public 角色可見的目錄檢視清單。

  • sys.allocation_units
  • sys.column_type_usages
  • sys.configurations
  • sys.data_spaces
  • sys.database_files
  • sys.destination_data_spaces
  • sys.filegroups
  • sys.messages
  • sys.parameter_type_usages
  • sys.partition_functions
  • sys.partition_range_values
  • sys.partition_schemes
  • sys.partitions
  • sys.schemas
  • sys.sql_dependencies
  • sys.type_assembly_usages