Dela via


Säkerhetsram: Indataverifiering | Mitigations

Produkt/tjänst Artikel
Webbprogram
Databas
Webb-API
Azure Document DB
WCF

Inaktivera XSLT-skript för alla transformeringar med hjälp av obetrodda formatmallar

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser XSLT-säkerhet, Xslt Inställningar. EnableScript-egenskap
Steg XSLT har stöd för skript i formatmallar med elementet <msxml:script> . Detta gör att anpassade funktioner kan användas i en XSLT-transformering. Skriptet körs under kontexten för den process som utför transformeringen. XSLT-skriptet måste inaktiveras i en obetrodd miljö för att förhindra körning av kod som inte är betrodd. Om du använder .NET: XSLT-skript är inaktiverat som standard, måste du dock se till att det inte uttryckligen har aktiverats via XsltSettings.EnableScript egenskapen.

Exempel

XsltSettings settings = new XsltSettings();
settings.EnableScript = true; // WRONG: THIS SHOULD BE SET TO false

Exempel

Om du använder MSXML 6.0 inaktiveras XSLT-skript som standard. Du måste dock se till att den inte uttryckligen har aktiverats via XML DOM-objektegenskapen AllowXsltScript.

doc.setProperty("AllowXsltScript", true); // WRONG: THIS SHOULD BE SET TO false

Exempel

Om du använder MSXML 5 eller lägre är XSLT-skript aktiverat som standard och du måste uttryckligen inaktivera det. Ange XML DOM-objektegenskapen AllowXsltScript till false.

doc.setProperty("AllowXsltScript", false); // CORRECT. Setting to false disables XSLT scripting.

Se till att varje sida som kan innehålla användarkontrollerbart innehåll avanmäler sig från automatisk MIME-sniffning

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser IE8-säkerhet del V – Omfattande skydd
Steg

För varje sida som kan innehålla användarkontrollerbart innehåll måste du använda HTTP-huvudet X-Content-Type-Options:nosniff. För att uppfylla detta krav kan du antingen ange den sidhuvudsida som krävs efter sida för endast de sidor som kan innehålla användarkontrollerbart innehåll, eller så kan du ange den globalt för alla sidor i programmet.

Varje typ av fil som levereras från en webbserver har en associerad MIME-typ (kallas även innehållstyp) som beskriver innehållets natur (dvs. bild, text, program osv.)

Rubriken X-Content-Type-Options är ett HTTP-huvud som gör att utvecklare kan ange att deras innehåll inte ska vara MIME-sniffat. Den här rubriken är utformad för att minimera MIME-sniffningsattacker. Stöd för den här rubriken har lagts till i Internet Explorer 8 (IE8)

Endast användare av Internet Explorer 8 (IE8) drar nytta av X-Content-Type-Options. Tidigare versioner av Internet Explorer respekterar för närvarande inte rubriken X-Content-Type-Options

Internet Explorer 8 (och senare) är de enda större webbläsarna som implementerar en MIME-sniffande opt-out-funktion. Om och när andra större webbläsare (Firefox, Safari, Chrome) implementerar liknande funktioner uppdateras den här rekommendationen till att även innehålla syntax för dessa webbläsare

Exempel

Om du vill aktivera det nödvändiga huvudet globalt för alla sidor i programmet kan du göra något av följande:

  • Lägg till huvudet i filen web.config om programmet hanteras av IIS (Internet Information Services) 7
<system.webServer> 
  <httpProtocol> 
    <customHeaders> 
      <add name=""X-Content-Type-Options"" value=""nosniff""/>
    </customHeaders>
  </httpProtocol>
</system.webServer> 
  • Lägg till rubriken via den globala Application_BeginRequest
void Application_BeginRequest(object sender, EventArgs e)
{
  this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
} 
  • Implementera anpassad HTTP-modul
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""); 
      } 
  } 

  • Du kan bara aktivera den nödvändiga rubriken för specifika sidor genom att lägga till den i enskilda svar:
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff""; 

Härda eller inaktivera XML-entitetsmatchning

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser XML-entitetsexpansion, XML Denial of Service-attacker och skydd, MSXML-säkerhetsöversikt, metodtips för att skydda MSXML-kod, NSXMLParserDelegate Protocol-referens, lösa externa referenser
Steg

Även om det inte används i stor utsträckning finns det en funktion i XML som gör att XML-parsern kan expandera makroentiteter med värden som definierats antingen i själva dokumentet eller från externa källor. Dokumentet kan till exempel definiera en entitet "företagsnamn" med värdet "Microsoft", så att varje gång texten "&companyname;" visas i dokumentet ersätts den automatiskt med texten Microsoft. Eller så kan dokumentet definiera en entitet "MSFTStock" som refererar till en extern webbtjänst för att hämta det aktuella värdet för Microsoft-lager.

