Triggers Stored Procedures

Безпека баз даних

Автентифікація, авторизація та керування правами доступу в SQL Server

Безпека баз даних

Захист даних у сучасних інформаційних системах є критично важливим аспектом. SQL Server надає потужні механізми для контролю доступу та захисту інформації на кількох рівнях.

Навіщо потрібна безпека БД?

Уявіть, що ваша база даних — це банківське сховище. Ви не можете дозволити будь-кому зайти всередину та робити що завгодно з вашими активами.

Конфіденційність

Цілісність

Аудит

Compliance

Системні таблиці та представлення

У SQL Server 2000 використовувалася система системних таблиць (наприклад, 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;                  -- Процедури

Основні системні представлення

Loading diagram...
graph TD
    A[sys.objects] -->|Тип='U'| B[Таблиці]
    A -->|Тип='P'| C[Процедури]
    A -->|Тип='TR'| D[Trigger]
    A -->|Тип='V'| E[View]
    A -->|Тип='FN'| F[Scalar Function]
    A -->|Тип='IF'/'TF'| G[Table-Valued Function]
    
    style A fill:#4F46E5,color:#fff
    style B fill:#059669,color:#fff
    style C fill:#059669,color:#fff
    style D fill:#059669,color:#fff
    style E fill:#059669,color:#fff
    style F fill:#059669,color:#fff
    style G fill:#059669,color:#fff

Корисні представлення для роботи з метаданими

-- Інформація про об'єкти БД
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;
Windows Authentication є найбільш захищеним варіантом для корпоративного середовища, оскільки використовує надійну систему автентифікації операційної системи.

Mixed Mode (SQL Server + Windows)

Коли використовувати:

  • Додатки, які працюють на різних платформах (Linux, macOS)
  • Веб-додатки без інтеграції з AD
  • Тестові середовища
-- SQL Server логін
CREATE LOGIN AppUser WITH PASSWORD = 'StrongP@ssw0rd!';
При використанні SQL Server Authentication:
  • Використовуйте складні паролі
  • Застосовуйте політику складності паролів
  • Регулярно змінюйте паролі
  • Шифруйте з'єднання (SSL/TLS)

::

Loading diagram...
sequenceDiagram
    participant Client as Клієнт
    participant Server as SQL Server
    participant AD as Active Directory

    rect rgb(200, 230, 255)
        Note over Client,AD: Windows Authentication
        Client->>AD: 1. Автентифікація користувача
        AD-->>Client: 2. Token автентифікації
        Client->>Server: 3. Підключення з Windows Token
        Server->>AD: 4. Перевірка токена
        AD-->>Server: 5. Підтвердження
        Server-->>Client: 6. Доступ надано
    end

    rect rgb(255, 230, 200)
        Note over Client,Server: SQL Server Authentication
        Client->>Server: 1. LOGIN + PASSWORD
        Server->>Server: 2. Перевірка облікових даних
        Server-->>Client: 3. Доступ надано/відхилено
    end

Двухрівнева модель безпеки

SQL Server використовує дворівневу модель безпеки:

Loading diagram...
graph LR
    A[Користувач підключається] --> B{Автентифікація<br/>Server Level}
    B -->|Успішно| C[LOGIN створений]
    C --> D{Авторизація<br/>Database Level}
    D -->|Успішно| E[USER створений]
    E --> F[Доступ до БД]
    
    B -->|Помилка| G[Відмова у доступі]
    D -->|Помилка| H[Немає доступу до БД]
    
    style B fill:#4F46E5,color:#fff
    style D fill:#4F46E5,color:#fff
    style F fill:#059669,color:#fff
    style G fill:#DC2626,color:#fff
    style H fill:#DC2626,color:#fff
  1. Server Level (LOGIN) — автентифікація на рівні сервера
  2. Database Level (USER) — авторизація на рівні бази даних
LOGIN — це облікові дані для підключення до SQL Server.
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 — політика складності паролів Windows
  • DEFAULT_DATABASE — БД за замовчуванням

:: ::

Модифікація логінів

-- Зміна пароля
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;
Перед видаленням логіна переконайтеся, що:
  1. Він не є власником баз даних або схем
  2. Немає активних підключень
  3. Видалені всі відповідні користувачі в базах даних

Перегляд логінів

-- Список всіх логінів
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;
DEFAULT_SCHEMA визначає схему, яка буде використовуватися за замовчуванням при створенні об'єктів цим користувачем.

Модифікація користувачів

-- Зміна схеми за замовчуванням
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)

