Sdílet prostřednictvím


Bezpečnostní rámec: Ověření vstupu | Zmírnění rizik

Produkt/služba Článek
Webová aplikace
Databáze
Webové rozhraní API
Azure Document DB
WCF

Zakázání skriptování XSLT pro všechny transformace pomocí nedůvěryhodných šablon stylů

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy Zabezpečení XSLT, Xslt Nastavení. EnableScript – vlastnost
Kroky XSLT podporuje skriptování uvnitř šablon stylů pomocí elementu <msxml:script> . To umožňuje použití vlastních funkcí v transformaci XSLT. Skript se spustí v kontextu procesu provádějícího transformaci. Skript XSLT musí být zakázán v nedůvěryhodném prostředí, aby se zabránilo spuštění nedůvěryhodného kódu. Pokud používáte .NET: Skriptování XSLT je ve výchozím nastavení zakázané. Musíte ale zajistit, aby nebyla explicitně povolena prostřednictvím XsltSettings.EnableScript vlastnosti.

Příklad

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

Příklad

Pokud používáte MSXML 6.0, skriptování XSLT je ve výchozím nastavení zakázáno; je však nutné zajistit, aby nebyla explicitně povolena prostřednictvím vlastnosti objektu XML DOM AllowXsltScript.

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

Příklad

Pokud používáte MSXML 5 nebo novější, skriptování XSLT je ve výchozím nastavení povolené a musíte ho explicitně zakázat. Nastavte vlastnost objektu XML DOM AllowXsltScript na false.

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

Ujistěte se, že každá stránka, která může obsahovat obsah s možností ovládacího prvku uživatele, se odhlásí z automatického šifrování MIME.

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy IE8 Security Part V – komplexní ochrana
Kroky

Pro každou stránku, která by mohla obsahovat obsah s možností ovládání uživatele, musíte použít hlavičku X-Content-Type-Options:nosniffHTTP . Pokud chcete vyhovět tomuto požadavku, můžete buď nastavit požadovanou stránku záhlaví podle stránky jenom pro stránky, které můžou obsahovat uživatelsky ovladatelný obsah, nebo ji můžete nastavit globálně pro všechny stránky v aplikaci.

Každý typ souboru doručovaný z webového serveru má přidružený typ MIME (označovaný také jako typ obsahu), který popisuje povahu obsahu (tj. obrázek, text, aplikace atd.).

Hlavička X-Content-Type-Options je hlavička HTTP, která vývojářům umožňuje určit, že jejich obsah by neměl být zašifrován MIME. Tato hlavička je navržená tak, aby zmírnit útoky MIME-Sniffing. Podpora pro tuto hlavičku byla přidána v Internet Exploreru 8 (IE8)

Možnosti X-Content-Type-Options budou využívat jenom uživatelé aplikace Internet Explorer 8 (IE8). Předchozí verze aplikace Internet Explorer v současné době nerespektují hlavičku X-Content-Type-Options.

Internet Explorer 8 (a novější) jsou jedinými hlavními prohlížeči, které implementují funkci odhlášení pomocí mime-sniff. Pokud a kdy jiné hlavní prohlížeče (Firefox, Safari, Chrome) implementují podobné funkce, bude toto doporučení aktualizováno tak, aby zahrnovalo také syntaxi těchto prohlížečů.

Příklad

Pokud chcete povolit požadované záhlaví globálně pro všechny stránky v aplikaci, můžete udělat jednu z těchto věcí:

  • Pokud je aplikace hostovaná službou Internetová informační služba (IIS) 7, přidejte hlavičku do souboru web.config.
<system.webServer> 
  <httpProtocol> 
    <customHeaders> 
      <add name=""X-Content-Type-Options"" value=""nosniff""/>
    </customHeaders>
  </httpProtocol>
</system.webServer> 
  • Přidání záhlaví prostřednictvím globálního Application_BeginRequest
void Application_BeginRequest(object sender, EventArgs e)
{
  this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
} 
  • Implementace vlastního modulu HTTP
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""); 
      } 
  } 

  • Požadované záhlaví můžete povolit jenom pro konkrétní stránky tak, že ho přidáte do jednotlivých odpovědí:
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff""; 

Posílení nebo zakázání překladu entit XML

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy Rozšíření entit XML, útoky a obrana XML, přehled zabezpečení MSXML, osvědčené postupy pro zabezpečení kódu MSXML, NSXMLParserDelegate Protocol Reference, překlad externích odkazů
Kroky

I když se široce nepoužívá, existuje funkce XML, která umožňuje analyzátoru XML rozšířit entity maker s hodnotami definovanými buď v samotném dokumentu, nebo z externích zdrojů. Dokument může například definovat entitu "companyname" s hodnotou "Microsoft", aby se při každém zobrazení textu "&companyname; v dokumentu" automaticky nahradil textem Microsoft. Nebo dokument může definovat entitu MSFTStock, která odkazuje na externí webovou službu a načte aktuální hodnotu akcií Microsoftu.