När "&MSFTStock;" visas i dokumentet ersätts det automatiskt med den aktuella aktiekursen. Den här funktionen kan dock missbrukas för att skapa DoS-villkor (Denial of Service). En angripare kan kapsla flera entiteter för att skapa en exponentiell XML-bomb för expansion som förbrukar allt tillgängligt minne i systemet.

Alternativt kan han skapa en extern referens som strömmar tillbaka en oändlig mängd data eller som helt enkelt låser tråden. Därför måste alla team inaktivera intern och/eller extern XML-entitetsmatchning helt om deras program inte använder den, eller manuellt begränsa mängden minne och tid som programmet kan använda för entitetsmatchning om den här funktionen är absolut nödvändig. Om entitetsmatchning inte krävs av ditt program inaktiverar du det.

Exempel

För .NET Framework-kod kan du använda följande metoder:

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);

Observera att standardvärdet för ProhibitDtd i XmlReaderSettings är sant, men i XmlTextReader det är falskt. Om du använder XmlReader Inställningar behöver du inte uttryckligen ange ProhibitDtd till true, men det rekommenderas för säkerhets skull att du gör det. Observera också att klassen XmlDocument tillåter entitetsmatchning som standard.

Exempel

Om du vill inaktivera entitetsmatchning för XmlDocuments använder XmlDocument.Load(XmlReader) du överbelastningen av metoden Load och anger lämpliga egenskaper i XmlReader-argumentet för att inaktivera upplösning, enligt följande kod:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument doc = new XmlDocument();
doc.Load(reader);

Exempel

Om det inte går att inaktivera entitetsmatchning för ditt program anger du XmlReader Inställningar. MaxCharactersFromEntities-egenskapen till ett rimligt värde enligt programmets behov. Detta begränsar effekten av potentiella exponentiella Expansion DoS-attacker. Följande kod innehåller ett exempel på den här metoden:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
XmlReader reader = XmlReader.Create(stream, settings);

Exempel

Om du behöver lösa infogade entiteter men inte behöver matcha externa entiteter anger du XmlReader Inställningar. XmlResolver-egenskapen till null. Till exempel:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(stream, settings);

Observera att i MSXML6 är ProhibitDTD inställt på sant (inaktivera DTD-bearbetning) som standard. För Apple OSX/iOS-kod finns det två XML-parsare som du kan använda: NSXMLParser och libXML2.

Program som använder http.sys utför URL-kanoniseringsverifiering

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser Ej tillämpligt
Steg

Alla program som använder http.sys bör följa dessa riktlinjer:

  • Begränsa URL-längden till högst 16 384 tecken (ASCII eller Unicode). Det här är den absoluta maximala URL-längden baserat på standardinställningen Internet Information Services (IIS) 6. Webbplatser bör sträva efter en längd som är kortare än detta om möjligt
  • Använd standardfil-I/O-klasserna för .NET Framework (till exempel FileStream) eftersom dessa kommer att dra nytta av kanoniseringsreglerna i .NET FX
  • Skapa uttryckligen en lista över kända filnamn
  • Avvisa uttryckligen kända filtyper som du inte kommer att hantera UrlScan-avvisanden: exe, bat, cmd, com, htw, ida, idq, htr, idc, shtm[l], stm, printer, ini, pol, dat files
  • Fånga följande undantag:
    • System.ArgumentException (för enhetsnamn)
    • System.NotSupportedException (för dataströmmar)
    • System.IO.FileNotFoundException (för ogiltiga undantagna filnamn)
    • System.IO.DirectoryNotFoundException (för ogiltiga undantagna dirs)
  • Anropa inte Win32-fil-I/O-API:er. På en ogiltig URL returnerar korrekt ett 400-fel till användaren och loggar det verkliga felet.

Se till att lämpliga kontroller finns på plats när du tar emot filer från användare

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser Obegränsad filuppladdning, tabell för filsignatur
Steg

Uppladdade filer utgör en betydande risk för program.

Det första steget i många attacker är att få lite kod till systemet som ska attackeras. Då behöver attacken bara hitta ett sätt att få koden utförd. Genom att använda en filuppladdning kan angriparen utföra det första steget. Konsekvenserna av obegränsad filuppladdning kan variera, inklusive fullständigt systemövertagande, ett överbelastat filsystem eller en databas, vidarebefordran av attacker till serverdelssystem och enkel defacement.

