Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makale, arka uç üzerinden SQL Server bağlanan Django uygulamalarına yönelik mssql-django güvenlik uygulamalarını kapsar. Bu uygulamalar Django'nun yerleşik güvenlik özelliklerini ve SQL Server güvenlik modelini tamamlar.
Parolalar yerine Microsoft Entra kimlik doğrulaması kullanma
Microsoft Entra kimlik doğrulaması depolanan veritabanı parolalarını ortadan kaldırır. Tüm Azure SQL bağlantıları için kullanın.
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",
},
},
}
Kimlik doğrulama yöntemlerinin tam listesi, mevcut sınırlamalar ve DefaultAzureCredential ile ManagedIdentityCredential içeren TOKEN örnekler için bkz. mssql-django ile Microsoft Entra kimlik doğrulaması.
Kimlik bilgilerini güvenli bir şekilde yönetme
SQL kimlik doğrulamasına ihtiyacınız olduğunda kimlik bilgilerini kaynak kodun dışında tutun.
Ortam değişkenleri
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
Üretim dağıtımları için gizli anahtarları Azure Key Vault'tan alın:
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
Kimlik bilgilerini hiçbir zaman kaynak denetimine işlemeyin.
.env dosyalarını .gitignore öğesine ekleyin. Kimlik bilgilerinin yanlışlıkla commit edilmesini taramak için git-secrets veya pre-commit kancalarını kullanın.
TLS şifrelemesini zorunlu kıl
SQL Server bağlantıları her zaman şifrelenmelidir. ODBC sürücüsü, ODBC Sürücüsü 18'den başlayarak bağlantıları varsayılan olarak şifreler:
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
},
},
}
ODBC Sürücüsü 17 kullanıyorsanız şifrelemeyi açıkça etkinleştirin:
"extra_params": "Encrypt=yes"
Caution
TrustServerCertificate=yes yalnızca kendinden imzalı sertifikalarla yerel geliştirme için kullanın. Üretimde kullanmayın. Sertifika zinciri doğrulamasını devre dışı bırakır ve ortadaki saldırgan riski artırır. Sunucuya güvenilir bir sertifika yükleyin ve ile TrustServerCertificate=nobağlanın.
En az ayrıcalık ilkesini uygulama
Yalnızca uygulamanızın ihtiyaç duyduğu izinlerle ayrılmış SQL Server oturum açma bilgileri oluşturun:
-- 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];
Üretimde geçişleri çalıştırmayan uygulamalar için ALTER ve CREATE TABLE izinlerini atlayın:
-- 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
Geçişleri ayrı, daha ayrıcalıklı bir dağıtım adımından çalıştırın:
-- Migration user (used only during deployments)
ALTER ROLE db_ddladmin ADD MEMBER [django_migrations];
Doğru rolü seçme
SQL Server sabit veritabanı rolleri en azdan en ayrıcalıklıya sıralanır. İş yükünüzü kapsayan en az ayrıcalıklı rolü seçin ve yalnızca gerektiğinde yükseltin:
| Rolü | Grants | Ne zaman kullanılır? |
|---|---|---|
| db_datareader |
SELECT tüm kullanıcı tablolarında ve görünümlerinde |
Salt okunur raporlama kullanıcıları |
| db_datawriter |
INSERT, UPDATE, DELETE tüm kullanıcı tablolarında |
Çalışma zamanı uygulama kullanıcısı (db_datareader ile birleştirilmiş) |
| db_ddladmin | Şema nesneleri oluşturma, değiştirme ve bırakma | Yalnızca geçiş veya dağıtım kullanıcısı |
| db_owner | Güvenlik de dahil olmak üzere tüm veritabanı izinleri | Uygulamalar için kullanmaktan kaçının; veritabanı yöneticilerine ayırın |
Sabit rollerin izin verdiğinden daha ayrıntılı denetim için özel bir veritabanı rolü ve GRANT yalnızca uygulamanızın kullandığı belirli şemada belirli izinleri oluşturun. Tüm uygulama nesnelerini özel bir şemada tutmak (örneğin, app), veritabanı genelindeki db_datareader ve db_datawriter rollerine güvenmek yerine izinleri GRANT ... ON SCHEMA::app ile sınırlandırmanıza olanak tanır.
Note
Uygulama bağlantıları için sa hesabını veya db_owner sabit veritabanı rolünü kullanmayın. Uygulamanın güvenliği aşılırsa, saldırgan tam veritabanı denetimine sahip olur.
SQL enjeksiyonunu önleme
Django'nun ORM'i tüm sorguları otomatik olarak parametreleştirir. SQL ekleme yalnızca ham SQL kullandığınızda bir risktir:
Güvenli: ORM sorguları
# Django parameterizes these automatically
users = User.objects.filter(email=user_input)
products = Product.objects.filter(price__lte=max_price)
Güvenli: Parametreli ham 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],
)
Güvenli değil: Ham SQL'de dize biçimlendirmesi
# 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 ve RawSQL
Django'nun extra() ve RawSQL() ham SQL parçacıklarını kabul eder. Her zaman parametreleri kullanın:
# 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
Dize biçimlendirmede asla extra() ya da RawSQL() kullanmayın. Bunlar ORM'nin otomatik parametreleştirmesini atlar.
Django güvenlik ara yazılımını yapılandırma
Web katmanını korumak için Django'nun yerleşik güvenlik ara yazılımını etkinleştirin. Bunlar veritabanına özgü olmasa da, veritabanınıza bağlanan uygulamayı korur:
# 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
Veritabanı erişimini denetleme
Django uygulamanızdan veritabanı işlemlerini izlemek için SQL Server denetimini etkinleştirin:
-- 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);
Azure SQL Veritabanı için Azure portalı veya Azure CLI aracılığıyla denetimi etkinleştirin:
az sql db audit-policy update --resource-group <rg> --server <server> \
--name <database> --state Enabled \
--storage-account <storage-account>
Always Encrypted ile hassas sütunların güvenliğini sağlama
SSN'ler, kredi kartı numaraları veya maaş verileri gibi hassas verilerin sütun düzeyinde şifrelemesi için Always Encrypted kullanın. ODBC sürücüsü şifreleme ve şifre çözme işlemlerini saydam bir şekilde işler:
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "ColumnEncryption=Enabled",
},
},
}
Azure Key Vault ile anahtar yönetimi dahil ayrıntılı kurulum için bkz. mssql-django ile Always Encrypted.
Güvenlik denetim listesi
| Kategori | Practice | Priority |
|---|---|---|
| Authentication | Azure SQL için Microsoft Entra kimlik doğrulamasını kullanın. | Yüksek |
| Credentials | Gizli anahtarları ortam değişkenlerinde veya Azure Key Vault'ta depolayın. | Yüksek |
| Encryption | ODBC Sürücüsü 18'i (varsayılan olarak şifreleme açık) veya Encrypt=yeskullanın. |
Yüksek |
| Enjeksiyon | ORM sorgularını veya parametreli ham SQL'i kullanın. SQL'i asla dize biçimlendirmeyle oluşturmayın. | Yüksek |
| En az ayrıcalık | Gerekli en düşük izinlere sahip ayrılmış oturum açma bilgileri oluşturun. | Yüksek |
| TLS | Üretimde kullanmayın TrustServerCertificate=yes . |
Yüksek |
| Django |
SECURE_SSL_REDIRECT güvenli tanımlama bilgilerini ve HSTS'yi etkinleştirin. |
Orta |
| Auditing | SQL Server denetimini veya Azure SQL Denetimi’ni etkinleştirin. | Orta |
| Sütun şifreleme | Çok hassas sütunlar için Always Encrypted kullanın. | Low |
| Bağlantı | Eski bağlantıları önlemek için CONN_MAX_AGE ve CONN_HEALTH_CHECKS ayarlayın. |
Low |