Poté, co se v dokumentu zobrazí "&MSFTStock;", se automaticky nahradí aktuální cenou akcií. Tato funkce však může být zneužita k vytvoření podmínek odepření služby (DoS). Útočník může vnořit více entit a vytvořit exponenciální expanzní bombu XML, která spotřebovává veškerou dostupnou paměť v systému.

Alternativně může vytvořit externí odkaz, který streamuje nekonečné množství dat nebo jednoduše zablokuje vlákno. V důsledku toho musí všechny týmy zcela zakázat interní nebo externí překlad entit XML, pokud ji jejich aplikace nepoužívá, nebo ručně omezit množství paměti a času, které může aplikace využívat pro překlad entit, pokud je tato funkce naprosto nezbytná. Pokud vaše aplikace nevyžaduje překlad entit, zakažte ho.

Příklad

Pro kód rozhraní .NET Framework můžete použít následující přístupy:

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

Všimněte si, že výchozí hodnota ProhibitDtd in XmlReaderSettings je true, ale v XmlTextReader ní je false. Pokud používáte XmlReader Nastavení, nemusíte explicitně nastavit ZákazDtd na true, ale doporučuje se pro bezpečnost, že to uděláte. Všimněte si také, že XmlDocument třída umožňuje rozlišení entit ve výchozím nastavení.

Příklad

Chcete-li zakázat rozlišení entity pro XmlDocuments, použijte XmlDocument.Load(XmlReader) přetížení Load metody a nastavte příslušné vlastnosti v argumentu XmlReader zakázat rozlišení, jak je znázorněno v následujícím kódu:

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

Příklad

Pokud pro vaši aplikaci není možné zakázat překlad entit, nastavte XmlReader Nastavení. Vlastnost MaxCharactersFromEntities na přiměřenou hodnotu podle potřeb vaší aplikace. Tím omezíte dopad potenciálních útoků doS exponenciálního rozšíření. Následující kód poskytuje příklad tohoto přístupu:

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

Příklad

Pokud potřebujete přeložit vložené entity, ale nepotřebujete překládat externí entity, nastavte XmlReader Nastavení. XmlResolver vlastnost null. Příklad:

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

Všimněte si, že v MSXML6 je ZakázánoDTD ve výchozím nastavení nastaveno na true (zakázání zpracování DTD). Pro kód Apple OSX/iOS můžete použít dva analyzátory XML: NSXMLParser a libXML2.

Aplikace využívající http.sys provádějí ověřování kanonizace adresy URL

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy
Kroky

Každá aplikace, která používá http.sys, by měla postupovat podle těchto pokynů:

  • Omezte délku adresy URL na maximálně 16 384 znaků (ASCII nebo Unicode). Toto je absolutní maximální délka adresy URL na základě výchozího nastavení Internetová informační služba (IIS) 6. Pokud je to možné, měly by weby usilovat o delší délku, než je to možné
  • Použijte standardní třídy vstupně-výstupních operací souboru rozhraní .NET Framework (například FileStream), protože tyto třídy budou využívat pravidla kanonizace v .NET FX.
  • Explicitně sestavte seznam povolených názvů souborů.
  • Explicitně odmítnout známé typy souborů, které nebudete obsluhovat UrlScan rejects: exe, bat, cmd, com, htw, ida, idq, htr, idc, shtm[l], stm, printer, ini, pol, dat soubory
  • Zachyťte následující výjimky:
    • System.ArgumentException (pro názvy zařízení)
    • System.NotSupportedException (pro datové proudy)
    • System.IO.FileNotFoundException (pro neplatné řídicí názvy souborů)
    • System.IO.DirectoryNotFoundException (pro neplatné řídicí diry)
  • Neozvájejte rozhraní API pro vstupně-výstupní operace souboru Win32. Na neplatné adrese URL řádně vrátí uživateli chybu 400 a zapíše skutečnou chybu.

Ujistěte se, že jsou při přijímání souborů od uživatelů zavedeny příslušné ovládací prvky.

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy Neomezené nahrávání souborů, tabulka podpisů souborů
Kroky

Nahrané soubory představují významné riziko pro aplikace.

Prvním krokem v mnoha útocích je získání kódu do systému, který se má napadnout. Útok pak potřebuje najít způsob, jak kód spustit. Použití nahrání souboru pomáhá útočníkovi provést první krok. Důsledky neomezeného nahrávání souborů se mohou lišit, včetně kompletního převzetí systému, přetíženého systému souborů nebo databáze, přesměrování útoků na back-endové systémy a jednoduchého odstranění identity.

