Considerazioni sulla sicurezza (Entity Framework)
In questo argomento vengono illustrate alcune considerazioni sulla sicurezza che riguardano in modo particolare lo sviluppo, la distribuzione e l'esecuzione di applicazioni Entity Framework. È consigliabile inoltre seguire le raccomandazioni relative alla creazione di applicazioni .NET Framework protette. Per ulteriori informazioni, vedere Cenni preliminari sulla sicurezza (ADO.NET).
Considerazioni generali sulla sicurezza
Le considerazioni sulla sicurezza sono valide per tutte le applicazioni che utilizzano Entity Framework.
Utilizzare solo provider delle origini dati attendibili.
Per comunicare con l'origine dati, un provider deve eseguire le operazioni seguenti:
Ricevere la stringa di connessione da Entity Framework.
Convertire la struttura comandi nel linguaggio di query nativo dell'origine dati.
Assemblare e restituire i set di risultati.
Durante l'operazione di accesso, le informazioni basate sulla password dell'utente vengono passate al server tramite le librerie di rete dell'origine dati sottostante. Un provider malintenzionato può rubare le credenziali utente, generare query dannose o manomettere il set di risultati.
Crittografare la connessione per proteggere i dati riservati.
Entity Framework non gestisce direttamente la crittografia dei dati. Se gli utenti accedono ai dati su una rete pubblica, l'applicazione deve stabilire una connessione crittografata all'origine dati per aumentare la sicurezza. Per ulteriori informazioni, vedere la documentazione relativa alla sicurezza dell'origine dati. Per un'origine dati SQL Server, vedere Crittografia delle connessioni a SQL Server.
Proteggere la stringa di connessione.
La protezione dell'accesso all'origine dati è uno dei principali obiettivi da raggiungere quando si imposta la protezione di un'applicazione. Una stringa di connessione presenta una potenziale vulnerabilità se non è protetta o se viene costruita in modo improprio. Se le informazioni di connessione vengono archiviate in testo normale o mantenute in memoria, si rischia di compromettere l'intero sistema. Di seguito sono riportati i metodi di protezione delle stringhe di connessione consigliati.
Utilizzare l'autenticazione di Windows con un'origine dati SQL Server.
Quando si utilizza l'autenticazione di Windows per connettersi a un'origine dati SQL Server, la stringa di connessione non contiene informazioni relative all'accesso e alla password.
Crittografare le sezioni dei file di configurazione tramite la configurazione protetta.
In ASP.NET è disponibile una nuova funzionalità, la configurazione protetta, che consente di crittografare le informazioni riservate in un file di configurazione. Sebbene sia stata progettata principalmente per ASP.NET, può essere utilizzata anche per crittografare sezioni dei file di configurazione delle applicazioni Windows. Per una descrizione dettagliata della nuova funzionalità di configurazione protetta, vedere Crittografia delle informazioni di configurazione utilizzando la configurazione protetta.
Archiviare le stringhe di connessione in file di configurazione protetti.
Le stringhe di connessione non devono mai essere incorporate nel codice sorgente. La possibilità di archiviarle nei file di configurazione elimina la necessità di incorporarle nel codice. Per impostazione predefinita, la procedura guidata Entity Data Model archivia le stringhe di connessione nel file di configurazione dell'applicazione. Per impedire accessi non autorizzati, è necessario proteggere tale file.
Utilizzare i generatori di stringhe di connessione durante la creazione dinamica delle connessioni.
Se è necessario costruire stringhe di connessione in fase di esecuzione, utilizzare la classe EntityConnectionStringBuilder. Questa classe del generatore di stringhe consente di impedire attacchi di tipo injection delle stringhe di connessione attraverso la convalida e l'esecuzione dell'escape delle informazioni di input non valide. Per ulteriori informazioni, vedere Procedura: compilare una stringa di connessione EntityConnection (Entity Framework). Utilizzare inoltre la classe del generatore di stringhe adatta per costruire la stringa di connessione dell'origine dati che fa parte della stringa di connessione di Entity Data Model (EDM). Per informazioni sui generatori di stringhe di connessione per i provider ADO.NET, vedere Generatori di stringhe di connessione (ADO.NET).
Per ulteriori informazioni, vedere Protezione delle informazioni di connessione (ADO.NET).
Non esporre un oggetto EntityConnection a utenti non attendibili.
Un oggetto EntityConnection espone la stringa di connessione della connessione sottostante. Un utente che dispone dell'accesso a un oggetto EntityConnection può modificare anche l'oggetto ConnectionState della connessione sottostante. La classe EntityConnection non è thread-safe.
Non passare connessioni al di fuori del contesto di sicurezza.
Dopo aver stabilito una connessione, non è possibile passarla al di fuori del contesto di sicurezza. Un thread con l'autorizzazione ad aprire una connessione, ad esempio, non deve archiviare la connessione in un percorso globale. Da questo percorso, infatti, potrebbe essere utilizzata da uno script dannoso senza un'autorizzazione esplicitamente concessa.
Tenere presente che le informazioni relative all'accesso e alla password possono essere visibili in un'immagine della memoria.
Quando nella stringa di connessione vengono fornite informazioni relative all'accesso e alla password della stringa di connessione, tali informazioni vengono conservate in memoria fino a quando le risorse non sono richieste dal processo di Garbage Collection. Diventa quindi impossibile determinare quando una stringa della password non è più in memoria. Se un'applicazione si arresta in modo anomalo, è possibile che un file di immagine della memoria contenga informazioni sulla sicurezza riservate che possono quindi diventare visibili all'utente che esegue l'applicazione e a qualsiasi utente con accesso amministrativo al computer. Utilizzare l'autenticazione di Windows per le connessioni a Microsoft SQL Server.
Concedere agli utenti solo le autorizzazioni necessarie nell'origine dati.
Un amministratore dell'origine dati deve concedere solo le autorizzazioni necessarie agli utenti. Sebbene Entity SQL non supporti istruzioni DML che modificano i dati, ad esempio INSERT, UPDATE o DELETE, gli utenti possono comunque accedere alla connessione all'origine dati. Un utente malintenzionato potrebbe utilizzare questa connessione per eseguire istruzioni DML nel linguaggio nativo dell'origine dati.
Eseguire le applicazioni con le autorizzazioni minime.
Quando si consente l'esecuzione di un'applicazione gestita con autorizzazione di attendibilità totale, .NET Framework non limita l'accesso dell'applicazione al computer. Questo potrebbe rendere vulnerabile l'applicazione e compromettere l'intero sistema. Per utilizzare la sicurezza dall'accesso di codice e gli altri meccanismi di sicurezza di .NET Framework, è necessario eseguire le applicazioni tramite autorizzazioni parzialmente attendibili e con l'insieme minimo di autorizzazioni necessarie a consentirne il funzionamento. Le autorizzazioni di accesso al codice seguenti sono le autorizzazioni minime necessarie per l'applicazione Entity Framework:
FileIOPermission: Write per aprire i file di metadati specificati o PathDiscovery per cercare i file di metadati in una directory.
ReflectionPermission: RestrictedMemberAccess per supportare query di LINQ to Entities.
DistributedTransactionPermission: Unrestricted da inserire in System.TransactionsTransaction.
SecurityPermission: SerializationFormatter per serializzare le eccezioni tramite l'interfaccia ISerializable.
Autorizzazione per aprire una connessione al database ed eseguire comandi sul database, ad esempio SqlClientPermission per un database di SQL Server.
Per ulteriori informazioni, vedere Sicurezza dall'accesso di codice e ADO.NET.
Non installare applicazioni non attendibili.
Entity Framework non applica autorizzazioni di sicurezza e richiamerà qualsiasi codice dell'oggetto dati fornito dall'utente in corso, indipendentemente dall'attendibilità. Assicurarsi che l'autenticazione e l'autorizzazione del client vengano eseguite dall'archivio dati e dall'applicazione.
Limitare l'accesso a tutti i file di configurazione.
Un amministratore deve limitare l'accesso in scrittura a tutti i file che specificano la configurazione per un'applicazione, inclusi enterprisesec.config, security.config, machine.conf e i file di configurazione dell'applicazione <applicazione>.exe.config.
Il nome invariante del provider può essere modificato in app.config. L'applicazione client deve accedere al provider sottostante tramite il modello di factory di provider standard utilizzando un nome sicuro.
Limitare le autorizzazioni ai file di mapping e di Entity Data Model.
Un amministratore deve limitare l'accesso in scrittura ai file di modello e di mapping (csdl, ssdl e msl) solo agli utenti che modificano il modello o i mapping. Entity Framework richiede solo l'accesso in lettura a questi file in fase di esecuzione. Un amministratore deve limitare anche l'accesso ai file del codice sorgente di visualizzazione precompilati e a livello di oggetto generati dagli strumenti di Entity Data Model.
Considerazioni sulla sicurezza relative alle query
Le considerazioni sulla sicurezza illustrate di seguito riguardano l'esecuzione di query su un modello EDM. Si applicano alle query Entity SQL che utilizzano EntityClient e alle query di oggetto che usano LINQ, Entity SQL e i metodi del generatore di query.
Impedire attacchi di tipo SQL injection.
Le applicazioni spesso accettano input esterno, ad esempio da un utente o da un altro agente esterno, ed eseguono azioni basate su tale input. L'eventuale input derivato in modo diretto o indiretto dall'utente o da un agente esterno può includere contenuto che sfrutta la sintassi del linguaggio di destinazione per eseguire azioni non autorizzate. Quando il linguaggio di destinazione è un linguaggio SQL (Structured Query Language), ad esempio Transact-SQL, questa manipolazione è nota come attacco di tipo SQL injection. Un utente malintenzionato può inserire comandi direttamente nella query e rimuovere una tabella di database, determinare un attacco di tipo Denial of Service o alterare in altro modo la natura dell'operazione da eseguire.
Attacchi di tipo Entity SQL injection:
Gli attacchi di tipo SQL injection possono essere eseguiti in Entity SQL attraverso l'inserimento di input dannoso nei valori utilizzati in un predicato della query e nei nomi del parametro. Per evitare il rischio di SQL injection, è necessario non combinare mai l'input dell'utente con il testo dei comandi Entity SQL.
Le query Entity SQL accettano parametri ovunque vengano accettati i valori letterali. È opportuno utilizzare query con parametri, anziché inserire valori letterali direttamente nella query tramite un agente esterno.
Attacchi di tipo LINQ to Entities injection :
Sebbene la composizione di query sia possibile in LINQ to Entities, essa viene eseguita attraverso l'API del modello a oggetti. A differenza delle query Entity SQL, le query LINQ to Entities non vengono composte mediante la manipolazione o la concatenazione di stringhe e non sono soggette agli attacchi SQL injection tradizionali.
Evitare la creazione di set di risultati molto grandi.
Un set di risultati molto grande può causare la chiusura del sistema client se il client sta eseguendo operazioni che utilizzano una quantità di risorse proporzionale alla dimensione del set di risultati. Set di risultati insolitamente grandi possono essere prodotti in presenza delle condizioni seguenti:
In query eseguite su un database molto ampio che non includono condizioni di filtro adatte.
In query che creano join cartesiani sul server.
In query Entity SQL nidificate.
Quando si accetta l'input dell'utente, è necessario assicurarsi che esso non causi l'aumento delle dimensioni del set di risultati oltre le capacità di gestione del sistema. Per limitare le dimensioni, è possibile utilizzare anche il metodo Take in LINQ to Entities o l'operatore LIMIT in Entity SQL.
Considerazioni sulla sicurezza relative a Object Services
Le considerazioni sulla sicurezza illustrate di seguito sono valide in caso di generazione e utilizzo di tipi di entità.
Non condividere un oggetto ObjectContext tra domini dell'applicazione.
La condivisione di un oggetto ObjectContext con più di un dominio dell'applicazione potrebbe esporre le informazioni contenute nella stringa di connessione. Al contrario, è necessario trasferire oggetti serializzati o oggetti grafici all'altro dominio dell'applicazione e quindi allegarli a un ObjectContext nel dominio dell'applicazione. Per ulteriori informazioni, vedere Serializzazione di oggetti (Entity Framework).
Impedire violazioni dell'indipendenza dai tipi.
Se l'indipendenza dai tipi viene violata, Object Services non è in grado di garantire l'integrità dei dati negli oggetti. La violazione può verificarsi se si consente l'esecuzione di applicazioni non attendibili con la sicurezza dall'accesso di codice dall'attendibilità totale.
Gestire le eccezioni nelle applicazioni ospitate.
In un ambiente di hosting, ad esempio ASP.NET, è necessario accedere a metodi e proprietà di un oggetto ObjectContext all'interno di un blocco try-catch. Il rilevamento di eccezioni impedisce alle eccezioni non gestite di esporre voci nell'oggetto ObjectStateManager agli utenti dell'applicazione.
Considerazioni sulla sicurezza relative ad applicazioni ASP.NET
Quando si utilizzano percorsi in applicazioni ASP.NET, è necessario considerare quanto segue.
Verificare se l'host esegue i controlli del percorso.
Quando viene utilizzata la stringa di sostituzione |DataDirectory| (racchiusa tra barre verticali), ADO.NET verifica che il percorso risolto sia supportato. "..", ad esempio, non è consentito dietro DataDirectory. Lo stesso controllo per la risoluzione dell'operatore radice dell'applicazione Web (~) viene eseguito dal processo che ospita ASP.NET. IIS esegue questo controllo, ma è possibile che host diversi da IIS non verifichino il supporto del percorso risolto. È opportuno dunque conoscere il comportamento dell'host su cui viene distribuita un'applicazione Entity Framework.
Non dare per scontati i nomi di percorso risolti.
Anche se i valori in cui l'operatore radice (~) e la stringa di sostituzione DataDirectory si risolvono dovrebbero rimanere costanti durante il runtime dell'applicazione, Entity Framework non impedisce all'host di modificarli.
Verificare la lunghezza del percorso prima della distribuzione.
Prima di distribuire un'applicazione Entity Framework, è necessario assicurarsi che i valori dell'operatore radice (~) e la stringa di sostituzione DataDirectory non superino i limiti di lunghezza del percorso stabiliti dal sistema operativo. I provider di dati ADO.NET non verificano che la lunghezza del percorso rientri nei limiti validi.
Considerazioni sulla sicurezza relative ai metadati ADO.NET
Le considerazioni sulla sicurezza illustrate di seguito si applicano in caso di generazione e utilizzo di file di mapping e di modello EDM.
Non esporre informazioni riservate tramite la registrazione.
I componenti del servizio di metadati ADO.NET non registrano informazioni private. In presenza di risultati che non è possibile restituire a causa di restrizioni di accesso, i sistemi di gestione dei database e i file system devono restituire zero risultati anziché generare un'eccezione che potrebbe contenere informazioni riservate.
Non accettare oggetti MetadataWorkspace da fonti non attendibili.
Le applicazioni non devono accettare istanze della classe MetadataWorkspace da fonti non attendibili. Al contrario, è necessario costruire in modo esplicito un'area di lavoro e popolarla a partire da tale origine.
Vedere anche
Concetti
Considerazioni relative alla distribuzione (Entity Framework)
Considerazioni sulla migrazione (Entity Framework)
Altre risorse
Protezione di applicazioni ADO.NET
Guida per programmatori (Entity Framework)