You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The visibility of metadata is limited to securables that a user either owns or on which the user has been granted some permission.
26
27
27
-
For example, the following query returns a row if the user grants a permission such as SELECT or INSERT on the table `myTable`.
28
+
For example, the following query returns a row if the user grants a permission such as `SELECT` or `INSERT` on the table `myTable`.
28
29
29
30
```sql
30
31
SELECT name, object_id
@@ -60,7 +61,7 @@ Limited metadata accessibility means the following:
60
61
- Queries on system views might only return a subset of rows, or sometimes an empty result set.
61
62
- Metadata-emitting, built-in functions such as OBJECTPROPERTYEX might return `NULL`.
62
63
- The [!INCLUDE [ssDE](../../includes/ssde-md.md)]`sp_help` stored procedures might return only a subset of rows, or `NULL`.
63
-
- As a result, applications that assume **public** metadata access will break.
64
+
- As a result, applications that assume **public** metadata access breaks.
64
65
65
66
SQL modules, such as stored procedures and triggers, run under the security context of the caller and, therefore, have limited metadata accessibility. For example, in the following code, when the stored procedure tries to access metadata for the table `myTable` on which the caller has no rights, an empty result set is returned. In earlier releases of [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)], a row is returned.
66
67
@@ -74,43 +75,43 @@ END;
74
75
GO
75
76
```
76
77
77
-
To allow callers to view metadata, you can grant the callers VIEW DEFINITION permission or starting with SQL Server 2022 either VIEW SECURITY DEFINITION or VIEW PERFORMANCE DEFINITION at an appropriate scope: object level, database level, or server level. Therefore, in the previous example, if the caller has VIEW DEFINITION permission on `myTable`, the stored procedure returns a row. For more information, see [GRANT (Transact-SQL)](../../t-sql/statements/grant-transact-sql.md) and [GRANT Database Permissions (Transact-SQL)](../../t-sql/statements/grant-database-permissions-transact-sql.md).
78
+
To allow callers to view metadata, you can grant the callers `VIEW DEFINITION` permission, or in [!INCLUDE [sssql22-md](../../includes/sssql22-md.md)] and later versions, either `VIEW SECURITY DEFINITION` or `VIEW PERFORMANCE DEFINITION` at an appropriate scope: object level, database level, or server level. Therefore, in the previous example, if the caller has `VIEW DEFINITION` permission on `myTable`, the stored procedure returns a row. For more information, see [GRANT](../../t-sql/statements/grant-transact-sql.md) and [GRANT Database Permissions](../../t-sql/statements/grant-database-permissions-transact-sql.md).
78
79
79
80
You can also modify the stored procedure so that it executes under the credentials of the owner. When the procedure owner and the table owner are the same owner, ownership chaining applies, and the security context of the procedure owner enables access to the metadata for `myTable`. Under this scenario, the following code returns a row of metadata to the caller.
80
81
81
82
> [!NOTE]
82
-
> The following example uses the [sys.objects](../../relational-databases/system-catalog-views/sys-objects-transact-sql.md) catalog view instead of the [sys.sysobjects](../../relational-databases/system-compatibility-views/sys-sysobjects-transact-sql.md) compatibility view.
83
+
> The following example uses the [sys.objects](../system-catalog-views/sys-objects-transact-sql.md) catalog view instead of the [sys.sysobjects](../system-compatibility-views/sys-sysobjects-transact-sql.md) compatibility view.
> You can use EXECUTE AS to temporarily switch to the security context of the caller. For more information, see [EXECUTE AS (Transact-SQL)](../../t-sql/statements/execute-as-transact-sql.md).
98
+
> You can use `EXECUTE AS` to temporarily switch to the security context of the caller. For more information, see [EXECUTE AS](../../t-sql/statements/execute-as-transact-sql.md).
98
99
99
100
## Benefits and limits of metadata visibility configuration
100
101
101
102
Metadata visibility configuration can play an important role in your overall security plan. However, there are cases in which a skilled and determined user can force the disclosure of some metadata. We recommend that you deploy metadata permissions as one of many defenses-in-depth.
102
103
103
-
It's theoretically possible to force the emission of metadata in error messages by manipulating the order of predicate evaluation in queries. The possibility of such *trial-and-error attacks* isn't specific to [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)]. It's implied by the associative and commutative transformations permitted in relational algebra. You can mitigate this risk by limiting the information returned in error messages. To further restrict the visibility of metadata in this way, you can start the server with trace flag 3625. This trace flag limits the amount of information shown in error messages. In turn, this helps to prevent forced disclosures. The tradeoff is that error messages will be terse and might be difficult to use for debugging purposes. For more information, see [Database Engine Service Startup Options](../../database-engine/configure-windows/database-engine-service-startup-options.md) and [Trace Flags (Transact-SQL)](../../t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql.md).
104
+
It's theoretically possible to force the emission of metadata in error messages by manipulating the order of predicate evaluation in queries. The possibility of such *trial-and-error attacks* isn't specific to [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)]. It's implied by the associative and commutative transformations permitted in relational algebra. You can mitigate this risk by limiting the information returned in error messages. To further restrict the visibility of metadata in this way, you can start the server with trace flag 3625. This trace flag limits the amount of information shown in error messages. In turn, this helps to prevent forced disclosures. The tradeoff is that error messages are terse and might be difficult to use for debugging purposes. For more information, see [Database Engine Service startup options](../../database-engine/configure-windows/database-engine-service-startup-options.md) and [Trace Flags](../../t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql.md).
104
105
105
106
The following metadata isn't subject to forced disclosure:
106
107
107
-
- The value stored in the `provider_string` column of `sys.servers`. A user that doesn't have **ALTER ANY LINKED SERVER** permission will see a `NULL` value in this column.
108
+
- The value stored in the `provider_string` column of `sys.servers`. A user that doesn't have `ALTER ANY LINKED SERVER` permission sees a `NULL` value in this column.
108
109
109
-
- Source definition of a user-defined object such as a stored procedure or trigger. The source code is visible only when one of the following is true:
110
+
- Source definition of a user-defined object such as a stored procedure or trigger. The source code is visible only when one of the following conditions is true:
110
111
111
-
- The user has **VIEW DEFINITION** permission on the object.
112
+
- The user has `VIEW DEFINITION` permission on the object.
112
113
113
-
- The user hasn't been denied **VIEW DEFINITION** permission on the object and has **CONTROL**, **ALTER**, or **TAKE OWNERSHIP** permission on the object. All other users will see `NULL`.
114
+
- The user hasn't been denied `VIEW DEFINITION` permission on the object and has `CONTROL`, `ALTER`, or `TAKE OWNERSHIP` permission on the object. All other users see `NULL`.
114
115
115
116
- The definition columns found in the following catalog views:
116
117
@@ -135,12 +136,11 @@ The following metadata isn't subject to forced disclosure:
- The value stored in the password_hash column of `sys.sql_logins`. A user that doesn't have **CONTROL SERVER** or starting with SQL Server 2022 the **VIEW ANY CRYPTOGRAPHICALLY SECURED DEFINITION** permission will see a `NULL` value in this column.
141
+
- The value stored in the `password_hash` column of `sys.sql_logins`. A user that doesn't have `CONTROL SERVER`, or in [!INCLUDE [sssql22-md](../../includes/sssql22-md.md)] and later versions, the `VIEW ANY CRYPTOGRAPHICALLY SECURED DEFINITION` permission sees a `NULL` value in this column.
141
142
142
-
> [!NOTE]
143
-
> The SQL definitions of built-in system procedures and functions are publicly visible through the `sys.system_sql_modules` catalog view, the `sp_helptext` stored procedure, and the OBJECT_DEFINITION() function.
143
+
The SQL definitions of built-in system procedures and functions are publicly visible through the `sys.system_sql_modules` catalog view, the `sp_helptext` stored procedure, and the `OBJECT_DEFINITION()` function.
144
144
145
145
> [!NOTE]
146
146
> The system stored procedure `sp_helptext` isn't supported in Azure Synapse Analytics. Instead, use the `sys.sql_modules` object catalog view.
@@ -150,11 +150,8 @@ The following metadata isn't subject to forced disclosure:
150
150
The following are some general principles to consider regarding metadata visibility:
151
151
152
152
- Fixed roles implicit permissions
153
-
154
153
- Scope of permissions
155
-
156
-
- Precedence of DENY
157
-
154
+
- Precedence of `DENY`
158
155
- Visibility of subcomponent metadata
159
156
160
157
### Fixed roles and implicit permissions
@@ -163,106 +160,101 @@ Metadata that can be accessed by fixed roles depends upon their corresponding im
163
160
164
161
### Scope of permissions
165
162
166
-
Permissions at one scope imply the ability to see metadata at that scope and at all enclosed scopes. For example, **SELECT** permission on a schema implies that the grantee has **SELECT** permission on all securables that are contained by that schema. The granting of **SELECT** permission on a schema therefore enables a user to see the metadata of the schema and also all tables, views, functions, procedures, queues, synonyms, types, and XML schema collections within it. For more information about scopes, see [Permissions Hierarchy (Database Engine)](../../relational-databases/security/permissions-hierarchy-database-engine.md).
163
+
Permissions at one scope imply the ability to see metadata at that scope and at all enclosed scopes. For example, `SELECT` permission on a schema implies that the grantee has `SELECT` permission on all securables that are contained by that schema. The granting of `SELECT` permission on a schema therefore enables a user to see the metadata of the schema and also all tables, views, functions, procedures, queues, synonyms, types, and XML schema collections within it. For more information about scopes, see [Permissions Hierarchy (Database Engine)](permissions-hierarchy-database-engine.md).
167
164
168
165
> [!NOTE]
169
-
> The **UNMASK** permission doesn't influence metadata visibility: granting **UNMASK** alone won't disclose any Metadata. **UNMASK** will always need to be accompanied by a **SELECT** permission to have any effect. Example: granting **UNMASK** on database scope and granting **SELECT** on an individual Table will have the result that the user can only see the metadata of the individual table from which they can select, not any others.
166
+
> The `UNMASK` permission doesn't influence metadata visibility: granting `UNMASK` alone doesn't disclose any Metadata. `UNMASK`always needs to be accompanied by a `SELECT` permission to have any effect. Example: granting `UNMASK` on database scope and granting `SELECT` on an individual table has the result that the user can only see the metadata of the individual table from which they can select, not any others.
170
167
171
168
### Precedence of DENY
172
169
173
-
**DENY** typically takes precedence over other permissions. For example, if a database user is granted **EXECUTE** permission on a schema but has been denied **EXECUTE** permission on a stored procedure in that schema, the user can't view the metadata for that stored procedure.
170
+
`DENY` typically takes precedence over other permissions. For example, if a database user is granted `EXECUTE` permission on a schema but has been denied `EXECUTE` permission on a stored procedure in that schema, the user can't view the metadata for that stored procedure.
174
171
175
-
Additionally, if a user is denied **EXECUTE** permission on a schema but has been granted **EXECUTE** permission on a stored procedure in that schema, the user can't view the metadata for that stored procedure.
172
+
Additionally, if a user is denied `EXECUTE` permission on a schema but has been granted `EXECUTE` permission on a stored procedure in that schema, the user can't view the metadata for that stored procedure.
176
173
177
-
For another example, if a user has been granted and denied **EXECUTE** permission on a stored procedure, which is possible through your various role memberships, **DENY** takes precedence and the user can't view the metadata of the stored procedure.
174
+
For another example, if a user has been granted and denied `EXECUTE` permission on a stored procedure, which is possible through your various role memberships, `DENY` takes precedence and the user can't view the metadata of the stored procedure.
178
175
179
176
### Visibility of subcomponent metadata
180
177
181
-
The visibility of subcomponents, such as indexes, check constraints, and triggers are determined by permissions on the parent. These subcomponents don't have grantable permissions. For example, if a user has been granted some permission on a table, the user can view the metadata for the tables, columns, indexes, check constraints, triggers, and other such subcomponents. Another example is granting **SELECT** on only an individual column of a given table: this will allow the grantee to view the metadata of the whole table, including all columns. One way to think of it, is that the **VIEW DEFINITION** permission only works on entity-level (the table in this case) and isn't available for Subentity lists (such as column or security expressions).
178
+
The visibility of subcomponents, such as indexes, check constraints, and triggers are determined by permissions on the parent. These subcomponents don't have grantable permissions. For example, if a user has been granted some permission on a table, the user can view the metadata for the tables, columns, indexes, check constraints, triggers, and other such subcomponents. Another example is granting `SELECT` on only an individual column of a given table: this allows the grantee to view the metadata of the whole table, including all columns. One way to think of it, is that the `VIEW DEFINITION` permission only works on entity-level (the table in this case) and isn't available for Subentity lists (such as column or security expressions).
182
179
183
180
The following code demonstrates this behavior:
184
181
185
182
```sql
186
183
CREATETABLEt1
187
184
(
188
-
c1 int,
189
-
c2 varchar
190
-
);
185
+
c1 INT,
186
+
c2 VARCHAR
187
+
);
191
188
GO
189
+
192
190
CREATEUSERtestUser WITHOUT LOGIN;
193
191
GO
194
192
195
-
EXECUTE AS USER='testUser';
196
-
SELECT OBJECT_SCHEMA_NAME(object_id), OBJECT_NAME(object_id), name FROMsys.columns;
197
-
SELECT*FROMsys.tables
193
+
EXECUTE AS USER ='testUser';
194
+
195
+
SELECT OBJECT_SCHEMA_NAME(object_id),
196
+
OBJECT_NAME(object_id),
197
+
name
198
+
FROMsys.columns;
199
+
200
+
SELECT*FROMsys.tables;
198
201
-- this returns no data, as the user has no permissions
202
+
199
203
REVERT;
200
204
GO
201
205
202
206
-- granting SELECT on only 1 column of the table:
203
-
GRANTSELECTON t1(c1) TO testUser;
207
+
GRANTSELECTON t1(c1) TO testUser;
204
208
GO
205
-
EXECUTE AS USER='testUser';
206
-
SELECT OBJECT_SCHEMA_NAME(object_id), OBJECT_NAME(object_id), name FROMsys.columns;
207
-
SELECT*FROMsys.tables
209
+
210
+
EXECUTE AS USER ='testUser';
211
+
212
+
SELECT OBJECT_SCHEMA_NAME(object_id),
213
+
OBJECT_NAME(object_id),
214
+
name
215
+
FROMsys.columns;
216
+
217
+
SELECT*FROMsys.tables;
208
218
-- this returns metadata for all columns of the table and the table itself
219
+
;
220
+
209
221
REVERT;
210
222
GO
211
223
212
-
DROPTABLE t1
213
-
DROPUSER testUser
224
+
DROPTABLE t1;
225
+
DROPUSER testUser;
214
226
```
215
227
216
228
#### Metadata that is accessible to all database users
217
229
218
-
Some metadata must be accessible to all users in a specific database. For example, filegroups don't have conferrable permissions; therefore, a user can't be granted permission to view the metadata of a filegroup. However, any user that can create a table must be able to access filegroup metadata to use the ON *filegroup* or TEXTIMAGE_ON *filegroup* clauses of the CREATE TABLE statement.
230
+
Some metadata must be accessible to all users in a specific database. For example, filegroups don't have conferrable permissions; therefore, a user can't be granted permission to view the metadata of a filegroup. However, any user that can create a table must be able to access filegroup metadata to use the `ON <filegroup>` or `TEXTIMAGE_ON <filegroup>` clauses of the `CREATE TABLE` statement.
219
231
220
-
The metadata that is returned by the DB_ID() and DB_NAME() functions is visible to all users.
232
+
The metadata that is returned by the `DB_ID()` and `DB_NAME()` functions is visible to all users.
221
233
222
234
This is a list of the catalog views that are visible to the **public** role.
0 commit comments