Záleží na tom, co aplikace dělá s nahraným souborem a hlavně na tom, kde je uložená. Chybí ověření na straně serveru pro nahrávání souborů. Pro funkci nahrávání souborů by se měly implementovat následující bezpečnostní prvky:

  • Kontrola přípony souboru (je třeba přijmout pouze platnou sadu povolených typů souborů)
  • Maximální limit velikosti souboru
  • Soubor by se neměl nahrávat do webroot; umístění by mělo být adresář na nesystémové jednotce.
  • Je třeba dodržovat zásady vytváření názvů, aby název nahraného souboru měl určitou náhodnost, aby se zabránilo přepsání souboru.
  • Soubory by se měly před zápisem na disk zkontrolovat proti virům.
  • Ujistěte se, že název souboru a všechna další metadata (např. cesta k souboru) jsou ověřená pro škodlivé znaky.
  • Je třeba zkontrolovat podpis formátu souboru, aby uživatel nemohl nahrát maskovaný soubor (např. nahrání souboru exe změnou přípony na txt).

Příklad

Poslední bod týkající se ověření podpisu formátu souboru najdete v následující třídě, kde najdete podrobnosti:

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

Ujistěte se, že jsou parametry bezpečné pro typ používané ve webové aplikaci pro přístup k datům.

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy
Kroky

Pokud používáte kolekci Parameters, SQL považuje vstup za hodnotu literálu, nikoli jako spustitelný kód. Kolekci Parameters lze použít k vynucení omezení typu a délky vstupních dat. Hodnoty mimo rozsah aktivují výjimku. Pokud se nepoužívají parametry SQL bezpečného typu, útočníci můžou spouštět útoky prostřednictvím injektáže, které jsou vložené do nefiltrovaného vstupu.

Při vytváření dotazů SQL použijte bezpečné parametry typu, abyste se vyhnuli možným útokům prostřednictvím injektáže SQL, ke kterým může dojít u nefiltrovaného vstupu. S uloženými procedurami a s dynamickými příkazy SQL můžete použít bezpečné parametry typu. Parametry jsou považovány za hodnoty literálů databáze a ne jako spustitelný kód. Parametry se také kontrolují pro typ a délku.

Příklad

Následující kód ukazuje, jak použít typ bezpečných parametrů s SqlParameterCollection při volání uložené procedury.

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

V předchozím příkladu kódu nemůže být vstupní hodnota delší než 11 znaků. Pokud data neodpovídají typu nebo délce definované parametrem, třída SqlParameter vyvolá výjimku.

