Infrastruttura di sicurezza: convalida dell'input - Procedure di mitigazione
Disabilitare gli script XSLT per tutte le trasformazioni con fogli di stile non attendibili
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | Sicurezza XSLT , Proprietà XsltSettings.EnableScript |
Passaggi | XSLT supporta l'inserimento di script all'interno dei fogli di stile con l'elemento <msxml:script> . Ciò consente di usare funzioni personalizzate in una trasformazione XSLT. Lo script viene eseguito nel contesto del processo che esegue la trasformazione. Lo script XSLT può essere disabilitato in un ambiente non attendibile per impedire l'esecuzione di codice non attendibile. Se si usa .NET, gli script XSLT sono disabilitati per impostazione predefinita. È tuttavia necessario verificare che non siano stati abilitati in modo esplicito tramite la proprietà XsltSettings.EnableScript . |
Esempio
XsltSettings settings = new XsltSettings();
settings.EnableScript = true; // WRONG: THIS SHOULD BE SET TO false
Esempio
Se si usa MSXML 6.0, gli script XSLT sono disabilitati per impostazione predefinita. È tuttavia necessario verificare che non siano stati abilitati in modo esplicito tramite la proprietà AllowXsltScript dell'oggetto DOM XML.
doc.setProperty("AllowXsltScript", true); // WRONG: THIS SHOULD BE SET TO false
Esempio
Se si usa MSXML 5 o versione inferiore, gli script XSLT sono abilitati per impostazione predefinita e devono essere disabilitati in modo esplicito. Impostare la proprietà AllowXsltScript dell'oggetto DOM XML su false.
doc.setProperty("AllowXsltScript", false); // CORRECT. Setting to false disables XSLT scripting.
Verificare che ogni pagina che potrebbe includere contenuti controllabili dall'utente rifiuti esplicitamente l'analisi MIME automatica
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | IE8 Security Part V: Comprehensive Protection (Sicurezza di IE8 parte V: protezione completa) |
Passaggi | Per ogni pagina che potrebbe includere contenuti controllabili dall'utente, è necessario usare l'intestazione HTTP A ogni tipo di file fornito da un server Web è associato un tipo MIME (denominato anche content-type) che descrive la natura del contenuto (immagine, testo, applicazione e così via). L'intestazione X-Content-Type-Options è un'intestazione HTTP che consente agli sviluppatori di specificare che il contenuto non deve essere sottoposto ad analisi MIME. Questa intestazione è progettata per mitigare gli attacchi basati sull'analisi MIME. Il supporto per questa intestazione è stato aggiunto in Internet Explorer 8 (IE8). Solo gli utenti di Internet Explorer 8 (IE8) potranno usufruire di X-Content-Type-Options. Le versioni precedenti di Internet Explorer attualmente non rispettano l'intestazione X-Content-Type-Options Internet Explorer 8 e le versioni successive sono gli unici browser principali che implementano una funzionalità di rifiuto esplicito dell'analisi MIME. Se e quando gli altri browser principali (Firefox, Safari e Chrome) implementeranno funzionalità simili, questa raccomandazione verrà aggiornata per includere anche la sintassi per tali browser. |
Esempio
Per abilitare l'intestazione necessaria a livello globale per tutte le pagine nell'applicazione, eseguire una di queste operazioni:
- Aggiungere l'intestazione nel file web.config se l'applicazione è ospitata da Internet Information Services (IIS) 7
<system.webServer>
<httpProtocol>
<customHeaders>
<add name=""X-Content-Type-Options"" value=""nosniff""/>
</customHeaders>
</httpProtocol>
</system.webServer>
- Aggiungere l'intestazione tramite il Application_BeginRequest globale
void Application_BeginRequest(object sender, EventArgs e)
{
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
}
- Implementare un modulo HTTP personalizzato
public class XContentTypeOptionsModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += newEventHandler(context_PreSendRequestHeaders);
}
#endregion
void context_PreSendRequestHeaders(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
if (application == null)
return;
if (application.Response.Headers[""X-Content-Type-Options ""] != null)
return;
application.Response.Headers.Add(""X-Content-Type-Options "", ""nosniff"");
}
}
- È possibile abilitare l'intestazione necessaria solo per pagine specifiche aggiungendola a singole risposte:
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
Applicare la protezione avanzata o la disabilitazione della risoluzione di entità XML
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | Espansione di entità XML, Attacchi Denial of Service e difese in XML, Cenni preliminari sulla sicurezza MSXML, Procedure consigliate per la protezione del codice MSXML, Informazioni di riferimento sul protocollo NSXMLParserDelegate, Risoluzione di riferimenti esterni |
Passaggi | Nonostante non sia largamente usata, esiste una funzionalità di XML che consente al parser XML di espandere macro entità con valori definiti all'interno del documento stesso o da origini esterne. Ad esempio, il documento potrebbe definire un'entità "companyname" con il valore "Microsoft", in modo che ogni volta che il testo "&companyname;" venga visualizzato nel documento, viene sostituito automaticamente con il testo Microsoft. In alternativa, il documento potrebbe definire un'entità "MSFTStock" che fa riferimento a un servizio Web esterno per recuperare il valore corrente delle azioni Microsoft. Quindi, ogni volta che "&MSFTStock;" viene visualizzato nel documento, viene sostituito automaticamente con il prezzo azionario corrente. Questa funzionalità può tuttavia essere usata in modo improprio per creare condizioni di Denial of Service (DoS). Un utente malintenzionato può annidare più entità per creare un'espansione esponenziale di XML che userà tutta la memoria disponibile nel sistema. In alternativa, può creare un riferimento esterno che trasmette una quantità infinita di dati o semplicemente blocca il thread. Di conseguenza, tutti i team devono disabilitare interamente la risoluzione di entità XML interne e/o esterne se non viene usata dall'applicazione oppure, se tale funzionalità è assolutamente necessaria, limitare manualmente la quantità di memoria e di tempo utilizzabile dall'applicazione per la risoluzione di entità. Se la risoluzione di entità non è richiesta dall'applicazione, disabilitarla. |
Esempio
Per il codice .NET Framework, è possibile usare gli approcci seguenti:
XmlTextReader reader = new XmlTextReader(stream);
reader.ProhibitDtd = true;
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);
// for .NET 4
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlReader reader = XmlReader.Create(stream, settings);
Si noti che il valore predefinito di ProhibitDtd
in XmlReaderSettings
è true, ma in XmlTextReader
è false. Se si usa XmlReaderSettings, non è necessario impostare ProhibitDtd su true in modo esplicito, ma è consigliabile ai fini della sicurezza. Si noti anche che la classe XmlDocument consente la risoluzione di entità per impostazione predefinita.
Esempio
Per disabilitare la risoluzione di entità per le classi XmlDocument, usare l'overload XmlDocument.Load(XmlReader)
del metodo Load e impostare le proprietà appropriate nell'argomento XmlReader per disabilitare la risoluzione, come illustrato nel codice seguente:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument doc = new XmlDocument();
doc.Load(reader);
Esempio
Se non è possibile disabilitare la risoluzione di entità per l'applicazione, impostare la proprietà XmlReaderSettings.MaxCharactersFromEntities su un valore ragionevole in base alle esigenze dell'applicazione. Verrà così limitato l'impatto dei potenziali attacchi DoS con espansione esponenziale. Il codice seguente offre un esempio di questo approccio:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
XmlReader reader = XmlReader.Create(stream, settings);
Esempio
Se è necessario risolvere entità incorporate ma non entità esterne, impostare la proprietà XmlReaderSettings.XmlResolver su null. Ad esempio:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(stream, settings);
Si noti che in MSXML6, la proprietà ProhibitDTD è impostata su true (in modo da disabilitare l'elaborazione DTD) per impostazione predefinita. Per il codice Apple OSX/iOS, è possibile usare due parser XML: NSXMLParser e libXML2.
Verifica della canonizzazione degli URL nelle applicazioni che utilizzano http.sys
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | N/D |
Passaggi | Tutte le applicazioni che usano http.sys devono seguire le linee guida seguenti:
|
Verificare la presenza dei controlli appropriati quando si accettano file dagli utenti
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | Unrestricted File Upload (Caricamento di file senza restrizioni), File Signature Table (Tabella delle firme dei file) |
Passaggi | I file caricati rappresentano un rischio significativo per le applicazioni. Il primo passaggio di numerosi attacchi consiste nell'inserire codice nel sistema da attaccare. È quindi sufficiente trovare un modo per far sì che il codice venga eseguito. Il caricamento di un file consente all'utente malintenzionato di portare a termine il primo passaggio. Le conseguenze del caricamento di file senza restrizioni possono variare dalla completa acquisizione della proprietà del sistema al sovraccarico del file system o del database, all'inoltro di attacchi ai sistemi back-end e al semplice danneggiamento. Ciò dipende da come il file caricato viene usato dall'applicazione e soprattutto dalla posizione in cui viene archiviato. La convalida sul lato server dei caricamenti di file non è disponibile. Per la funzionalità di caricamento file devono essere implementati i controlli di sicurezza seguenti:
|
Esempio
Per informazioni dettagliate sull'ultimo punto relativo alla convalida della firma del formato di file, vedere la classe seguente:
private static Dictionary<string, List<byte[]>> fileSignature = new Dictionary<string, List<byte[]>>
{
{ ".DOC", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } } },
{ ".DOCX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
{ ".PDF", new List<byte[]> { new byte[] { 0x25, 0x50, 0x44, 0x46 } } },
{ ".ZIP", new List<byte[]>
{
new byte[] { 0x50, 0x4B, 0x03, 0x04 },
new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x55 },
new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
new byte[] { 0x50, 0x4B, 0x05, 0x06 },
new byte[] { 0x50, 0x4B, 0x07, 0x08 },
new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 }
}
},
{ ".PNG", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
{ ".JPG", new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 }
}
},
{ ".JPEG", new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 }
}
},
{ ".XLS", new List<byte[]>
{
new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 },
new byte[] { 0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00 },
new byte[] { 0xFD, 0xFF, 0xFF, 0xFF }
}
},
{ ".XLSX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
{ ".GIF", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } }
};
public static bool IsValidFileExtension(string fileName, byte[] fileData, byte[] allowedChars)
{
if (string.IsNullOrEmpty(fileName) || fileData == null || fileData.Length == 0)
{
return false;
}
bool flag = false;
string ext = Path.GetExtension(fileName);
if (string.IsNullOrEmpty(ext))
{
return false;
}
ext = ext.ToUpperInvariant();
if (ext.Equals(".TXT") || ext.Equals(".CSV") || ext.Equals(".PRN"))
{
foreach (byte b in fileData)
{
if (b > 0x7F)
{
if (allowedChars != null)
{
if (!allowedChars.Contains(b))
{
return false;
}
}
else
{
return false;
}
}
}
return true;
}
if (!fileSignature.ContainsKey(ext))
{
return true;
}
List<byte[]> sig = fileSignature[ext];
foreach (byte[] b in sig)
{
var curFileSig = new byte[b.Length];
Array.Copy(fileData, curFileSig, b.Length);
if (curFileSig.SequenceEqual(b))
{
flag = true;
break;
}
}
return flag;
}
Verificare che nell'applicazione Web vengano usati parametri indipendenti dai tipi per l'accesso ai dati
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | N/D |
Passaggi | Se si usa la raccolta Parameters, SQL considera l'input come un valore letterale anziché come codice eseguibile. La raccolta Parameters può essere usata per imporre vincoli di tipo e lunghezza sui dati di input. I valori non compresi nell'intervallo attivano un'eccezione. Se non vengono usati parametri SQL indipendenti dai tipi, gli utenti malintenzionati potrebbero eseguire attacchi di tipo injection incorporati nell'input non filtrato. Quando si costruiscono query SQL, usare parametri indipendenti dai tipi per evitare gli attacchi SQL injection che possono verificarsi con input non filtrato. È possibile usare parametri indipendenti dai tipi con stored procedure e con istruzioni SQL dinamiche. I parametri vengono considerati dal database come valori letterali e non come codice eseguibile. Viene anche eseguito il controllo del tipo e della lunghezza dei parametri. |
Esempio
Il codice seguente illustra come usare parametri indipendenti dai tipi con SqlParameterCollection quando si chiama una stored procedure.
using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet userDataset = new DataSet();
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11);
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text;
myCommand.Fill(userDataset);
}
Nell'esempio di codice precedente, la lunghezza del valore di input non può essere maggiore di 11 caratteri. Se i dati non sono conformi alla lunghezza o al tipo definito dal parametro, la classe SqlParameter genera un'eccezione.
Usare classi di associazione di modelli separate o elenchi di filtri di associazione per prevenire la vulnerabilità dell'assegnazione di massa in MVC
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | MVC 5, MVC 6 |
Attributi | N/D |
Riferimenti | Attributi dei metadati, Public Key Security Vulnerability And Mitigation (Vulnerabilità della sicurezza delle chiavi pubbliche e mitigazione), Guida completa all'assegnazione di massa in ASP.NET MVC, Introduzione a Entity Framework con MVC |
Passaggi |
|
Codificare l'output Web non attendibile prima del rendering
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generico, Web Form, MVC 5, MVC 6 |
Attributi | N/D |
Riferimenti | How to prevent Cross-site scripting in ASP.NET (Come impedire attacchi tramite script da altri siti in ASP.NET), Cross-site Scripting (Attacchi tramite script da altri siti), XSS (Cross Site Scripting) Prevention Cheat Sheet (Foglio informativo sulla prevenzione degli attacchi tramite script da altri siti) |
Passaggi | Gli attacchi tramite script da altri siti (comunemente abbreviati in XSS, Cross-Site Scripting) sono un vettore di attacco per i servizi online o qualsiasi applicazione/componente che utilizza input dal Web. Le vulnerabilità XSS possono consentire a un utente malintenzionato di eseguire script sul computer di un altro utente tramite un'applicazione Web vulnerabile. Gli script dannosi possono essere usati per rubare cookie o manomettere in altro modo il computer di una vittima tramite JavaScript. È possibile impedire attacchi XSS convalidando l'input utente e verificando che il formato e la codifica siano corretti prima di eseguirne il rendering in una pagina Web. La convalida dell'input e la codifica dell'output possono essere eseguite con Web Protection Library. Per codice gestito (C#, VB.NET e così via), usare uno o più metodi di codifica appropriati dalla libreria Protezione Web (Anti-XSS), a seconda del contesto in cui l'input dell'utente viene manifesto: |
Esempio
* Encoder.HtmlEncode
* Encoder.HtmlAttributeEncode
* Encoder.JavaScriptEncode
* Encoder.UrlEncode
* Encoder.VisualBasicScriptEncode
* Encoder.XmlEncode
* Encoder.XmlAttributeEncode
* Encoder.CssEncode
* Encoder.LdapEncode
Eseguire la convalida dell'input e applicare filtri a tutte le proprietà del modello di tipo stringa
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generico, MVC 5, MVC 6 |
Attributi | N/D |
Riferimenti | Adding Validation (Aggiunta della convalida), Validating Model Data in an MVC Application (Convalida dei dati del modello in un'applicazione MVC), Principi guida per le applicazioni ASP.NET MVC |
Passaggi | Tutti i parametri di input devono essere convalidati prima di essere usati nell'applicazione per garantire la protezione dell'applicazione da input utente dannosi. Convalidare i valori di input usando le convalide delle espressioni regolari sul lato server con una strategia di convalida dell'elenco consentita. I parametri o gli input utente non purificati passati ai metodi possono causare vulnerabilità a code injection. Per le applicazioni Web, i punti di ingresso possono includere anche campi modulo, stringhe di query, cookie, intestazioni HTTP e parametri del servizio Web. All'associazione di modelli devono essere eseguiti i controlli di convalida dell'input seguenti:
|
Applicazione della purificazione nei campi modulo che accettano tutti i caratteri, ad esempio un editor di testo RTF
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | Encode Unsafe Input (Codificare l'input non sicuro), HtmlSanitizer |
Passaggi | Identificare tutti i tag di markup statici che si vogliono usare. Una procedura comune consiste nel limitare la formattazione a elementi HTML sicuri, come Prima della scrittura dei dati, applicare la codifica HTML. In questo modo, eventuali script dannosi diventeranno sicuri perché verranno gestiti come testo anziché come codice eseguibile.
La direttiva di pagina nei riferimenti disabilita la convalida delle richieste ASP.NET con l'impostazione HtmlSanitizer è una libreria .NET per la pulizia di documenti e frammenti HTML dei costrutti che possono causare attacchi XSS. Per l'analisi, la manipolazione e il rendering di HTML e CSS usa AngleSharp. È possibile installare HtmlSanitizer come pacchetto NuGet e passare l'input utente attraverso i metodi di purificazione HTML o CSS pertinenti, a seconda dei casi, sul lato server. Si noti che la purificazione deve essere presa in considerazione come controllo di sicurezza solo come ultima opzione. La convalida dell'input e la codifica dell'output sono considerati controlli di sicurezza più efficienti. |
Non assegnare elementi DOM a sink senza codifica incorporata
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | N/D |
Passaggi | Molte funzioni JavaScript non eseguono la codifica per impostazione predefinita. L'assegnazione di input non attendibile a elementi DOM tramite funzioni di questo tipo può determinare attacchi tramite script da altri siti (XSS). |
Esempio
Gli esempi seguenti non sono sicuri:
document.getElementByID("div1").innerHtml = value;
$("#userName").html(res.Name);
return $('<div/>').html(value)
$('body').append(resHTML);
Non usare innerHtml
. Usare invece innerText
. Analogamente, usare $("#elm").text()
invece di $("#elm").html()
.
Convalidare come chiusi o sicuri tutti i reindirizzamenti nell'applicazione
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | The OAuth 2.0 Authorization Framework - Open Redirectors (Framework di autorizzazione di OAuth 2.0 - Redirector aperti) |
Passaggi | Se la progettazione dell'applicazione richiede il reindirizzamento a un percorso specificato dall'utente, è necessario vincolare le possibile destinazioni di reindirizzamento a un elenco "sicuro" predefinito di siti o domini. Tutti i reindirizzamenti nell'applicazione devono essere chiusi/sicuri. A questo scopo:
|
Implementare la convalida dell'input in un tutti i parametri di tipo stringa accettati dai metodi del controller
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generico, MVC 5, MVC 6 |
Attributi | N/D |
Riferimenti | Validating Model Data in an MVC Application (Convalida dei dati del modello in un'applicazione MVC), Principi guida per le applicazioni ASP.NET MVC |
Passaggi | Per i metodi che accettano come argomento solo un tipo di dati primitivo e non modelli, deve essere eseguita la convalida dell'input con un'espressione regolare. In questo caso, è necessario usare Regex.IsMatch con un criterio regex valido. Se l'input non corrisponde all'espressione regolare specificata, il controllo dovrà essere interrotto e dovrà essere visualizzato un avviso relativo all'errore di convalida. |
Impostare il limite massimo di timeout per l'elaborazione di espressioni regolari per impedire attacchi DoS causati da espressioni regolari errate
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generico, Web Form, MVC 5, MVC 6 |
Attributi | N/D |
Riferimenti | Proprietà DefaultRegexMatchTimeout |
Passaggi | Per prevenire attacchi Denial of Service contro espressioni regolari create in modo non corretto, che causano un elevato backtracking, impostare il timeout predefinito globale. Se il tempo necessario per l'elaborazione è superiore al limite massimo definito, verrà generata un'eccezione di timeout. In assenza di configurazione, il timeout sarà infinito. |
Esempio
La configurazione seguente, ad esempio, genera un'eccezione RegexMatchTimeoutException se l'elaborazione richiede più di 5 secondi:
<httpRuntime targetFramework="4.5" defaultRegexMatchTimeout="00:00:05" />
Evitare di usare Html.Raw nelle visualizzazioni Razor
Title | Dettagli |
---|---|
Componente | Applicazione Web |
Fase SDL | Compilazione |
Tecnologie applicabili | MVC 5, MVC 6 |
Attributi | N/D |
Riferimenti | N/D |
Procedi | Le pagine Web ASP.NET (Razor) eseguono la codifica HTML automatica. A tutte le stringhe stampate da nugget di codice incorporati (blocchi @) viene applicata automaticamente la codifica HTML. Quando viene richiamato HtmlHelper.Raw , tuttavia, questo metodo restituisce markup senza codifica HTML. Se viene usato il metodo helper Html.Raw() , questo ignora la protezione con codifica automatica fornita da Razor. |
Esempio
L'esempio seguente non è sicuro:
<div class="form-group">
@Html.Raw(Model.AccountConfirmText)
</div>
<div class="form-group">
@Html.Raw(Model.PaymentConfirmText)
</div>
</div>
Non usare Html.Raw()
a meno che non sia necessario visualizzare markup. Questo metodo non esegue implicitamente la codifica dell'output. Usare altri helper ASP.NET, ad esempio @Html.DisplayFor()
Non usare query dinamiche nelle stored procedure
Title | Dettagli |
---|---|
Componente | Database |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | N/D |
Passaggi | Un attacco SQL injection sfrutta le vulnerabilità nella convalida dell'input per eseguire comandi arbitrari nel database. Può verificarsi quando l'applicazione usa l'input per costruire istruzioni SQL dinamiche per accedere al database, nonché se il codice usa stored procedure costituite da stringhe passate contenenti input utente non elaborato. Con l'attacco SQL injection, l'utente malintenzionato può eseguire comandi arbitrari nel database. Tutte le istruzioni SQL, incluse quelle nelle stored procedure, devono includere parametri. Le istruzioni SQL con parametri accetteranno senza problemi caratteri con un significato speciale per SQL (come la virgoletta singola) perché sono fortemente tipizzate. |
Esempio
L'esempio seguente è una stored procedure dinamica non sicura:
CREATE PROCEDURE [dbo].[uspGetProductsByCriteria]
(
@productName nvarchar(200) = NULL,
@startPrice float = NULL,
@endPrice float = NULL
)
AS
BEGIN
DECLARE @sql nvarchar(max)
SELECT @sql = ' SELECT ProductID, ProductName, Description, UnitPrice, ImagePath' +
' FROM dbo.Products WHERE 1 = 1 '
PRINT @sql
IF @productName IS NOT NULL
SELECT @sql = @sql + ' AND ProductName LIKE ''%' + @productName + '%'''
IF @startPrice IS NOT NULL
SELECT @sql = @sql + ' AND UnitPrice > ''' + CONVERT(VARCHAR(10),@startPrice) + ''''
IF @endPrice IS NOT NULL
SELECT @sql = @sql + ' AND UnitPrice < ''' + CONVERT(VARCHAR(10),@endPrice) + ''''
PRINT @sql
EXEC(@sql)
END
Esempio
Di seguito è riportata la stessa stored procedure implementata in modo sicuro:
CREATE PROCEDURE [dbo].[uspGetProductsByCriteriaSecure]
(
@productName nvarchar(200) = NULL,
@startPrice float = NULL,
@endPrice float = NULL
)
AS
BEGIN
SELECT ProductID, ProductName, Description, UnitPrice, ImagePath
FROM dbo.Products where
(@productName IS NULL or ProductName like '%'+ @productName +'%')
AND
(@startPrice IS NULL or UnitPrice > @startPrice)
AND
(@endPrice IS NULL or UnitPrice < @endPrice)
END
Verificare l'esecuzione della convalida dei modelli nei metodi di API Web
Title | Dettagli |
---|---|
Componente | API Web |
Fase SDL | Compilazione |
Tecnologie applicabili | MVC 5, MVC 6 |
Attributi | N/D |
Riferimenti | Convalida dei modelli in un'API Web ASP.NET |
Passaggi | Quando un client invia dati a un'API Web, è obbligatorio convalidare i dati prima di eseguire qualsiasi elaborazione. Per le API Web ASP.NET che accettano modelli come input, usare le annotazioni dei dati nei modelli per impostare le regole di convalida nelle proprietà dei modelli. |
Esempio
Il codice seguente illustra quanto descritto sopra:
using System.ComponentModel.DataAnnotations;
namespace MyApi.Models
{
public class Product
{
public int Id { get; set; }
[Required]
[RegularExpression(@"^[a-zA-Z0-9]*$", ErrorMessage="Only alphanumeric characters are allowed.")]
public string Name { get; set; }
public decimal Price { get; set; }
[Range(0, 999)]
public double Weight { get; set; }
}
}
Esempio
Nel metodo di azione dei controller dell'API la validità del modello deve essere selezionata in modo esplicito come illustrato di seguito:
namespace MyApi.Controllers
{
public class ProductsController : ApiController
{
public HttpResponseMessage Post(Product product)
{
if (ModelState.IsValid)
{
// Do something with the product (not shown).
return new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
}
}
Implementare la convalida dell'input in tutti i parametri di tipo stringa accettati dai metodi di API Web
Title | Dettagli |
---|---|
Componente | API Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generico, MVC 5, MVC 6 |
Attributi | N/D |
Riferimenti | Validating Model Data in an MVC Application (Convalida dei dati del modello in un'applicazione MVC), Principi guida per le applicazioni ASP.NET MVC |
Passaggi | Per i metodi che accettano come argomento solo un tipo di dati primitivo e non modelli, deve essere eseguita la convalida dell'input con un'espressione regolare. In questo caso, è necessario usare Regex.IsMatch con un criterio regex valido. Se l'input non corrisponde all'espressione regolare specificata, il controllo dovrà essere interrotto e dovrà essere visualizzato un avviso relativo all'errore di convalida. |
Verificare che nell'API Web vengano usati parametri indipendenti dai tipi per l'accesso ai dati
Title | Dettagli |
---|---|
Componente | API Web |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | N/D |
Passaggi | Se si usa la raccolta Parameters, SQL considera l'input come un valore letterale anziché come codice eseguibile. La raccolta Parameters può essere usata per imporre vincoli di tipo e lunghezza sui dati di input. I valori non compresi nell'intervallo attivano un'eccezione. Se non vengono usati parametri SQL indipendenti dai tipi, gli utenti malintenzionati potrebbero eseguire attacchi di tipo injection incorporati nell'input non filtrato. Quando si costruiscono query SQL, usare parametri indipendenti dai tipi per evitare gli attacchi SQL injection che possono verificarsi con input non filtrato. È possibile usare parametri indipendenti dai tipi con stored procedure e con istruzioni SQL dinamiche. I parametri vengono considerati dal database come valori letterali e non come codice eseguibile. Viene anche eseguito il controllo del tipo e della lunghezza dei parametri. |
Esempio
Il codice seguente illustra come usare parametri indipendenti dai tipi con SqlParameterCollection quando si chiama una stored procedure.
using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet userDataset = new DataSet();
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11);
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text;
myCommand.Fill(userDataset);
}
Nell'esempio di codice precedente, la lunghezza del valore di input non può essere maggiore di 11 caratteri. Se i dati non sono conformi alla lunghezza o al tipo definito dal parametro, la classe SqlParameter genera un'eccezione.
Usare query SQL con parametri per Azure Cosmos DB
Title | Dettagli |
---|---|
Componente | Azure DocumentDB |
Fase SDL | Compilazione |
Tecnologie applicabili | Generica |
Attributi | N/D |
Riferimenti | Announcing SQL Parameterization in Azure Cosmos DB (Annuncio della parametrizzazione SQL in Azure Cosmos DB) |
Passaggi | Benché Azure Cosmos DB supporti solo query di sola lettura, se le query vengono costruite con la concatenazione con input utente sono comunque possibili attacchi SQL injection. Un utente potrebbe ottenere l'accesso a dati a cui non dovrebbe accedere nella stessa raccolta creando query SQL dannose. Se le query vengono costruite in base all'input utente, usare query SQL con parametri. |
WCF: convalida dell'input tramite l'associazione allo schema
Title | Dettagli |
---|---|
Componente | WCF |
Fase SDL | Compilazione |
Tecnologie applicabili | Generico, NET Framework 3 |
Attributi | N/D |
Riferimenti | MSDN |
Passaggi | L'assenza di convalida espone a diversi attacchi di tipo injection. La convalida dei messaggi rappresenta una linea di difesa nella protezione di un'applicazione WCF. Con questo approccio, si convalidano i messaggi usando schemi per proteggere le operazioni del servizio WCF dall'attacco di un client non autorizzato. Convalidare tutti i messaggi ricevuti dal client per proteggere il client dall'attacco di un servizio dannoso. In questo modo è possibile convalidare i messaggi quando le operazioni utilizzano contratti dati o contratti di messaggio, una funzionalità non supportata dalla convalida dei parametri. La convalida dei messaggi consente di creare la logica di convalida all'interno di schemi, offrendo così maggiore flessibilità e riducendo i tempi di sviluppo. Gli schemi possono essere riusati in diverse applicazioni all'interno dell'organizzazione, creando standard per la rappresentazione dei dati. La convalida dei messaggi consente anche di proteggere le operazioni quando utilizzano tipi di dati più complessi associati a contratti che rappresentano la logica di business. Per eseguire la convalida dei messaggi, si compila prima di tutto uno schema che rappresenta le operazioni del servizio e i tipi di dati utilizzati da tali operazioni. Si crea quindi una classe .NET che implementa un controllo messaggio personalizzato del client e un controllo messaggio personalizzato dello strumento di recapito per convalidare i messaggi inviati al servizio o da esso ricevuti. Successivamente, si implementa un comportamento dell'endpoint personalizzato per abilitare la convalida dei messaggi sia nel client che nel servizio. Infine, si implementa un elemento di configurazione personalizzato per la classe che consente di esporre il comportamento dell'endpoint personalizzato esteso nel file di configurazione del servizio o del client. |
WCF: convalida dell'input tramite controlli parametro
Title | Dettagli |
---|---|
Componente | WCF |
Fase SDL | Compilazione |
Tecnologie applicabili | Generico, NET Framework 3 |
Attributi | N/D |
Riferimenti | MSDN |
Passaggi | La convalida dell'input e dei dati rappresenta una linea di difesa importante nella protezione di un'applicazione WCF. È consigliabile convalidare tutti i parametri esposti nelle operazioni del servizio WCF per proteggere il servizio dall'attacco di un client malintenzionato. Viceversa, è consigliabile convalidare tutti i valori restituiti ricevuti dal client per proteggere il client dall'attacco di un servizio dannoso. WCF offre diversi punti di estendibilità che consentono di personalizzare il comportamento del runtime WCF creando estensioni personalizzate. I controlli messaggio e i controlli parametro sono due meccanismi di estendibilità usati per ottenere maggiore controllo sui dati che vengono passati tra un client e un servizio. È consigliabile usare i controlli parametro per la convalida dell'input e i controlli messaggio solo quando è necessario controllare l'intero flusso dei messaggi da e verso un servizio. Per eseguire la convalida dell'input, si compila una classe .NET e si implementa un controllo parametro personalizzato per convalidare i parametri per le operazioni nel servizio. Si implementa quindi un comportamento dell'endpoint personalizzato per abilitare la convalida sia nel client che nel servizio. Infine, si implementa un elemento di configurazione personalizzato per la classe che consente di esporre il comportamento dell'endpoint personalizzato esteso nel file di configurazione del servizio o del client. |