Azure SQL 分析师可以从禁止的跨数据库数据创建视图

问题描述 投票:0回答:1

TLDR问题

用户可以通过在他拥有 CONTROL 权限的个人架构中创建禁止数据的视图来查看禁止的数据。


简介

我有一个带有两个数据库的 Azure SQL(托管实例)服务器:

  • sources
    :包含数据的表格
  • reports
    :视图构建在
    sources
  • 中的表格之上

reports
数据库中,数据分析师拥有自己的个人模式,有权创建视图和表。由于某些数据的性质,并非每个模式都允许向数据分析师公开。

问题

我拒绝/撤销对某些模式的访问,并且可以直接访问这些模式。但数据分析师仍然可以创建引用

sources
数据库中禁止的表的新视图,并仍然通过创建的视图查看数据。

问题

这应该是不可能的,因为数据分析师不应该能够访问

sources
数据库中的数据。但我似乎找不到办法来阻止这种情况。

设置

用户的帐户是在 Azure 的 AD 中创建的。我在

reports
数据库中为用户创建登录名。

CREATE USER [[email protected]] FOR LOGIN [[email protected]];

用他自己的模式:

USE [reports];

CREATE SCHEMA mypersonal;

-- Create a role
CREATE ROLE mypersonal_schema_creator;

-- Grant permissions to the role
GRANT CREATE TABLE TO mypersonal_schema_creator;
GRANT CREATE VIEW TO mypersonal_schema_creator;

-- Grant control on the schema to the role
GRANT CONTROL ON SCHEMA::mypersonal TO mypersonal_schema_creator;

-- Add the user to the role
ALTER ROLE mypersonal_schema_creator ADD MEMBER [[email protected]];

我授予用户访问

sources
数据库中模式的权限:

-- Connect to sqldb-ingestion01
CREATE USER [[email protected]] FOR LOGIN [[email protected]];

-- Grant SELECT permission on the ALLOWED schema
GRANT SELECT ON SCHEMA::allowed TO [[email protected]];

并且当用户访问

sources
数据库时,他看不到除
allowed
模式之外的其他模式。但是当他创建一个访问
forbidden
模式中的表的视图时,他仍然可以看到数据。

permissions azure-sql-database access-control azure-sql-managed-instance
1个回答
0
投票

这既是预期行为,也是有记录的行为。您所经历的就是所谓的所有权链。

当调用某个对象(例如

VIEW
PROCEDURE
)时,如果
USER
有权使用该对象,那么它也会 隐式 被授予访问与该对象具有相同所有者的对象引用的任何对象的权限对象,而在该对象的范围内。在这种情况下,您有一个
USER
创建了一个
VIEW
,其中
SELECT
来自具有相同所有者的其他对象(大概是
dbo
或其他东西),所以即使
USER
不对基础表具有显式访问权限,
VIEW
允许它们隐式权限。

虽然我很感激您为我们提供了一些细节,但我将使用对象 DDL 来设置我自己的示例。首先,我们创建一个测试数据库并

USER

CREATE DATABASE YourDB;
GO
USE YourDB;
GO

CREATE USER SomeUser WITHOUT LOGIN; --Example User
GO

CREATE SCHEMA SomeSchema; --Example schema
GO

GRANT CONTROL ON SCHEMA::SomeSchema TO SomeUser;
GRANT CREATE TABLE TO SomeUser;
GRANT CREATE VIEW TO SomeUser;
GRANT SELECT ON SCHEMA::SomeSchema TO SomeUser;

因此

USER
有权创建
VIEW
TABLE
,它们
CONTROL
“他们的”模式,并且他们也可以从他们的模式中
SELECT

现在让我们创建一些示例对象:

CREATE TABLE dbo.SomeTable (SomeID int);
CREATE TABLE dbo.AnotherTable (AnotherID int);
--We don't need any sample data, this is just permissions checking;
GO
GRANT SELECT ON dbo.SomeTable TO SomeUser;

注意,我授予

USER
SomeTable
的显式访问权限,但不授予
AnotherTable

现在,作为

USER
,我要
CREATE
一些
VIEW
,然后做一些测试
SELECT

EXECUTE AS USER = 'SomeUser';
GO

SELECT SomeID
FROM dbo.SomeTable; --Works
GO

CREATE VIEW SomeSchema.SomeView AS
    SELECT SomeID AS ID
    FROM dbo.SomeTable;
GO

SELECT ID
FROM SomeSchema.SomeView; --Doesn't works.
GO
SELECT AnotherID
FROM dbo.AnotherTable; --Works
GO

CREATE VIEW SomeSchema.AnotherView AS
    SELECT AnotherID AS ID
    FROM dbo.AnotherTable;
GO

SELECT ID
FROM SomeSchema.AnotherView; --Does works, due to permission chaining
GO

GO
REVERT; --back to normal

正如我们所看到的,这正如我所预期的那样;唯一失败的

SELECT
是直接针对物体
dbo.AnotherTable

为了解决这个问题,正如我提到的,更改

USER
正在使用的架构的所有者:

--Let's change the owner of the schema
ALTER AUTHORIZATION ON SCHEMA::SomeSchema TO SomeUser;

现在我们可以再次测试,只需查询 2 个

VIEW

--Now let's try those VIEWs again
EXECUTE AS USER = 'SomeUser';
GO
SELECT SomeID
FROM dbo.SomeTable; --Works, we have explicit SELECT on  the table
GO
SELECT ID
FROM SomeSchema.AnotherView; --Fails, we don't have explicit permission and ownership chaining fails
GO
REVERT;

这次针对

SomeSchema.AnotherView
also 的查询失败,与尝试直接查询
dbo.AnotherTable
时遇到的权限错误相同。


清理

USE master;
GO
ALTER DATABASE YourDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
DROP DATABASE YourDB;
© www.soinside.com 2019 - 2024. All rights reserved.