Použití samostatných tříd vazeb modelu nebo seznamů filtrů vazeb k zabránění ohrožení zabezpečení hromadného přiřazení MVC

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie MVC5, MVC6
Atributy
Odkazy Atributy metadat, ohrožení zabezpečení veřejného klíče a omezení rizik, kompletní průvodce hromadným přiřazením v ASP.NET MVC, začínáme s EF pomocí MVC
Kroky
  • Kdy mám hledat ohrožení zabezpečení před publikováním? - K nadměrnému publikování ohrožení zabezpečení může dojít na libovolném místě, kde vytvoříte vazbu tříd modelu ze vstupu uživatele. Architektury, jako je MVC, můžou představovat uživatelská data ve vlastních třídách .NET, včetně objektů POCO (Plain Old ClR Objects). MVC tyto třídy modelu automaticky naplní daty z požadavku a poskytuje pohodlné vyjádření pro práci se vstupem uživatele. Pokud tyto třídy zahrnují vlastnosti, které by neměly být nastaveny uživatelem, může být aplikace ohrožena útoky nadměrného publikování, které uživateli umožňují kontrolu nad daty, která aplikace nikdy nezamýšlela. Podobně jako vazby modelu MVC podporují technologie přístupu k databázím, jako jsou objekty nebo relační mapovače, jako je Entity Framework, často také použití objektů POCO k reprezentaci databázových dat. Tyto třídy datového modelu poskytují stejné pohodlí při práci s databázovými daty jako MVC při práci se vstupem uživatele. Vzhledem k tomu, že MVC i databáze podporují podobné modely, jako jsou objekty POCO, zdá se snadné znovu použít stejné třídy pro oba účely. Tento postup nedokáže zachovat oddělení obav a je to jedna společná oblast, ve které jsou nechtěné vlastnosti vystaveny vazbě modelu, což umožňuje útoky nadměrného publikování.
  • Proč bych neměl jako parametry pro akce MVC používat nefiltrované třídy modelu databáze? - Vzhledem k tomu, že vazba modelu MVC bude svázat cokoli v této třídě. I když se data ve vašem zobrazení nezobrazují, může škodlivý uživatel odeslat požadavek HTTP s daty, která obsahuje, a MVC je rád sváže, protože vaše akce říká, že databázová třída je tvarem dat, která by měla přijmout pro uživatelský vstup.
  • Proč bych se měl starat o tvar použitý pro vazbu modelu? - Použití ASP.NET vazby modelu MVC s příliš rozsáhlými modely zveřejňuje aplikaci pro nadměrné publikování útoků. Nadměrné účtování může útočníkům umožnit, aby změnili data aplikace nad rámec toho, co vývojář chtěl, například přepsání ceny položky nebo oprávnění zabezpečení pro účet. Aplikace by měly používat modely vazeb specifické pro akce (nebo seznamy konkrétních povolených filtrů vlastností) k poskytnutí explicitního kontraktu pro to, co nedůvěryhodný vstup umožňuje prostřednictvím vazby modelu.
  • Mají samostatné modely vazeb jenom duplikující kód? - Ne, jde o oddělení obav. Pokud opakovaně používáte databázové modely v metodách akcí, říkáte, že jakákoli vlastnost (nebo dílčí vlastnost) v této třídě může uživatel nastavit v požadavku HTTP. Pokud to není to, co chcete, aby MVC dělal, potřebujete seznam filtrů nebo samostatný obrazec třídy, abyste místo toho zobrazili MVC, jaká data mohou pocházet ze vstupu uživatele.
  • Pokud mám samostatné modely vazeb pro uživatelský vstup, musím duplikovat všechny atributy datových poznámek? - Ne nutně. MetadataTypeAttribute ve třídě modelu databáze můžete použít k propojení s metadaty třídy vazby modelu. Stačí poznamenat, že typ odkazovaný metadataTypeAttribute musí být podmnožinou odkazujícího typu (může mít méně vlastností, ale ne více).
  • Přesouvání dat mezi uživatelskými vstupními modely a databázovými modely je zdlouhavé. Můžu jednoduše kopírovat všechny vlastnosti pomocí reflexe? - Ano. Jedinými vlastnostmi, které se zobrazují v modelech vazeb, jsou ty, které jste určili jako bezpečné pro uživatelský vstup. Neexistuje žádný důvod zabezpečení, který brání použití reflexe ke kopírování všech vlastností, které existují společné mezi těmito dvěma modely.
  • Co [Bind(Exclude ="â€")]. Můžu použít místo samostatných vazebních modelů? - Tento přístup se nedoporučuje. Použití funkce [Bind(Exclude ="â€")] znamená, že jakákoli nová vlastnost je ve výchozím nastavení svázatelná. Když se přidá nová vlastnost, je potřeba si pamatovat další krok, který si pamatuje, aby byly věci zabezpečené, a ne aby návrh byl ve výchozím nastavení zabezpečený. V závislosti na vývojáři, který tento seznam kontroluje při každém přidání vlastnosti, je rizikové.
  • Je [Bind(Include ="â€")] užitečné pro operace úprav? - Ne. [Bind(Include ="â€")] je vhodný pouze pro operace ve stylu INSERT (přidání nových dat). V případě operací ve stylu UPDATE (revize existujících dat) použijte jiný přístup, například použití samostatných vazeb modelů nebo předání explicitního seznamu povolených vlastností updateModel nebo TryUpdateModel. Přidání atributu [Bind(Include ="â€")] u operace úpravy znamená, že MVC vytvoří instanci objektu a nastaví pouze uvedené vlastnosti, přičemž ostatní zůstanou ve svých výchozích hodnotách. Když jsou data trvalá, zcela nahradí existující entitu a resetuje hodnoty pro všechny vynechané vlastnosti na výchozí hodnoty. Pokud by byl například atribut Is Správa vynechán z atributu [Bind(Include ="â€")], jakýkoli uživatel, jehož jméno bylo upraveno touto akcí, by se resetoval na Hodnotu Is Správa = false (jakýkoli upravený uživatel ztratí stav správce). Pokud chcete zabránit aktualizacím určitých vlastností, použijte jeden z dalších přístupů výše. Všimněte si, že některé verze nástrojů MVC generují třídy kontroleru s možností [Bind(Include ="â€")] u akcí úprav a naznačují, že odebrání vlastnosti z tohoto seznamu zabrání útokům, které by se přeúčtováním zabránily. Jak je však popsáno výše, tento přístup nefunguje tak, jak má, a místo toho resetuje všechna data v vynechaných vlastnostech na výchozí hodnoty.
  • V případě operací vytvoření existují nějaké upozornění, které místo samostatných vazeb používají [Bind(Include ="â€")]? - Ano. Nejprve tento přístup nefunguje pro scénáře úprav, což vyžaduje zachování dvou samostatných přístupů pro zmírnění všech ohrožení zabezpečení při nadměrném účtování. Za druhé, samostatné modely vazby vynucují oddělení obav mezi obrazcem používaným pro uživatelský vstup a obrazec používaným pro trvalost, něco [Bind(Include ="â€")] neprovádí. Za třetí si všimněte, že [Bind(Include ="â€")] dokáže zpracovat pouze vlastnosti nejvyšší úrovně; v atributu nelze povolit pouze části dílčích vlastností (například "Details.Name"). Nakonec a možná nejdůležitější je, že pomocí funkce [Bind(Include ="â€")] přidáte další krok, který se musí pamatovat při každém použití třídy pro vazbu modelu. Pokud se nová metoda akce sváže přímo s datovou třídou a zapomene zahrnout atribut [Bind(Include ="â€")], může být ve výchozím nastavení zranitelná vůči útokům přeúčtování, takže přístup [Bind(Include ="â€")] je ve výchozím nastavení poněkud méně zabezpečený. Pokud použijete [Bind(Include ="â€"),], nezapomeňte je vždy pamatovat na to, abyste ho při každém zobrazení datových tříd použili jako parametry metody akce.
  • V případě operací vytvoření, co vložení atributu [Bind(Include ="â€")] do samotné třídy modelu? Nevyhýbá se tento přístup nutnosti pamatovat si atribut na každou metodu akce? - Tento přístup funguje v některých případech. Použití metody [Bind(Include ="â€")] u samotného typu modelu (místo parametrů akce používajících tuto třídu) není nutné při každé metodě akce pamatovat na zahrnutí atributu [Bind(Include ="â€")]. Použití atributu přímo ve třídě efektivně vytvoří samostatnou plochu této třídy pro účely vazby modelu. Tento přístup ale umožňuje pouze jeden obrazec vazby modelu na třídu modelu. Pokud jedna metoda akce potřebuje povolit vazbu modelu pole (například akce pouze správce, která aktualizuje role uživatelů) a další akce musí zabránit vazbě modelu tohoto pole, nebude tento přístup fungovat. Každá třída může mít pouze jeden obrazec vazby modelu; pokud různé akce potřebují různé obrazce vazby modelu, musí tyto samostatné obrazce znázorňovat buď pomocí samostatných tříd vazby modelu, nebo samostatných atributů [Bind(Include ="â€}")] v metodách akce.
  • Co jsou modely vazeb? Jsou stejné jako modely zobrazení? - Jedná se o dva související koncepty. Model vazby termínů odkazuje na třídu modelu použitou v seznamu parametrů akce (obrazec předaný z vazby modelu MVC do metody akce). Model zobrazení termínů odkazuje na třídu modelu předanou z metody akce do zobrazení. Použití modelu specifického pro zobrazení je běžný přístup k předávání dat z metody akce do zobrazení. Tento obrazec je často vhodný také pro vazbu modelu a model zobrazení termínů lze použít k odkazování stejného modelu použitého na obou místech. Abychom mohli být přesný, tento postup hovoří konkrétně o vazbových modelech a zaměřuje se na tvar předaný akci, což je důležité pro účely hromadného přiřazení.