Det beror på vad programmet gör med den uppladdade filen och särskilt var den lagras. Validering på serversidan av filuppladdningar saknas. Följande säkerhetskontroller bör implementeras för filuppladdningsfunktioner:

  • Filnamnstilläggskontroll (endast en giltig uppsättning tillåtna filtyper bör godkännas)
  • Maximal filstorleksgräns
  • Filen bör inte laddas upp till webroot. platsen ska vara en katalog på en enhet som inte är en systemenhet
  • Namngivningskonvention bör följas, så att det uppladdade filnamnet har viss slumpmässighet, för att förhindra filöverskrivningar
  • Filer ska genomsökas efter antivirus innan de skrivs till disken
  • Kontrollera att filnamnet och andra metadata (t.ex. filsökväg) har verifierats för skadliga tecken
  • Signatur för filformat bör kontrolleras för att förhindra att en användare laddar upp en maskerad fil (t.ex. ladda upp en exe-fil genom att ändra tillägget till txt)

Exempel

För den sista punkten om validering av filformatssignatur, se klassen nedan för mer information:

        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;
        }

Se till att typsäkra parametrar används i webbprogrammet för dataåtkomst

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser Ej tillämpligt
Steg

Om du använder samlingen Parametrar behandlar SQL indata som ett literalvärde snarare än som körbar kod. Samlingen Parametrar kan användas för att framtvinga typ- och längdbegränsningar för indata. Värden utanför intervallet utlöser ett undantag. Om typsäkra SQL-parametrar inte används kan angripare köra inmatningsattacker som är inbäddade i de ofiltrerade indata.

Använd typsäkra parametrar när du skapar SQL-frågor för att undvika eventuella SQL-inmatningsattacker som kan inträffa med ofiltrerade indata. Du kan använda typsäkra parametrar med lagrade procedurer och med dynamiska SQL-instruktioner. Parametrar behandlas som literalvärden av databasen och inte som körbar kod. Parametrarna kontrolleras också efter typ och längd.

Exempel

Följande kod visar hur du använder typsäkra parametrar med SqlParameterCollection när du anropar en lagrad procedur.

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);
}  

I föregående kodexempel får indatavärdet inte vara längre än 11 tecken. Om data inte överensstämmer med den typ eller längd som definieras av parametern utlöser klassen SqlParameter ett undantag.