Ролі — це механізм групування користувачів для спрощення управління правами доступу.

Loading diagram...
graph TD
    A[Ролі SQL Server] --> B[Server Roles]
    A --> C[Database Roles]
    
    B --> B1[Fixed Server Roles]
    B --> B2[User-Defined Server Roles]
    
    C --> C1[Fixed Database Roles]
    C --> C2[User-Defined Database Roles]
    C --> C3[Application Roles]
    
    style A fill:#4F46E5,color:#fff
    style B fill:#059669,color:#fff
    style C fill:#059669,color:#fff

Фіксовані ролі сервера (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;
Best Practice: Для додатків зазвичай створюють користувача з роллю 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 — це спеціальний тип ролі, яка активується паролем і не має прямих членів.

Loading diagram...
sequenceDiagram
    participant App as Додаток
    participant DB as SQL Server
    participant Role as Application Role

    App->>DB: 1. Підключитися як AppUser
    DB-->>App: 2. З'єднання встановлено
    App->>DB: 3. EXEC sp_setapprole 'AppRole', 'password'
    DB->>Role: 4. Активувати Application Role
    Role-->>DB: 5. Застосувати права ролі
    DB-->>App: 6. Контекст змінено на AppRole
    Note over App,DB: Тепер всі запити виконуються<br/>під правами AppRole
    App->>DB: 7. SELECT * FROM SecretData
    DB-->>App: 8. Доступ дозволено (через роль)

Створення та використання

-- Створення 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;
Коли використовувати Application Roles:
  • Двох-рівневі додатки, де всі користувачі підключаються через єдиний акаунт
  • Потрібен додатковий рівень безпеки для певних операцій
  • Розмежування прав доступу на рівні додатка, а не користувача

Модифікація та видалення

-- Зміна пароля
ALTER APPLICATION ROLE AppRole
WITH PASSWORD = 'NewP@ssw0rd!';

-- Зміна схеми за замовчуванням
ALTER APPLICATION ROLE AppRole
WITH DEFAULT_SCHEMA = Sales;

-- Видалення
DROP APPLICATION ROLE AppRole;
Після активації Application Role:
  • Не можна змінювати контекст БД (USE)
  • Втрачається інформація про оригінального користувача (але можна зберегти через cookie)
  • Всі операції виконуються під контекстом ролі

Права доступу (Permissions)

SQL Server має гранульовану систему прав доступу на рівні об'єктів.

Ієрархія прав

Loading diagram...
graph TD
    A[CONTROL SERVER] --> B[CONTROL DATABASE]
    B --> C[CONTROL SCHEMA]
    C --> D[CONTROL OBJECT]
    
    D --> E[SELECT]
    D --> F[INSERT]
    D --> G[UPDATE]
    D --> H[DELETE]
    D --> I[EXECUTE]
    D --> J[REFERENCES]
    
    style A fill:#DC2626,color:#fff
    style B fill:#EA580C,color:#fff
    style C fill:#CA8A04,color:#fff
    style D fill:#059669,color:#fff

Надання прав (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 для безпеки

  1. Використовуйте Windows Authentication

  1. Принцип найменших привілеїв

  1. Використовуйте ролі

  1. Аудит доступу

  1. Схеми для розділення

  1. Шифрування з'єднань

Перевірка складності паролів

-- Увімкнути політику паролів
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;

Висновки

Безпека баз даних — це багаторівнева система, яка включає:

  1. Автентифікацію (хто ви?) — Logins на рівні сервера
  2. Авторизацію (що ви можете робити?) — Users, Roles, Permissions на рівні БД
  3. Аудит (що ви зробили?) — Triggers, SQL Server Audit

Ключові висновки

Подальше вивчення


Додаткові ресурси

Copyright © 2026