Kódování nedůvěryhodného webového výstupu před vykreslováním

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecné, Webové formuláře, MVC5, MVC6
Atributy
Odkazy Jak zabránit skriptování mezi weby v ASP.NET, skriptování mezi weby, XSS (skriptování mezi weby) Prevence
Kroky Skriptování mezi weby (obvykle zkrácené jako XSS) je vektor útoku pro online služby nebo jakoukoli aplikaci nebo komponentu, která využívá vstup z webu. Ohrožení zabezpečení XSS může útočníkovi umožnit spuštění skriptu na počítači jiného uživatele prostřednictvím zranitelné webové aplikace. Škodlivé skripty lze použít ke krádeži souborů cookie a jinak manipulaci s počítačem oběti prostřednictvím JavaScriptu. XSS je znemožněno ověřením vstupu uživatele, aby byl správně formátován a kódován předtím, než se vykresluje na webové stránce. Ověření vstupu a kódování výstupu lze provést pomocí knihovny Web Protection. Pro spravovaný kód (C#, VB.NET atd.) použijte jednu nebo více vhodných metod kódování z knihovny Web Protection (Anti-XSS) v závislosti na kontextu, ve kterém se uživatelský vstup manifestuje:

Příklad

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

Proveďte ověření vstupu a filtrování pro všechny vlastnosti modelu typu řetězce.

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecné, MVC5, MVC6
Atributy
Odkazy Přidání ověřování, ověřování dat modelu v aplikaci MVC, principy guid pro aplikace ASP.NET MVC
Kroky

Před použitím v aplikaci musí být všechny vstupní parametry ověřeny, aby se zajistilo, že aplikace bude chráněna před škodlivými vstupy uživatelů. Ověřte vstupní hodnoty pomocí ověřování regulárních výrazů na straně serveru se strategií ověřování seznamu povolených. Nesanitizované uživatelské vstupy / parametry předané metodám mohou způsobit ohrožení zabezpečení injektáže kódu.

U webových aplikací můžou vstupní body obsahovat také pole formulářů, řetězec dotazu, soubory cookie, hlavičky HTTP a parametry webové služby.

Při vazbě modelu musí být provedeny následující kontroly ověření vstupu:

  • Vlastnosti modelu by měly být opatřeny poznámkami RegularExpression pro příjem povolených znaků a maximální přípustné délky.
  • Metody kontroleru by měly provádět platnost ModeluState.

Sanitizace by se měla použít u polí formuláře, která přijímají všechny znaky, například editor formátovaného textu.

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy Kódování nebezpečného vstupu, sanitizátor HTML
Kroky

Identifikujte všechny značky statických značek, které chcete použít. Běžným postupem je omezit formátování na bezpečné elementy HTML, jako <b> jsou (tučné písmo) a <i> kurzíva.

Před zápisem dat je html kódujte. Díky tomu je jakýkoli škodlivý skript bezpečný tím, že ho zpracujete jako text, ne jako spustitelný kód.

  1. Zakažte ověření požadavku ASP.NET přidáním atributu ValidateRequest="false" do direktivy @ Page.
  2. Kódování vstupu řetězce metodou HtmlEncode
  3. Použití StringBuilder a volání metody Replace k selektivní odebrání kódování u elementů HTML, které chcete povolit

Stránka v odkazech zakáže ověření požadavku ASP.NET nastavením ValidateRequest="false". Kóduje vstup a selektivně umožňuje <b> také <i> knihovnu .NET pro sanitizaci HTML.

HtmlSanitizer je knihovna .NET pro čištění fragmentů HTML a dokumentů z konstruktorů, které můžou vést k útokům XSS. Používá AngleSharp k analýze, manipulaci a vykreslení HTML a CSS. HtmlSanitizer lze nainstalovat jako balíček NuGet a uživatelský vstup lze předat prostřednictvím příslušných metod sanitizace HTML nebo CSS, jak je to možné, na straně serveru. Upozorňujeme, že sanitizace jako bezpečnostní prvek by měla být považována za poslední možnost.

Ověření vstupu a kódování výstupu se považují za lepší bezpečnostní prvky.

Nepřiřazovat elementy DOM k jímkách, které nemají sestavené kódování

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy
Kroky Mnoho javascriptových funkcí ve výchozím nastavení kódování nedělá. Při přiřazování nedůvěryhodného vstupu k prvkům DOM prostřednictvím těchto funkcí může dojít k provádění skriptů mezi weby (XSS).

Příklad

Tady jsou nezabezpečené příklady:

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

Nepoužívejte innerHtml; místo toho použijte innerText. Podobně místo $("#elm").html()použití $("#elm").text()

Ověřte, že jsou všechna přesměrování v aplikaci zavřená nebo se bezpečně provádějí.

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy Autorizační architektura OAuth 2.0 – otevřené přesměrovače
Kroky

Návrh aplikace vyžadující přesměrování do uživatelem zadaného umístění musí omezit možné cíle přesměrování na předdefinovaný "bezpečný" seznam lokalit nebo domén. Všechna přesměrování v aplikaci musí být uzavřena/bezpečná.

Akce:

  • Identifikace všech přesměrování
  • Implementujte vhodné zmírnění rizik pro každé přesměrování. Mezi vhodná omezení rizik patří seznam povolených přesměrování nebo potvrzení uživatele. Pokud web nebo služba s ohrožením zabezpečení otevřeného přesměrování používá zprostředkovatele identity Facebook/OAuth/OpenID, může útočník ukrást přihlašovací token uživatele a zosobnit tohoto uživatele. Toto je základní riziko při použití OAuth, které je zdokumentované v DOKUMENTU RFC 6749 "The OAuth 2.0 Authorization Framework", oddíl 10.15 "Open Redirects" podobně, přihlašovací údaje uživatelů mohou být ohroženy spear phishing útoky pomocí otevřených přesměrování.

Implementace ověřování vstupu u všech parametrů typu řetězce přijatých metodami kontroleru

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecné, MVC5, MVC6
Atributy
Odkazy Ověřování dat modelu v aplikaci MVC s hlavními principy pro aplikace ASP.NET MVC
Kroky Pro metody, které pouze přijímají primitivní datový typ, a ne modely jako argument, je třeba provést ověřování vstupu pomocí regulárního výrazu. Tady by se měl použít regulární výraz Regex.IsMatch s platným vzorem regulárního výrazu. Pokud vstup neodpovídá zadanému regulárnímu výrazu, neměl by ovládací prvek pokračovat dál a mělo by se zobrazit odpovídající upozornění týkající se selhání ověření.

Nastavení časového limitu horního limitu pro zpracování regulárních výrazů, aby se zabránilo doS kvůli špatným regulárním výrazům

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie Obecné, Webové formuláře, MVC5, MVC6
Atributy
Odkazy DefaultRegexMatchTimeout – vlastnost
Kroky Pokud chcete zajistit útoky na dostupnost služby proti nesprávně vytvořeným regulárním výrazům, které způsobují velké množství zpětného navracení, nastavte globální výchozí časový limit. Pokud doba zpracování trvá déle, než je definovaný horní limit, vyvolá se výjimka časového limitu. Pokud se nic nekonfiguruje, časový limit by byl nekonečný.

Příklad

Například následující konfigurace vyvolá výjimku RegexMatchTimeoutException, pokud zpracování trvá déle než 5 sekund:

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

Nepoužívejte Html.Raw v zobrazeních Razor

Nadpis Detaily
Součást Webová aplikace
Fáze SDL Sestavit
Použitelné technologie MVC5, MVC6
Atributy
Odkazy
Krok ASP.NET WebPages (Razor) provádí automatické kódování HTML. Všechny řetězce vytištěné vloženými nuggety kódu (@ bloky) se automaticky zakódují ve formátu HTML. Při HtmlHelper.Raw vyvolání metody však vrátí kód, který není kódován HTML. Pokud Html.Raw() se používá pomocná metoda, obchází automatickou ochranu kódování, kterou Razor poskytuje.

Příklad

Následuje nezabezpečený příklad:

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

Nepoužívejte Html.Raw() , pokud nepotřebujete zobrazit revize. Tato metoda neprovádí implicitní kódování výstupu. Použití jiných pomocných rutin ASP.NET, např. @Html.DisplayFor()

Nepoužívejte dynamické dotazy v uložených procedurách.

Nadpis Detaily
Součást Databáze
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy
Kroky

Útok prostřednictvím injektáže SQL využívá chyby zabezpečení při ověřování vstupu ke spuštění libovolných příkazů v databázi. Může k tomu dojít, když vaše aplikace použije vstup k vytvoření dynamických příkazů SQL pro přístup k databázi. Může k tomu dojít také v případě, že váš kód používá uložené procedury, které jsou předány řetězce, které obsahují nezpracovaný uživatelský vstup. Pomocí útoku prostřednictvím injektáže SQL může útočník v databázi spustit libovolné příkazy. Všechny příkazy SQL (včetně příkazů SQL v uložených procedurách) musí být parametrizovány. Parametrizované příkazy SQL přijímají znaky, které mají speciální význam pro SQL (například jednoduché uvozovky) bez problémů, protože jsou silně napsané.

Příklad

Následuje příklad nezabezpečené dynamické uložené procedury:

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

Příklad

Následuje stejná uložená procedura, která je bezpečně implementována:

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

Ujistěte se, že ověřování modelu probíhá u metod webového rozhraní API.

Nadpis Detaily
Součást Webové rozhraní API
Fáze SDL Sestavit
Použitelné technologie MVC5, MVC6
Atributy
Odkazy Ověření modelu ve webovém rozhraní API ASP.NET
Kroky Když klient odesílá data do webového rozhraní API, je nutné data před zpracováním ověřit. Pro ASP.NET webová rozhraní API, která přijímají modely jako vstup, použijte datové poznámky na modelech k nastavení ověřovacích pravidel pro vlastnosti modelu.

Příklad

Stejný kód ukazuje následující kód:

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

Příklad

V metodě akce kontrolerů rozhraní API musí být platnost modelu explicitně zkontrolována, jak je znázorněno níže:

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

Implementace ověřování vstupu pro všechny parametry typu řetězce přijaté metodami webového rozhraní API

Nadpis Detaily
Součást Webové rozhraní API
Fáze SDL Sestavit
Použitelné technologie Obecné, MVC 5, MVC 6
Atributy
Odkazy Ověřování dat modelu v aplikaci MVC s hlavními principy pro aplikace ASP.NET MVC
Kroky Pro metody, které pouze přijímají primitivní datový typ, a ne modely jako argument, je třeba provést ověřování vstupu pomocí regulárního výrazu. Tady by se měl použít regulární výraz Regex.IsMatch s platným vzorem regulárního výrazu. Pokud vstup neodpovídá zadanému regulárnímu výrazu, neměl by ovládací prvek pokračovat dál a mělo by se zobrazit odpovídající upozornění týkající se selhání ověření.

Ujistěte se, že se pro přístup k datům používají parametry bezpečného typu ve webovém rozhraní API.

Nadpis Detaily
Součást Webové rozhraní API
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy
Kroky

Pokud používáte kolekci Parameters, SQL považuje vstup za hodnotu literálu, nikoli jako spustitelný kód. Kolekci Parameters lze použít k vynucení omezení typu a délky vstupních dat. Hodnoty mimo rozsah aktivují výjimku. Pokud se nepoužívají parametry SQL bezpečného typu, útočníci můžou spouštět útoky prostřednictvím injektáže, které jsou vložené do nefiltrovaného vstupu.

Při vytváření dotazů SQL použijte bezpečné parametry typu, abyste se vyhnuli možným útokům prostřednictvím injektáže SQL, ke kterým může dojít u nefiltrovaného vstupu. S uloženými procedurami a s dynamickými příkazy SQL můžete použít bezpečné parametry typu. Parametry jsou považovány za hodnoty literálů databáze a ne jako spustitelný kód. Parametry se také kontrolují pro typ a délku.

Příklad

Následující kód ukazuje, jak použít typ bezpečných parametrů s SqlParameterCollection při volání uložené procedury.

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

V předchozím příkladu kódu nemůže být vstupní hodnota delší než 11 znaků. Pokud data neodpovídají typu nebo délce definované parametrem, třída SqlParameter vyvolá výjimku.

Použití parametrizovaných dotazů SQL pro službu Azure Cosmos DB

Nadpis Detaily
Součást Azure Document DB
Fáze SDL Sestavit
Použitelné technologie Obecná
Atributy
Odkazy Oznámení o parametrizaci SQL ve službě Azure Cosmos DB
Kroky I když Azure Cosmos DB podporuje pouze dotazy jen pro čtení, injektáž SQL je stále možná, pokud jsou dotazy vytvořené zřetězením s uživatelským vstupem. Může být možné, že uživatel získá přístup k datům, ke kterým by neměl mít přístup ve stejné kolekci, tím, že vytvoří škodlivé dotazy SQL. Pokud jsou dotazy vytvořené na základě uživatelského vstupu, použijte parametrizované dotazy SQL.

Ověřování vstupu WCF prostřednictvím vazby schématu

Nadpis Detaily
Součást WCF
Fáze SDL Sestavit
Použitelné technologie Obecné, NET Framework 3
Atributy
Odkazy MSDN
Kroky

Nedostatek ověření vede k různým útokům prostřednictvím injektáže typu.

Ověřování zpráv představuje jeden řádek obrany v ochraně vaší aplikace WCF. Pomocí tohoto přístupu ověříte zprávy pomocí schémat k ochraně operací služby WCF před útokem škodlivého klienta. Ověřte všechny zprávy přijaté klientem a chraňte klienta před útokem škodlivou službou. Ověření zpráv umožňuje ověřit zprávy, když operace spotřebovávají kontrakty zpráv nebo datové kontrakty, které nelze provést pomocí ověření parametru. Ověřování zpráv umožňuje vytvářet logiku ověřování uvnitř schémat, což poskytuje větší flexibilitu a zkracuje dobu vývoje. Schémata je možné opakovaně používat v různých aplikacích v organizaci a vytvářet standardy pro reprezentaci dat. Kromě toho ověřování zpráv umožňuje chránit operace, když spotřebovávají složitější datové typy zahrnující kontrakty představující obchodní logiku.

Pokud chcete provést ověření zpráv, nejprve vytvoříte schéma, které představuje operace vaší služby a datové typy využívané těmito operacemi. Pak vytvoříte třídu .NET, která implementuje vlastní kontrolu zpráv klienta a vlastního inspektoru zpráv dispečera k ověření odeslaných a přijatých zpráv ze služby. Dále implementujete vlastní chování koncového bodu, které povolí ověřování zpráv v klientovi i službě. Nakonec implementujete vlastní konfigurační element třídy, který umožňuje zveřejnit rozšířené chování vlastního koncového bodu v konfiguračním souboru služby nebo klienta"

WCF – Ověřování vstupu prostřednictvím inspektorů parametrů

Nadpis Detaily
Součást WCF
Fáze SDL Sestavit
Použitelné technologie Obecné, NET Framework 3
Atributy
Odkazy MSDN
Kroky

Ověřování vstupu a dat představuje jednu důležitou linii ochrany v ochraně vaší aplikace WCF. Měli byste ověřit všechny parametry zveřejněné v operacích služby WCF, abyste ochránili službu před útokem škodlivého klienta. Naopak byste měli ověřit všechny návratové hodnoty přijaté klientem, abyste ochránili klienta před útoky škodlivou službou.

WCF poskytuje různé body rozšiřitelnosti, které umožňují přizpůsobit chování modulu runtime WCF vytvořením vlastních rozšíření. Kontroly zpráv a inspektory parametrů jsou dva mechanismy rozšiřitelnosti, které slouží k získání větší kontroly nad daty předávajícími mezi klientem a službou. Kontroly parametrů byste měli použít pro ověřování vstupu a používat kontroly zpráv pouze v případě, že potřebujete zkontrolovat celý tok zpráv do služby a mimo službu.

K ověření vstupu vytvoříte třídu .NET a implementujete vlastní inspektor parametrů, abyste ověřili parametry operací ve vaší službě. Pak implementujete vlastní chování koncového bodu, abyste povolili ověřování v klientovi i službě. Nakonec implementujete vlastní konfigurační prvek třídy, který umožňuje zveřejnit rozšířené chování vlastního koncového bodu v konfiguračním souboru služby nebo klienta.