Använd separata modellbindningsklasser eller bindningsfilterlistor för att förhindra sårbarhet för MVC-masstilldelning

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker MVC5, MVC6
Attribut Ej tillämpligt
Referenser Metadataattribut, säkerhetsrisk och riskreducering för offentliga nycklar, fullständig guide till masstilldelning i ASP.NET MVC, Komma igång med EF med MVC
Steg
  • När ska jag leta efter sårbarheter för överpublicering? - Överpublicering av sårbarheter kan inträffa på valfri plats där du binder modellklasser från användarindata. Ramverk som MVC kan representera användardata i anpassade .NET-klasser, inklusive Oformaterade gamla CLR-objekt (POCOs). MVC fyller automatiskt i dessa modellklasser med data från begäran, vilket ger en bekväm representation för att hantera användarindata. När dessa klasser innehåller egenskaper som inte ska anges av användaren kan programmet vara sårbart för överpubliceringsattacker, vilket tillåter användarkontroll av data som programmet aldrig avsåg. Precis som MVC-modellbindning stöder databasåtkomsttekniker som objekt-/relationsmappare som Entity Framework ofta också användning av POCO-objekt för att representera databasdata. Dessa datamodellklasser ger samma bekvämlighet när det gäller att hantera databasdata som MVC gör när det gäller att hantera användarindata. Eftersom både MVC och databasen stöder liknande modeller, till exempel POCO-objekt, verkar det enkelt att återanvända samma klasser för båda syftena. Den här metoden kan inte bevara uppdelningen av problem, och det är ett vanligt område där oavsiktliga egenskaper exponeras för modellbindning, vilket möjliggör överpubliceringsattacker.
  • Varför ska jag inte använda mina ofiltrerade databasmodellklasser som parametrar för mina MVC-åtgärder? - Eftersom MVC-modellbindningen binder allt i den klassen. Även om data inte visas i vyn kan en obehörig användare skicka en HTTP-begäran med dessa data inkluderade, och MVC binder den gärna eftersom din åtgärd säger att databasklassen är den form av data som den ska acceptera för användarindata.
  • Varför ska jag bry mig om den form som används för modellbindning? - Om du använder ASP.NET MVC-modellbindning med alltför breda modeller exponeras ett program för överpubliceringsattacker. Överpublicering kan göra det möjligt för angripare att ändra programdata utöver vad utvecklaren avsåg, till exempel åsidosätta priset för ett objekt eller säkerhetsbehörigheterna för ett konto. Program bör använda åtgärdsspecifika bindningsmodeller (eller specifika tillåtna egenskapsfilterlistor) för att tillhandahålla ett explicit kontrakt för vad ej betrodda indata ska tillåta via modellbindning.
  • Är det bara att duplicera kod med separata bindningsmodeller? - Nej, det är en fråga om separation av oro. Om du återanvänder databasmodeller i åtgärdsmetoder säger du att alla egenskaper (eller underegenskap) i den klassen kan anges av användaren i en HTTP-begäran. Om det inte är vad du vill att MVC ska göra behöver du en filterlista eller en separat klassform för att visa MVC vilka data som kan komma från användarindata i stället.
  • Om jag har separata bindningsmodeller för användarindata, måste jag duplicera alla mina dataanteckningsattribut? - Inte nödvändigtvis. Du kan använda MetadataTypeAttribute i databasmodellklassen för att länka till metadata i en modellbindningsklass. Observera bara att den typ som refereras av MetadataTypeAttribute måste vara en delmängd av referenstypen (den kan ha färre egenskaper, men inte mer).
  • Det är tråkigt att flytta data fram och tillbaka mellan användarindatamodeller och databasmodeller. Kan jag bara kopiera över alla egenskaper med reflektion? - Ja. De enda egenskaper som visas i bindningsmodellerna är de som du har fastställt är säkra för användarindata. Det finns ingen säkerhetsorsak som förhindrar att reflektion används för att kopiera över alla egenskaper som finns gemensamt mellan dessa två modeller.
  • Hur är det med [Bind(Exclude ="â€|")]. Kan jag använda det i stället för att ha separata bindningsmodeller? - Den här metoden rekommenderas inte. Om du använder [Bind(Exclude ="â€|")] innebär det att alla nya egenskaper kan bindas som standard. När en ny egenskap läggs till finns det ett extra steg att komma ihåg att skydda saker och ting i stället för att designen ska vara säker som standard. Beroende på vilken utvecklare som kontrollerar den här listan varje gång en egenskap läggs till är det riskabelt.
  • Är [Bind(Include ="â€|")] användbart för redigeringsåtgärder? - Nej. [Bind(Include ="â€|")] är endast lämplig för ÅTGÄRDER i INSERT-format (lägga till nya data). För åtgärder i UPPDATERINGsformat (ändra befintliga data) använder du en annan metod, till exempel att ha separata bindningsmodeller eller skicka en explicit lista över tillåtna egenskaper till UpdateModel eller TryUpdateModel. Att lägga till attributet [Bind(Include ="â€|")] för en redigeringsåtgärd innebär att MVC skapar en objektinstans och endast anger de listade egenskaperna, vilket lämnar alla andra som standardvärden. När data sparas ersätter de helt den befintliga entiteten och återställer värdena för eventuella utelämnade egenskaper till deras standardvärden. Om Till exempel IsAdmin utelämnades från ett [Bind(Include ="â€|")]-attribut för en redigeringsåtgärd, skulle alla användare vars namn redigerades via den här åtgärden återställas till IsAdmin = false (en redigerad användare skulle förlora administratörsstatus). Om du vill förhindra uppdateringar av vissa egenskaper använder du någon av de andra metoderna ovan. Observera att vissa versioner av MVC-verktyg genererar kontrollantklasser med [Bind(Include ="â€|")] på Redigera åtgärder och innebär att borttagning av en egenskap från listan förhindrar överpubliceringsattacker. Men enligt beskrivningen ovan fungerar inte den metoden som den är avsedd och återställer i stället alla data i de utelämnade egenskaperna till standardvärdena.
  • Finns det några varningar för att skapa åtgärder med hjälp av [Bind(Include ="â€|")] i stället för separata bindningsmodeller? - Ja. För det första fungerar inte den här metoden för redigeringsscenarier, vilket kräver två separata metoder för att minimera alla överpubliceringsrisker. För det andra framtvingar separata bindningsmodeller separation av problem mellan den form som används för användarindata och formen som används för beständighet, något [Bind(Include ="â€|")] inte gör. För det tredje, observera att [Bind(Include ="â€|")] bara kan hantera egenskaper på den översta nivån. Du kan inte bara tillåta delar av underegenskaper (till exempel "Details.Name") i attributet. Slutligen, och kanske viktigast av allt, med hjälp av [Bind(Include ="â€|")] lägger till ett extra steg som måste kommas ihåg varje gång klassen används för modellbindning. Om en ny åtgärdsmetod binder direkt till dataklassen och glömmer att inkludera attributet [Bind(Include ="â€|")] kan den vara sårbar för överpubliceringsattacker, så metoden [Bind(Include ="â€|")] är något mindre säker som standard. Om du använder [Bind(Include ="â€|")], var noga med att alltid komma ihåg att ange det varje gång dina dataklasser visas som åtgärdsmetodparametrar.
  • För Skapa åtgärder, vad sägs om att placera attributet [Bind(Include ="â€|")] på själva modellklassen? Undviker inte den här metoden behovet av att komma ihåg att lägga attributet på varje åtgärdsmetod? - Den här metoden fungerar i vissa fall. Om du använder [Bind(Include ="â€|")] på själva modelltypen (i stället för på åtgärdsparametrar som använder den här klassen) undviker du behovet av att komma ihåg att inkludera attributet [Bind(Include ="â€|")] på varje åtgärdsmetod. Om du använder attributet direkt i klassen skapas effektivt en separat yta i den här klassen för modellbindningsändamål. Den här metoden tillåter dock bara en modellbindningsform per modellklass. Om en åtgärdsmetod behöver tillåta modellbindning av ett fält (till exempel en åtgärd endast för administratörer som uppdaterar användarroller) och andra åtgärder måste förhindra modellbindning av det här fältet fungerar inte den här metoden. Varje klass kan bara ha en modellbindningsform. Om olika åtgärder behöver olika modellbindningsformer måste de representera dessa separata former med hjälp av antingen separata modellbindningsklasser eller separata attribut [Bind(Include ="â€|")] på åtgärdsmetoderna.
  • Vad är bindningsmodeller? Är de samma sak som visningsmodeller? - Det här är två relaterade begrepp. Termen bindningsmodell refererar till en modellklass som används i en åtgärds parameterlista (formen som skickas från MVC-modellbindningen till åtgärdsmetoden). Termen vymodell refererar till en modellklass som skickas från en åtgärdsmetod till en vy. Att använda en vyspecifik modell är en vanlig metod för att skicka data från en åtgärdsmetod till en vy. Ofta är den här formen också lämplig för modellbindning, och termen vymodell kan användas för att referera till samma modell som används på båda platserna. För att vara exakt talar detta förfarande specifikt om bindningsmodeller, med fokus på den form som skickas till åtgärden, vilket är det som är viktigt för masstilldelningsändamål.

