Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit artikel worden beveiligingsprocedures beschreven voor Django-toepassingen die verbinding maken met SQL Server via de mssql-django back-end. Deze procedures vormen een aanvulling op de ingebouwde beveiligingsfuncties van Django en het beveiligingsmodel van SQL Server.
Gebruik Microsoft Entra verificatie in plaats van wachtwoorden
Microsoft Entra verificatie elimineert opgeslagen databasewachtwoorden. Gebruik deze voor alle Azure SQL verbindingen.
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",
},
},
}
Zie Microsoft Entra-authenticatie met mssql-django voor de volledige lijst met authenticatiemethoden, huidige aandachtspunten en TOKEN voorbeelden met DefaultAzureCredential en ManagedIdentityCredential.
Referenties veilig beheren
Wanneer u SQL-verificatie nodig hebt, moet u referenties buiten de broncode houden.
Omgevingsvariabelen
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
Voor productie-implementaties haalt u geheimen op uit 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",
},
},
}
Waarschuwing
Voer nooit referenties door naar broncodebeheer. Voeg .env bestanden toe aan .gitignore. Gebruik git-secrets of pre-commit-hooks om te scannen op commits waarin per ongeluk inloggegevens zijn opgenomen.
TLS-versleuteling afdwingen
SQL Server verbindingen moeten altijd worden versleuteld. Het ODBC-stuurprogramma versleutelt standaard verbindingen vanaf ODBC-stuurprogramma 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
},
},
}
Als u ODBC-stuurprogramma 17 gebruikt, schakelt u versleuteling expliciet in:
"extra_params": "Encrypt=yes"
Waarschuwing
Alleen gebruiken TrustServerCertificate=yes voor lokale ontwikkeling met zelfondertekende certificaten. Gebruik het niet in productie. Hierdoor wordt de validatie van de certificaatketen uitgeschakeld en neemt het man-in-the-middle-risico toe. Installeer een vertrouwd certificaat op de server en maak verbinding met TrustServerCertificate=no.
Het principe van minimale bevoegdheden toepassen
Maak toegewezen SQL Server aanmeldingen met alleen de machtigingen die uw toepassing nodig heeft:
-- 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];
Voor toepassingen die geen migraties uitvoeren in productie, laat u de ALTER en CREATE TABLE machtigingen weg:
-- 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
Voer migraties uit vanuit een afzonderlijke, meer bevoegde implementatiestap:
-- Migration user (used only during deployments)
ALTER ROLE db_ddladmin ADD MEMBER [django_migrations];
De juiste rol kiezen
SQL Server vaste databaserollen worden geordend van minst naar meest bevoegd. Kies de rol met minimale bevoegdheden die betrekking heeft op uw workload en escaleer alleen wanneer dat nodig is:
| Role | Grants | Wanneer gebruiken |
|---|---|---|
| db_datareader |
SELECT op alle gebruikerstabellen en views |
Gebruikers met alleen-leestoegang tot rapportages |
| db_datawriter |
INSERT, UPDATE, DELETE op alle gebruikerstabellen |
Runtime-toepassingsgebruiker (combineren met db_datareader) |
| db_ddladmin | Schemaobjecten maken, wijzigen en verwijderen | Alleen migratie- of implementatiegebruiker |
| db_owner | Alle databasemachtigingen, inclusief beveiliging | Vermijd voor toepassingen; reserveren voor DBA's |
Voor fijnmazigere controle dan met de vaste rollen mogelijk is, maakt u een aangepaste databaserol aan en GRANT alleen de specifieke machtigingen op het specifieke schema dat uw app gebruikt. Door alle toepassingsobjecten in een toegewezen schema onder te brengen (bijvoorbeeld app), kunt u machtigingen afbakenen met GRANT ... ON SCHEMA::app in plaats van te vertrouwen op de databrede rollen db_datareader en db_datawriter.
Note
Gebruik niet het account sa of de vaste databaserol db_owner voor applicatieverbindingen. Als de toepassing is aangetast, krijgt een aanvaller volledige databasebeheer.
SQL-injectie voorkomen
Django's ORM parameteriseert automatisch alle query's. SQL-injectie is alleen een risico wanneer u onbewerkte SQL gebruikt:
Veilig: query’s van ORM
# Django parameterizes these automatically
users = User.objects.filter(email=user_input)
products = Product.objects.filter(price__lte=max_price)
Veilig: Geparameteriseerde onbewerkte 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],
)
Onveilig: Tekenreeksopmaak in onbewerkte 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 en RawSQL
Django's extra() en RawSQL() accepteren onbewerkte SQL-fragmenten. Altijd parameters gebruiken:
# 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
Gebruik nooit extra() of RawSQL() met tekenreeksopmaak. Hiermee wordt de automatische parameterisatie van de ORM overgeslagen.
Django-beveiligings-middleware configureren
Schakel de ingebouwde beveiligings-middleware van Django in om de weblaag te beveiligen. Hoewel deze niet databasespecifiek zijn, beveiligen ze de toepassing die verbinding maakt met uw database:
# 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
Databasetoegang controleren
Schakel SQL Server controle in om databasebewerkingen bij te houden vanuit uw Django-toepassing:
-- 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);
Schakel voor Azure SQL Database controle in via de Azure-portal of Azure CLI:
az sql db audit-policy update --resource-group <rg> --server <server> \
--name <database> --state Enabled \
--storage-account <storage-account>
Gevoelige kolommen beveiligen met Always Encrypted
Gebruik Always Encrypted voor versleuteling op kolomniveau van gevoelige gegevens, zoals SSN's, creditcardnummers of salarisgegevens. Het ODBC-stuurprogramma verwerkt versleuteling en ontsleuteling transparant:
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "ColumnEncryption=Enabled",
},
},
}
Zie Always Encrypted met mssql-django voor gedetailleerde instellingen, waaronder sleutelbeheer met Azure Key Vault.
Controlelijst voor beveiliging
| Categorie | Practice | Priority |
|---|---|---|
| Authentication | Gebruik Microsoft Entra verificatie voor Azure SQL. | Hoog |
| Credentials | Geheimen opslaan in omgevingsvariabelen of Azure Key Vault. | Hoog |
| Encryption | Gebruik ODBC-stuurprogramma 18 (standaard versleuteling ingeschakeld) of Encrypt=yes. |
Hoog |
| Injectie | Gebruik ORM-query's of geparameteriseerde onbewerkte SQL. Formatteer SQL nooit met tekenreeksen. | Hoog |
| Minimale bevoegdheid | Maak toegewezen aanmeldingen met minimale vereiste machtigingen. | Hoog |
| TLS | Gebruik niet TrustServerCertificate=yes in productie. |
Hoog |
| Django | Schakel SECURE_SSL_REDIRECT, beveiligde cookies en HSTS in. |
Gemiddeld |
| Auditing | Schakel SQL Server controle of Azure SQL controle in. | Gemiddeld |
| Kolomversleuteling | Gebruik Always Encrypted voor zeer gevoelige kolommen. | Laag |
| Verbinding | Stel CONN_MAX_AGE en CONN_HEALTH_CHECKS in om verouderde verbindingen te voorkomen. |
Laag |