Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek popisuje postupy zabezpečení pro aplikace Django, které se připojují k SQL Server prostřednictvím back-endumssql-django. Tyto postupy doplňují integrované funkce zabezpečení Django a model zabezpečení SQL Server.
Použití ověřování Microsoft Entra místo hesel
Ověřování Microsoft Entra odstraňuje potřebu ukládat hesla k databázi. Použijte ho pro všechna připojení Azure SQL.
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "Authentication=ActiveDirectoryMsi",
},
},
}
Úplný seznam metod ověřování, aktuálních upozornění a TOKEN příkladů pro DefaultAzureCredential a ManagedIdentityCredential najdete v článku ověřování Microsoft Entra pomocí mssql-django.
Zabezpečená správa přihlašovacích údajů
Pokud potřebujete ověřování SQL, zachovejte přihlašovací údaje mimo zdrojový kód.
Proměnné prostředí
import os
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": os.environ["DB_NAME"],
"USER": os.environ["DB_USER"],
"PASSWORD": os.environ["DB_PASSWORD"],
"HOST": os.environ["DB_HOST"],
"PORT": os.environ.get("DB_PORT", "1433"),
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
},
},
}
Azure Key Vault
Pro produkční nasazení načtěte tajné kódy z Azure Key Vault:
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
credential = DefaultAzureCredential()
client = SecretClient(vault_url="https://<your-vault>.vault.azure.net/", credential=credential)
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": client.get_secret("db-name").value,
"USER": client.get_secret("db-user").value,
"PASSWORD": client.get_secret("db-password").value,
"HOST": client.get_secret("db-host").value,
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
},
},
}
Caution
Nikdy nesvěřujte přihlašovací údaje do správy zdrojového kódu. Přidat soubory .env do .gitignore. Použijte git-secrets nebo pre-commit hooky ke kontrole commitů, které omylem obsahují přihlašovací údaje.
Vynucení šifrování TLS
SQL Server připojení by měla být vždy šifrovaná. Ovladač ODBC ve výchozím nastavení šifruje připojení počínaje verzí ODBC Driver 18:
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"HOST": "<your-server>.database.windows.net",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
# Encryption is on by default with Driver 18
},
},
}
Pokud používáte ovladač ODBC 17, povolte šifrování explicitně:
"extra_params": "Encrypt=yes"
Caution
Používejte TrustServerCertificate=yes pouze pro místní vývoj s certifikáty podepsanými svým držitelem. Nepoužívejte ho v produkčním prostředí. Zakáže ověřování řetězce certifikátů a zvyšuje riziko útoku typu man-in-the-middle. Nainstalujte na server důvěryhodný certifikát a připojte se pomocí TrustServerCertificate=no.
Použití principu nejnižšího oprávnění
Vytvořte vyhrazená SQL Server přihlášení pouze s oprávněními, která vaše aplikace potřebuje:
-- Create a login and user for the application
CREATE LOGIN [django_app]
WITH PASSWORD = '<strong-password>';
USE [<your-database>];
CREATE USER [django_app] FOR LOGIN [django_app];
-- Grant minimum required permissions
-- Read and write data
ALTER ROLE db_datareader ADD MEMBER [django_app];
ALTER ROLE db_datawriter ADD MEMBER [django_app];
-- Allow Django to create and alter tables during migrations
GRANT ALTER ON SCHEMA::dbo TO [django_app];
GRANT CREATE TABLE TO [django_app];
GRANT REFERENCES ON SCHEMA::dbo TO [django_app];
U aplikací, u kterých se v produkčním prostředí nespouštějí migrace, vynechte oprávnění ALTER a CREATE TABLE:
-- Production application user (read/write only)
ALTER ROLE db_datareader ADD MEMBER [django_app];
ALTER ROLE db_datawriter ADD MEMBER [django_app];
GRANT EXECUTE ON SCHEMA::dbo TO [django_app]; -- If using stored procedures
Spusťte migrace v rámci samostatného kroku nasazení s vyššími oprávněními:
-- Migration user (used only during deployments)
ALTER ROLE db_ddladmin ADD MEMBER [django_migrations];
Volba správné role
SQL Server pevné databázové role jsou seřazené od nejméně po nejvíce privilegované. Vyberte nejméně privilegovanou roli, která pokrývá vaši úlohu, a v případě potřeby pouze eskalujte:
| Úloha | Grants | Kdy ho použít |
|---|---|---|
| db_datareader |
SELECT ve všech uživatelských tabulkách a zobrazeních |
Uživatelé pro vykazování s oprávněním jen pro čtení |
| db_datawriter |
INSERT, UPDATE, DELETE ve všech uživatelských tabulkách |
Uživatel aplikace runtime (kombinování s db_datareader) |
| db_ddladmin | Vytváření, změny a odstraňování objektů schématu | Pouze pro uživatele migrace nebo nasazení |
| db_owner | Všechna oprávnění k databázi, včetně zabezpečení | Nepoužívejte pro aplikace; vyhraďte pro správce databází |
Pro jemně odstupňované řízení, než umožňují pevné role, vytvořte vlastní roli databáze a GRANT pouze konkrétní oprávnění ke konkrétnímu schématu, které vaše aplikace používá. Uložení všech objektů aplikace do vyhrazeného schématu (například app) umožňuje omezit rozsah oprávnění pomocí GRANT ... ON SCHEMA::app namísto spoléhání na celo-databázové role db_datareader a db_datawriter.
Note
Nepoužívejte sa účet ani db_owner pevnou roli databáze pro připojení aplikací. Pokud dojde k ohrožení zabezpečení aplikace, útočník získá úplnou kontrolu nad databází.
Prevence injektáže SQL
Django ORM parametrizuje všechny dotazy automaticky. Injektáž SQL představuje riziko pouze v případech, kdy používáte nezpracovaný SQL:
Bezpečné: Dotazy ORM
# Django parameterizes these automatically
users = User.objects.filter(email=user_input)
products = Product.objects.filter(price__lte=max_price)
Bezpečné: Parametrizované nezpracované SQL
from django.db import connection
with connection.cursor() as cursor:
cursor.execute(
"SELECT * FROM products WHERE category = %s AND price < %s",
[category, max_price],
)
Nebezpečné: Formátování řetězců v nezpracovaných SQL
# NEVER do this - vulnerable to SQL injection
cursor.execute(f"SELECT * FROM products WHERE category = '{category}'")
cursor.execute("SELECT * FROM products WHERE category = '%s'" % category)
Extra a RawSQL
Django přijímá extra()RawSQL() nezpracované fragmenty SQL. Vždy používat parametry:
# Safe - parameterized
Product.objects.extra(where=["category = %s"], params=[category])
from django.db.models.expressions import RawSQL
Product.objects.annotate(
discount=RawSQL("price * %s", [discount_rate])
)
Important
Nikdy nepoužívejte extra() ani RawSQL() s formátováním řetězců. Tyto obcházejí automatickou parametrizaci ORM.
Konfigurace middlewaru zabezpečení Django
Povolte vestavěný bezpečnostní middleware frameworku Django pro ochranu webové vrstvy. I když nejsou specifické pro databázi, chrání aplikaci, která se připojuje k vaší databázi:
# settings.py
# HTTPS enforcement
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000 # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# Cookie security
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
# Content security
SECURE_CONTENT_TYPE_NOSNIFF = True
Auditovat přístup k databázi
Povolte auditování SQL Server ke sledování databázových operací z aplikace Django:
-- Create a server audit (Azure SQL uses Azure SQL Auditing instead)
CREATE SERVER AUDIT [DjangoAudit]
TO FILE (FILEPATH = 'C:\Audits\')
WITH (ON_FAILURE = CONTINUE);
ALTER SERVER AUDIT [DjangoAudit] WITH (STATE = ON);
-- Create a database audit specification
USE [<your-database>];
CREATE DATABASE AUDIT SPECIFICATION [DjangoDbAudit]
FOR SERVER AUDIT [DjangoAudit]
ADD (SELECT, INSERT, UPDATE, DELETE ON SCHEMA::dbo BY [django_app])
WITH (STATE = ON);
U Azure SQL Database povolte auditování prostřednictvím portálu Azure nebo Azure CLI:
az sql db audit-policy update --resource-group <rg> --server <server> \
--name <database> --state Enabled \
--storage-account <storage-account>
Zabezpečení citlivých sloupců pomocí funkce Always Encrypted
Pro šifrování citlivých dat na úrovni sloupců, jako jsou rodná čísla, čísla platebních karet nebo mzdové údaje, použijte funkci Always Encrypted. Ovladač ODBC zpracovává šifrování a dešifrování transparentně:
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "ColumnEncryption=Enabled",
},
},
}
Podrobné nastavení včetně správy klíčů s Azure Key Vault najdete v tématu Always Encrypted s mssql-django.
Kontrolní seznam zabezpečení
| Kategorie | Practice | Priorita |
|---|---|---|
| Ověřování | Pro Azure SQL použijte ověřování Microsoft Entra. | Vysoko |
| Credentials | Ukládejte tajné kódy do proměnných prostředí nebo Azure Key Vault. | Vysoko |
| Encryption | Použijte ODBC Driver 18 (šifrování je ve výchozím nastavení zapnuté) nebo Encrypt=yes. |
Vysoko |
| Injekce | Použijte dotazy ORM nebo parametrizované nezpracované SQL. Nikdy neformátujte SQL jako řetězec. | Vysoko |
| Nejnižší oprávnění | Vytvořte vyhrazená přihlášení s minimálními požadovanými oprávněními. | Vysoko |
| protokol TLS | Nepoužívejte TrustServerCertificate=yes v produkčním prostředí. |
Vysoko |
| Django | Povolte SECURE_SSL_REDIRECT, zabezpečené soubory cookie, HSTS. |
Středně |
| Auditing | Povolte auditování SQL Server nebo auditování Azure SQL. | Středně |
| Šifrování sloupců | Používejte funkci Always Encrypted pro vysoce citlivé sloupce. | Nízká úroveň |
| Připojení | Nastavte CONN_MAX_AGE a CONN_HEALTH_CHECKS, abyste zabránili neaktivním připojením. |
Nízká úroveň |