Koda ej betrodda webbutdata före återgivning

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Generic, Web Forms, MVC5, MVC6
Attribut Ej tillämpligt
Referenser Så här förhindrar du skript mellan webbplatser i ASP.NET, skript för flera webbplatser, XSS -skydd (skript för flera webbplatser)
Steg Skript mellan webbplatser (ofta förkortat XSS) är en attackvektor för onlinetjänster eller program/komponent som använder indata från webben. XSS-sårbarheter kan göra det möjligt för en angripare att köra skript på en annan användares dator via ett sårbart webbprogram. Skadliga skript kan användas för att stjäla cookies och på annat sätt manipulera ett offers dator via JavaScript. XSS förhindras genom att användarindata verifieras, vilket säkerställer att det är välformat och kodning innan det återges på en webbsida. Indataverifiering och utdatakodning kan göras med hjälp av webbskyddsbiblioteket. För Hanterad kod (C#, VB.NET osv.) använder du en eller flera lämpliga kodningsmetoder från webbskyddsbiblioteket (Anti-XSS), beroende på kontexten där användarindata visas:

Exempel

* Encoder.HtmlEncode 
* Encoder.HtmlAttributeEncode 
* Encoder.JavaScriptEncode 
* Encoder.UrlEncode
* Encoder.VisualBasicScriptEncode 
* Encoder.XmlEncode 
* Encoder.XmlAttributeEncode 
* Encoder.CssEncode 
* Encoder.LdapEncode 

Utföra validering och filtrering av indata på alla egenskaper för strängtypmodell

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Generic, MVC5, MVC6
Attribut Ej tillämpligt
Referenser Lägga till validering, validera modelldata i ett MVC-program, vägledande principer för dina ASP.NET MVC-program
Steg

Alla indataparametrar måste verifieras innan de används i programmet för att säkerställa att programmet skyddas mot skadliga användarindata. Verifiera indatavärdena med valideringar av reguljära uttryck på serversidan med en tillåten listvalideringsstrategi. Oanvända användarindata/parametrar som skickas till metoderna kan orsaka sårbarheter vid kodinmatning.

För webbprogram kan startpunkter även innehålla formulärfält, QueryStrings, cookies, HTTP-huvuden och webbtjänstparametrar.

Följande verifieringskontroller av indata måste utföras vid modellbindning:

  • Modellegenskaperna ska kommenteras med RegularExpression-kommentar, för att acceptera tillåtna tecken och maximal tillåten längd
  • Kontrollantmetoderna ska utföra ModelState-giltighet

Sanitering bör tillämpas på formulärfält som accepterar alla tecken, t.ex. RTF-redigeraren

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser Koda osäkra indata, HTML-sanitator
Steg

Identifiera alla statiska påläggstaggar som du vill använda. En vanlig metod är att begränsa formateringen till säkra HTML-element, till exempel <b> (fetstil) och <i> (kursiv).

Innan du skriver data, HTML-koda dem. Detta gör alla skadliga skript säkra genom att det hanteras som text, inte som körbar kod.

  1. Inaktivera validering av ASP.NET begäran genom att lägga till attributet ValidateRequest="false" i @Page-direktivet
  2. Koda strängindata med htmlencode-metoden
  3. Använd en StringBuilder och anropa dess Replace-metod för att selektivt ta bort kodningen för de HTML-element som du vill tillåta

Sidan i referenserna inaktiverar ASP.NET validering av begäran genom att ange ValidateRequest="false". Html-kodar indata och tillåter <b> selektivt och <i> Alternativt kan ett .NET-bibliotek för HTML-sanering också användas.

HtmlSanitizer är ett .NET-bibliotek för att rensa HTML-fragment och dokument från konstruktioner som kan leda till XSS-attacker. Den använder AngleSharp för att parsa, manipulera och återge HTML och CSS. HtmlSanitizer kan installeras som ett NuGet-paket och användarindata kan skickas via relevanta HTML- eller CSS-saneringsmetoder, beroende på vad som är tillämpligt, på serversidan. Observera att sanering som en säkerhetskontroll endast bör betraktas som ett sista alternativ.

Indataverifiering och utdatakodning anses vara bättre säkerhetskontroller.

Tilldela inte DOM-element till mottagare som inte har inbyggd kodning

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser Ej tillämpligt
Steg Många JavaScript-funktioner kodar inte som standard. När du tilldelar obetrodda indata till DOM-element via sådana funktioner kan det resultera i XSS-körningar (cross site script).

Exempel

Följande är osäkra exempel:

document.getElementByID("div1").innerHtml = value;
$("#userName").html(res.Name);
return $('<div/>').html(value)
$('body').append(resHTML);   

Använd innerHtmlinte . Använd innerTexti stället . I stället för $("#elm").html()använder du på samma sätt $("#elm").text()

Verifiera att alla omdirigeringar i programmet stängs eller görs på ett säkert sätt

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser OAuth 2.0 Authorization Framework – Öppna omdirigeringar
Steg

Programdesign som kräver omdirigering till en plats som tillhandahålls av användaren måste begränsa de möjliga omdirigeringsmålen till en fördefinierad "säker" lista över webbplatser eller domäner. Alla omdirigeringar i programmet måste vara stängda/säkra.

Så här gör du:

  • Identifiera alla omdirigeringar
  • Implementera en lämplig åtgärd för varje omdirigering. Lämpliga åtgärder är listan över tillåtna omdirigeringar eller användarbekräftelse. Om en webbplats eller tjänst med en öppen omdirigeringsrisk använder Facebook/OAuth/OpenID-identitetsproviders kan en angripare stjäla en användares inloggningstoken och personifiera den användaren. Detta är en inneboende risk när du använder OAuth, som dokumenteras i RFC 6749 "The OAuth 2.0 Authorization Framework", avsnitt 10.15 "Öppna omdirigeringar" På samma sätt kan användarnas autentiseringsuppgifter komprometteras av nätfiskeattacker med hjälp av öppna omdirigeringar

Implementera indataverifiering på alla strängtypsparametrar som godkänns av kontrollantmetoder

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Generic, MVC5, MVC6
Attribut Ej tillämpligt
Referenser Validera modelldata i ett MVC-program, vägledande principer för dina ASP.NET MVC-program
Steg För metoder som bara accepterar primitiv datatyp, och inte modeller som argument, bör indataverifiering med reguljärt uttryck göras. Här bör Regex.IsMatch användas med ett giltigt regex-mönster. Om indata inte matchar det angivna reguljära uttrycket bör kontrollen inte fortsätta och en lämplig varning om valideringsfel ska visas.

Ange tidsgräns för övre gräns för bearbetning av reguljära uttryck för att förhindra DoS på grund av felaktiga reguljära uttryck

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker Generic, Web Forms, MVC5, MVC6
Attribut Ej tillämpligt
Referenser Egenskapen DefaultRegexMatchTimeout
Steg För att säkerställa överbelastningsattacker mot felaktigt skapade reguljära uttryck, som orsakar en hel del bakåtspårning, anger du den globala standardtimeouten. Om bearbetningstiden tar längre tid än den definierade övre gränsen utlöser den ett timeout-undantag. Om inget har konfigurerats skulle tidsgränsen vara oändlig.

Exempel

Följande konfiguration genererar till exempel en RegexMatchTimeoutException om bearbetningen tar mer än 5 sekunder:

<httpRuntime targetFramework="4.5" defaultRegexMatchTimeout="00:00:05" />

Undvik att använda Html.Raw i Razor-vyer

Title Details
Komponent Webbprogram
SDL-fas Skapa
Tillämpliga tekniker MVC5, MVC6
Attribut Ej tillämpligt
Referenser Ej tillämpligt
Steg ASP.NET WebPages (Razor) utför automatisk HTML-kodning. Alla strängar som skrivs ut av inbäddade kodklimpar (@ block) html-kodas automatiskt. Men när HtmlHelper.Raw metoden anropas returneras markering som inte är HTML-kodad. Om Html.Raw() hjälpmetoden används kringgås det automatiska kodningsskydd som Razor tillhandahåller.

Exempel

Följande är ett osäkert exempel:

<div class="form-group">
            @Html.Raw(Model.AccountConfirmText)
        </div>
        <div class="form-group">
            @Html.Raw(Model.PaymentConfirmText)
        </div>
</div>

Använd inte Html.Raw() om du inte behöver visa pålägg. Den här metoden utför inte utdatakodning implicit. Använd andra ASP.NET hjälpverktyg, t.ex. @Html.DisplayFor()

Använd inte dynamiska frågor i lagrade procedurer

Title Details
Komponent Databas
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser Ej tillämpligt
Steg

En SQL-inmatningsattack utnyttjar sårbarheter i indatavalidering för att köra godtyckliga kommandon i databasen. Det kan inträffa när ditt program använder indata för att skapa dynamiska SQL-instruktioner för att komma åt databasen. Det kan också inträffa om koden använder lagrade procedurer som skickas med strängar som innehåller råa användarindata. Med sql-inmatningsattacken kan angriparen köra godtyckliga kommandon i databasen. Alla SQL-instruktioner (inklusive SQL-uttrycken i lagrade procedurer) måste parametriseras. Parametriserade SQL-uttryck accepterar tecken som har särskild betydelse för SQL (som enkla citattecken) utan problem eftersom de är starkt skrivna.

Exempel

Följande är ett exempel på osäker dynamisk lagrad procedur:

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

Exempel

Följande är samma lagrade procedur som implementeras på ett säkert sätt:

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

Kontrollera att modellverifieringen görs på webb-API-metoder

Title Details
Komponent Webb-API
SDL-fas Skapa
Tillämpliga tekniker MVC5, MVC6
Attribut Ej tillämpligt
Referenser Modellverifiering i ASP.NET webb-API
Steg När en klient skickar data till ett webb-API är det obligatoriskt att verifiera data innan någon bearbetning utförs. För ASP.NET webb-API:er som accepterar modeller som indata använder du dataanteckningar på modeller för att ange verifieringsregler för modellens egenskaper.

Exempel

Följande kod visar samma sak:

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; }
    }
}

