Безпека баз даних
Безпека баз даних
Навіщо потрібна безпека БД?
Уявіть, що ваша база даних — це банківське сховище. Ви не можете дозволити будь-кому зайти всередину та робити що завгодно з вашими активами.
Конфіденційність
Цілісність
Аудит
Compliance
Системні таблиці та представлення
sysobjects, syscolumns). Починаючи з SQL Server 2005/2008, Microsoft переходить на системні представлення каталогу (sys.*), які є більш структурованими та стабільними.Порівняння: SQL Server 2000 vs 2008+
-- Старі системні таблиці
SELECT * FROM sysobjects WHERE xtype = 'U'; -- Таблиці
SELECT * FROM syscolumns; -- Стовпці
SELECT * FROM sysusers; -- Користувачі
SELECT * FROM sysprocedures; -- Процедури
-- Нові системні представлення
SELECT * FROM sys.objects WHERE type = 'U'; -- Таблиці
SELECT * FROM sys.columns; -- Стовпці
SELECT * FROM sys.database_principals; -- Користувачі
SELECT * FROM sys.procedures; -- Процедури
Основні системні представлення
Корисні представлення для роботи з метаданими
-- Інформація про об'єкти БД
SELECT
name AS [Назва об'єкта],
type_desc AS [Тип],
create_date AS [Дата створення],
modify_date AS [Дата зміни]
FROM sys.objects
WHERE is_ms_shipped = 0 -- Виключити системні об'єкти
ORDER BY type_desc, name;
-- Перегляд тексту збережених процедур і функцій
SELECT
o.name AS [Назва],
o.type_desc AS [Тип],
m.definition AS [Код]
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id = o.object_id
WHERE o.is_ms_shipped = 0;
-- Інформація про тригери
SELECT
name AS [Тригер],
parent_class_desc AS [Область],
is_disabled AS [Відключений],
is_instead_of_trigger AS [INSTEAD OF]
FROM sys.triggers
WHERE is_ms_shipped = 0;
sys.* представлення замість застарілих системних таблиць. Це гарантує сумісність з майбутніми версіями SQL Server.Режими автентифікації
SQL Server підтримує два основні режими автентифікації:
Автентифікація Windows (рекомендовано)
Переваги:
- Централізоване керування через Active Directory
- Підтримка Kerberos
- Автоматична інтеграція з групами безпеки
- Немає необхідності зберігати паролі в додатку
-- Windows-логін створюється через AD
CREATE LOGIN [DOMAIN\UserName] FROM WINDOWS;
Mixed Mode (SQL Server + Windows)
Коли використовувати:
- Додатки, які працюють на різних платформах (Linux, macOS)
- Веб-додатки без інтеграції з AD
- Тестові середовища
-- SQL Server логін
CREATE LOGIN AppUser WITH PASSWORD = 'StrongP@ssw0rd!';
- Використовуйте складні паролі
- Застосовуйте політику складності паролів
- Регулярно змінюйте паролі
- Шифруйте з'єднання (SSL/TLS)
::
Двухрівнева модель безпеки
SQL Server використовує дворівневу модель безпеки:
- Server Level (LOGIN) — автентифікація на рівні сервера
- Database Level (USER) — авторизація на рівні бази даних
USER — це облікові дані для роботи з конкретною базою даних.Один LOGIN може мати кілька USER у різних базах даних.
Керування логінами (Logins)
Створення логінів
-- Створення SQL Server логіна
CREATE LOGIN AppUser
WITH PASSWORD = 'MyP@ssw0rd123',
DEFAULT_DATABASE = MyDatabase,
CHECK_EXPIRATION = ON,
CHECK_POLICY = ON;
Параметри:
CHECK_EXPIRATION— термін дії пароляCHECK_POLICY— політика складності паролів WindowsDEFAULT_DATABASE— БД за замовчуванням
-- Створення Windows логіна
CREATE LOGIN [DOMAIN\UserName] FROM WINDOWS
WITH DEFAULT_DATABASE = MyDatabase;
-- Створення групи з Active Directory
CREATE LOGIN [DOMAIN\DevelopersGroup] FROM WINDOWS;
:: ::
Модифікація логінів
-- Зміна пароля
ALTER LOGIN AppUser
WITH PASSWORD = 'NewP@ssw0rd456';
-- Розблокування та зміна пароля
ALTER LOGIN AppUser
WITH PASSWORD = 'NewP@ssw0rd456' UNLOCK;
-- Відключення логіна (не видаляючи)
ALTER LOGIN AppUser DISABLE;
-- Увімкнення логіна
ALTER LOGIN AppUser ENABLE;
-- Перейменування логіна
ALTER LOGIN AppUser WITH NAME = NewAppUser;
Видалення логінів
-- Видалення логіна
DROP LOGIN AppUser;
- Він не є власником баз даних або схем
- Немає активних підключень
- Видалені всі відповідні користувачі в базах даних
Перегляд логінів
-- Список всіх логінів
SELECT
name AS [Login],
type_desc AS [Тип],
create_date AS [Створено],
is_disabled AS [Відключено]
FROM sys.sql_logins
ORDER BY name;
-- Системна процедура
EXEC sp_helplogins;
EXEC sp_helplogins 'AppUser'; -- Детальна інформація про конкретний логін
Керування користувачами (Users)
Після створення логіна потрібно створити користувача в конкретній базі даних.
Створення користувачів
USE MyDatabase;
GO
-- Створення користувача для SQL-логіна
CREATE USER AppUser FOR LOGIN AppUser;
-- Створення користувача для Windows-логіна
CREATE USER [DOMAIN\UserName] FOR LOGIN [DOMAIN\UserName];
-- Користувач без логіна (для certificates або asymmetric keys)
CREATE USER GuestUser WITHOUT LOGIN;
-- Користувач з default schema
CREATE USER DevUser FOR LOGIN DevUser
WITH DEFAULT_SCHEMA = dbo;
Модифікація користувачів
-- Зміна схеми за замовчуванням
ALTER USER AppUser WITH DEFAULT_SCHEMA = Sales;
-- Перейменування користувача
ALTER USER AppUser WITH NAME = NewAppUser;
Видалення користувачів
USE MyDatabase;
GO
DROP USER AppUser;
Перегляд користувачів
-- Список користувачів поточної БД
SELECT
name AS [Користувач],
type_desc AS [Тип],
authentication_type_desc AS [Автентифікація],
default_schema_name AS [Схема за замовчуванням],
create_date AS [Створено]
FROM sys.database_principals
WHERE type IN ('S', 'U', 'G') -- S=SQL user, U=Windows user, G=Windows group
ORDER BY name;
Ролі (Roles)
Ролі — це механізм групування користувачів для спрощення управління правами доступу.
Фіксовані ролі сервера (Fixed Server Roles)
ALTER SERVER ROLE securityadmin ADD MEMBER [DOMAIN\SecurityAdmin];
::
::
Фіксовані ролі бази даних (Fixed Database Roles)
USE MyDatabase;
GO
-- db_owner — повний контроль над БД
ALTER ROLE db_owner ADD MEMBER AppUser;
-- db_securityadmin — керування ролями та правами
ALTER ROLE db_securityadmin ADD MEMBER SecurityUser;
-- db_accessadmin — додавання/видалення користувачів
ALTER ROLE db_accessadmin ADD MEMBER AccessUser;
-- db_backupoperator — резервне копіювання
ALTER ROLE db_backupoperator ADD MEMBER BackupUser;
-- db_ddladmin — DDL операції (CREATE, ALTER, DROP)
ALTER ROLE db_ddladmin ADD MEMBER DDLUser;
USE MyDatabase;
GO
-- db_datareader — читання всіх даних
ALTER ROLE db_datareader ADD MEMBER ReaderUser;
-- db_datawriter — зміна всіх даних
ALTER ROLE db_datawriter ADD MEMBER WriterUser;
-- db_denydatareader — заборонити читання
ALTER ROLE db_denydatareader ADD MEMBER DeniedReaderUser;
-- db_denydatawriter — заборонити запис
ALTER ROLE db_denydatawriter ADD MEMBER DeniedWriterUser;
db_datareader + db_datawriter замість надання ролі db_owner.Користувацькі ролі бази даних
USE MyDatabase;
GO
-- Створення власної ролі
CREATE ROLE SalesTeam;
-- Надання прав ролі
GRANT SELECT, INSERT, UPDATE ON Sales.Orders TO SalesTeam;
GRANT SELECT ON Sales.Customers TO SalesTeam;
GRANT EXECUTE ON dbo.GetSalesReport TO SalesTeam;
-- Додавання користувачів до ролі
ALTER ROLE SalesTeam ADD MEMBER SalesUser1;
ALTER ROLE SalesTeam ADD MEMBER SalesUser2;
-- Видалення користувача з ролі
ALTER ROLE SalesTeam DROP MEMBER SalesUser1;
-- Видалення ролі
DROP ROLE SalesTeam;
Застарілі процедури (SQL Server 2005-2008)
ALTER SERVER ROLE та ALTER ROLE замість них.-- ЗАСТАРІЛО: Додавання до серверної ролі
EXEC sp_addsrvrolemember 'AppUser', 'dbcreator';
-- ЗАСТАРІЛО: Видалення із серверної ролі
EXEC sp_dropsrvrolemember 'AppUser', 'dbcreator';
-- ЗАСТАРІЛО: Додавання до ролі БД
EXEC sp_addrolemember 'db_datareader', 'AppUser';
-- ЗАСТАРІЛО: Видалення з ролі БД
EXEC sp_droprolemember 'db_datareader', 'AppUser';
Перегляд членства в ролях
-- Серверні ролі
SELECT
r.name AS [Роль],
m.name AS [Член]
FROM sys.server_role_members rm
JOIN sys.server_principals r ON rm.role_principal_id = r.principal_id
JOIN sys.server_principals m ON rm.member_principal_id = m.principal_id
ORDER BY r.name, m.name;
-- Ролі БД
SELECT
r.name AS [Роль],
m.name AS [Член]
FROM sys.database_role_members rm
JOIN sys.database_principals r ON rm.role_principal_id = r.principal_id
JOIN sys.database_principals m ON rm.member_principal_id = m.principal_id
ORDER BY r.name, m.name;
Ролі додатків (Application Roles)
Application Roles — це спеціальний тип ролі, яка активується паролем і не має прямих членів.
Створення та використання
-- Створення Application Role
CREATE APPLICATION ROLE AppRole
WITH PASSWORD = 'SecureP@ssw0rd!',
DEFAULT_SCHEMA = dbo;
-- Надання прав
GRANT SELECT, INSERT ON dbo.Orders TO AppRole;
GRANT EXECUTE ON dbo.ProcessOrder TO AppRole;
-- Активація ролі з додатка
DECLARE @cookie VARBINARY(8000);
EXEC sp_setapprole
@rolename = 'AppRole',
@password = 'SecureP@ssw0rd!',
@fCreateCookie = 1,
@cookie = @cookie OUTPUT;
-- Виконання операцій під роллю
SELECT * FROM dbo.Orders;
-- Повернення до попереднього контексту
EXEC sp_unsetapprole @cookie;
- Двох-рівневі додатки, де всі користувачі підключаються через єдиний акаунт
- Потрібен додатковий рівень безпеки для певних операцій
- Розмежування прав доступу на рівні додатка, а не користувача
Модифікація та видалення
-- Зміна пароля
ALTER APPLICATION ROLE AppRole
WITH PASSWORD = 'NewP@ssw0rd!';
-- Зміна схеми за замовчуванням
ALTER APPLICATION ROLE AppRole
WITH DEFAULT_SCHEMA = Sales;
-- Видалення
DROP APPLICATION ROLE AppRole;
- Не можна змінювати контекст БД (
USE) - Втрачається інформація про оригінального користувача (але можна зберегти через cookie)
- Всі операції виконуються під контекстом ролі
Права доступу (Permissions)
SQL Server має гранульовану систему прав доступу на рівні об'єктів.
Ієрархія прав
Надання прав (GRANT)
USE MyDatabase;
GO
-- Надати права на читання таблиці
GRANT SELECT ON dbo.Employees TO AppUser;
-- Надати права на конкретні стовпці
GRANT SELECT ON dbo.Employees(FirstName, LastName, Email) TO AppUser;
-- Надати права на оновлення
GRANT UPDATE ON dbo.Products TO SalesUser;
-- Надати права на виконання процедури
GRANT EXECUTE ON dbo.GetSalesReport TO ReportUser;
-- Надати права на схему
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::Sales TO SalesTeam;
-- Надати права з можливістю передачі (WITH GRANT OPTION)
GRANT SELECT ON dbo.Orders TO ManagerUser WITH GRANT OPTION;
WITH GRANT OPTION дозволяє користувачу надавати права іншим користувачам.Відмова в правах (DENY)
-- Явно заборонити читання
DENY SELECT ON dbo.Salaries TO RegularUser;
-- Заборонити видалення
DENY DELETE ON dbo.Orders TO AppUser;
-- Заборонити всі DML операції
DENY SELECT, INSERT, UPDATE, DELETE ON dbo.SecurityAudit TO AppUser;
DENY має вищий пріоритет ніж GRANT. Навіть якщо користувач є членом ролі з правом SELECT, але має явний DENY, доступ буде заборонено.Відкликання прав (REVOKE)
-- Відкликати права на читання
REVOKE SELECT ON dbo.Employees FROM AppUser;
-- Відкликати права на виконання
REVOKE EXECUTE ON dbo.ProcessOrder FROM AppUser;
-- Відкликати GRANT OPTION (але залишити саме право)
REVOKE GRANT OPTION FOR SELECT ON dbo.Orders FROM ManagerUser;
Перегляд прав
-- Права на об'єкти поточної БД
SELECT
dp.name AS [Principal],
dp.type_desc AS [Principal Type],
o.name AS [Object],
p.permission_name AS [Permission],
p.state_desc AS [State]
FROM sys.database_permissions p
JOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id
LEFT JOIN sys.objects o ON p.major_id = o.object_id
WHERE dp.name = 'AppUser'
ORDER BY o.name, p.permission_name;
-- Права на рівні сервера
SELECT
sp.name AS [Principal],
p.permission_name AS [Permission],
p.state_desc AS [State]
FROM sys.server_permissions p
JOIN sys.server_principals sp ON p.grantee_principal_id = sp.principal_id
WHERE sp.name = 'AppUser';
Best Practices для безпеки
- Використовуйте Windows Authentication
- Принцип найменших привілеїв
- Використовуйте ролі
- Аудит доступу
- Схеми для розділення
- Шифрування з'єднань
Перевірка складності паролів
-- Увімкнути політику паролів
ALTER LOGIN AppUser
WITH CHECK_POLICY = ON, CHECK_EXPIRATION = ON;
-- Вимоги до пароля:
-- - Мінімум 8 символів
-- - Містить великі та малі літери
-- - Містить цифри
-- - Містить спеціальні символи
Відстеження автентифікації
-- Створення DDL тригера для відстеження створення логінів
CREATE TRIGGER trg_AuditLoginCreation
ON ALL SERVER
FOR CREATE_LOGIN
AS
BEGIN
DECLARE @EventData XML = EVENTDATA();
INSERT INTO SecurityDB.dbo.LoginAudit (
EventType,
LoginName,
CreatedBy,
EventDate
)
SELECT
@EventData.value('(/EVENT_INSTANCE/EventType)[1]', 'NVARCHAR(100)'),
@EventData.value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(100)'),
@EventData.value('(/EVENT_INSTANCE/LoginName)[1]', 'NVARCHAR(100)'),
GETDATE();
END;
GO
Відстеження невдалих спроб входу
-- Створення LOGON тригера
CREATE TRIGGER trg_LoginFailureTracking
ON ALL SERVER
WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN
-- Перевірка кількості невдалих спроб
DECLARE @LoginName NVARCHAR(128) = ORIGINAL_LOGIN();
DECLARE @FailedAttempts INT;
SELECT @FailedAttempts = COUNT(*)
FROM SecurityDB.dbo.FailedLogins
WHERE LoginName = @LoginName
AND AttemptTime > DATEADD(MINUTE, -15, GETDATE());
-- Якщо більше 5 невдалих спроб за 15 хвилин
IF @FailedAttempts >= 5
BEGIN
ROLLBACK;
RAISERROR('Забагато невдалих спроб входу. Акаунт тимчасово заблоковано.', 16, 1);
END
END;
GO
Практичні завдання
::
Корисні поради
- Логіни:
app_shopuser,svc_reporting - Ролі:
SalesTeam,ReportReaders,DataAnalysts - Application Roles:
WebAppRole,MobileAppRole
app_ для додатків, svc_ для сервісів, usr_ для користувачів.sp_ для власних процедур!SQL Server спочатку шукає процедури з префіксом sp_ у системній БД master, що призводить до зниження продуктивності. Використовуйте інші префікси, наприклад usp_ (user stored procedure).ORIGINAL_LOGIN()У тригерах та при використанні EXECUTE AS корисно отримувати оригінальний логін:SELECT
SUSER_NAME() AS CurrentContext,
ORIGINAL_LOGIN() AS OriginalLogin;
Висновки
Безпека баз даних — це багаторівнева система, яка включає:
- Автентифікацію (хто ви?) — Logins на рівні сервера
- Авторизацію (що ви можете робити?) — Users, Roles, Permissions на рівні БД
- Аудит (що ви зробили?) — Triggers, SQL Server Audit
Ключові висновки
Подальше вивчення