Exempel

I åtgärdsmetoden för API-kontrollanterna måste modellens giltighet uttryckligen kontrolleras enligt nedan:

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);
            }
        }
    }
}

Implementera indataverifiering på alla strängtypsparametrar som godkänts av web-API-metoder

Title Details
Komponent Webb-API
SDL-fas Skapa
Tillämpliga tekniker Generic, MVC 5, MVC 6
Attribut Ej tillämpligt
Referenser Validera modelldata i ett MVC-program, vägledande principer för dina ASP.NET MVC-program
Steg För metoder som bara accepterar primitiv datatyp, och inte modeller som argument, bör indataverifiering med reguljärt uttryck göras. Här bör Regex.IsMatch användas med ett giltigt regex-mönster. Om indata inte matchar det angivna reguljära uttrycket bör kontrollen inte fortsätta och en lämplig varning om valideringsfel ska visas.

Kontrollera att typsäkra parametrar används i webb-API för dataåtkomst

Title Details
Komponent Webb-API
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser Ej tillämpligt
Steg

Om du använder samlingen Parametrar behandlar SQL indata som ett literalvärde snarare än som körbar kod. Samlingen Parametrar kan användas för att framtvinga typ- och längdbegränsningar för indata. Värden utanför intervallet utlöser ett undantag. Om typsäkra SQL-parametrar inte används kan angripare köra inmatningsattacker som är inbäddade i de ofiltrerade indata.

Använd typsäkra parametrar när du skapar SQL-frågor för att undvika eventuella SQL-inmatningsattacker som kan inträffa med ofiltrerade indata. Du kan använda typsäkra parametrar med lagrade procedurer och med dynamiska SQL-instruktioner. Parametrar behandlas som literalvärden av databasen och inte som körbar kod. Parametrarna kontrolleras också efter typ och längd.

Exempel

Följande kod visar hur du använder typsäkra parametrar med SqlParameterCollection när du anropar en lagrad procedur.

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);
}  

I föregående kodexempel får indatavärdet inte vara längre än 11 tecken. Om data inte överensstämmer med den typ eller längd som definieras av parametern utlöser klassen SqlParameter ett undantag.

Använda parametriserade SQL-frågor för Azure Cosmos DB

Title Details
Komponent Azure Document DB
SDL-fas Skapa
Tillämpliga tekniker Allmän
Attribut Ej tillämpligt
Referenser Tillkännagivande av SQL-parameterisering i Azure Cosmos DB
Steg Även om Azure Cosmos DB endast stöder skrivskyddade frågor är SQL-inmatning fortfarande möjligt om frågor skapas genom sammanlänkning med användarindata. Det kan vara möjligt för en användare att få åtkomst till data som de inte bör komma åt i samma samling genom att skapa skadliga SQL-frågor. Använd parameteriserade SQL-frågor om frågor konstrueras baserat på användarindata.

Verifiering av WCF-indata via schemabindning

Title Details
Komponent WCF
SDL-fas Skapa
Tillämpliga tekniker Generic, NET Framework 3
Attribut Ej tillämpligt
Referenser MSDN
Steg

Brist på validering leder till olika typinmatningsattacker.

Meddelandeverifiering representerar en försvarslinje i skyddet av ditt WCF-program. Med den här metoden validerar du meddelanden med hjälp av scheman för att skydda WCF-tjänståtgärder från angrepp av en skadlig klient. Verifiera alla meddelanden som tas emot av klienten för att skydda klienten från angrepp av en skadlig tjänst. Meddelandeverifiering gör det möjligt att verifiera meddelanden när åtgärder använder meddelandekontrakt eller datakontrakt, vilket inte kan göras med hjälp av parameterverifiering. Med meddelandeverifiering kan du skapa valideringslogik i scheman, vilket ger mer flexibilitet och minskar utvecklingstiden. Scheman kan återanvändas i olika program i organisationen, vilket skapar standarder för datarepresentation. Dessutom kan du med meddelandeverifiering skydda åtgärder när de använder mer komplexa datatyper som omfattar kontrakt som representerar affärslogik.

För att utföra meddelandeverifiering skapar du först ett schema som representerar driften av tjänsten och de datatyper som används av dessa åtgärder. Sedan skapar du en .NET-klass som implementerar en anpassad klientmeddelandekontroll och en anpassad meddelandekontroll för avsändare för att verifiera de meddelanden som skickas/tas emot till/från tjänsten. Därefter implementerar du ett anpassat slutpunktsbeteende för att aktivera meddelandeverifiering på både klienten och tjänsten. Slutligen implementerar du ett anpassat konfigurationselement i klassen som gör att du kan exponera det utökade beteendet för anpassade slutpunkter i konfigurationsfilen för tjänsten eller klienten"

WCF – Validering av indata via parameterkontrollanter

Title Details
Komponent WCF
SDL-fas Skapa
Tillämpliga tekniker Generic, NET Framework 3
Attribut Ej tillämpligt
Referenser MSDN
Steg

Validering av indata och data representerar en viktig försvarslinje i skyddet av ditt WCF-program. Du bör verifiera alla parametrar som exponeras i WCF-tjänståtgärder för att skydda tjänsten från angrepp av en skadlig klient. Däremot bör du också verifiera alla returvärden som tas emot av klienten för att skydda klienten från angrepp av en skadlig tjänst

WCF tillhandahåller olika utökningspunkter som gör att du kan anpassa WCF-körningsbeteendet genom att skapa anpassade tillägg. Meddelandekontrollanter och parameterkontrollanter är två utökningsmekanismer som används för att få större kontroll över dataöverföringen mellan en klient och en tjänst. Du bör använda parameterkontrollanter för indataverifiering och endast använda meddelandekontrollanter när du behöver inspektera hela meddelandet som flödar in och ut ur en tjänst.

För att utföra indataverifiering skapar du en .NET-klass och implementerar en anpassad parameterkontroll för att verifiera parametrar för åtgärder i din tjänst. Sedan implementerar du ett anpassat slutpunktsbeteende för att aktivera validering på både klienten och tjänsten. Slutligen implementerar du ett anpassat konfigurationselement i klassen som gör att du kan exponera det utökade anpassade slutpunktsbeteendet i konfigurationsfilen för tjänsten eller klienten