Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Při práci s daty ve Službě Windows Communication Foundation (WCF) musíte zvážit řadu kategorií hrozeb. Následující seznam ukazuje nejdůležitější třídy hrozeb, které souvisejí se zpracováním dat. WCF poskytuje nástroje pro zmírnění těchto hrozeb.
Odepření služby
Při příjmu nedůvěryhodných dat mohou tato data způsobit, že přijímající strana přistupuje k nepřiměřeně velkému množství různých prostředků, jako jsou paměť, vlákna, dostupná připojení nebo cykly procesoru, což způsobí zdlouhavé výpočty. Útok typu odepření služby na server může způsobit jeho chybové ukončení a ten pak nebude moci zpracovávat zprávy od jiných, legitimních klientů.
Spuštění škodlivého kódu
Příchozí nedůvěryhodná data způsobí, že přijímající strana spustí kód, který neměl v úmyslu.
Zpřístupnění informací
Vzdálený útočník vynutí přijímající stranu reagovat na své žádosti takovým způsobem, aby zveřejnil více informací, než chce.
User-Provided Kód a zabezpečení přístupu ke kódu
Řada míst v infrastruktuře Wcf (Windows Communication Foundation) spouští kód, který poskytuje uživatel. Například může modul pro serializaci DataContractSerializer volat uživatelsky definované přístupové funkce set a přístupové funkce get. Infrastruktura kanálu WCF může také volat uživatelské odvozené třídy z Message.
Autor kódu zodpovídá za to, aby se zajistilo, že neexistují žádná ohrožení zabezpečení. Pokud například vytvoříte typ datového kontraktu s vlastností datového člena typu integer a v set implementaci přístupového objektu přidělíte pole na základě hodnoty vlastnosti, zpřístupníte možnost útoku do služby, pokud škodlivá zpráva obsahuje extrémně velkou hodnotu pro tohoto datového člena. Obecně se vyhněte přidělení na základě příchozích dat nebo zdlouhavého zpracování v uživatelském kódu (zejména v případě, že může být zdlouhavé zpracování způsobeno malým množstvím příchozích dat). Při analýze zabezpečení uživatelského kódu nezapomeňte vzít v úvahu také všechny případy selhání (to znamená všechny větve kódu, ve kterých jsou vyvolány výjimky).
Konečným příkladem uživatelem poskytnutého kódu je kód uvnitř vaší implementace služby pro každou operaci. Zabezpečení implementace služby je vaší zodpovědností. Je snadné nechtěně vytvořit nezabezpečené implementace operací, které mohou vést k zranitelnostem vedoucím ke stavu odepření služby. Například operace, která přebírá řetězec a vrací seznam zákazníků z databáze, jejíž název začíná tímto řetězcem. Pokud pracujete s velkou databází a předávaný řetězec je jen jedno písmeno, může se váš kód pokusit vytvořit zprávu větší než veškerá dostupná paměť, což způsobí selhání celé služby. (Položka OutOfMemoryException v rozhraní .NET Framework není obnovitelná a vždy vede k ukončení vaší aplikace.)
Měli byste zajistit, aby do různých bodů rozšiřitelnosti nebyl zapojen žádný škodlivý kód. To je zvlášť důležité, když běží pod částečným vztahem důvěryhodnosti, pracuje s typy z částečně důvěryhodných sestavení nebo vytváří součásti použitelné částečně důvěryhodným kódem. Další informace najdete v části "Částečné hrozby důvěryhodnosti" v další části.
Všimněte si, že při spuštění v částečné důvěryhodnosti podporuje infrastruktura serializace kontraktů dat pouze omezenou podmnožinu programovacího modelu kontraktu dat – například soukromé datové členy nebo typy používající SerializableAttribute atribut nejsou podporovány. Další informace naleznete v tématu Částečná důvěryhodnost.
Poznámka:
Zabezpečení přístupu kódu (CAS) je zastaralé ve všech verzích rozhraní .NET Framework a .NET. Nedávné verze .NET nezohledňují anotace CAS a způsobují chyby, pokud se používají API související s CAS. Vývojáři by měli hledat alternativní způsoby provádění úloh zabezpečení.
Zabránění neúmyslnému zpřístupnění informací
Při navrhování serializovatelných typů s ohledem na bezpečnost je možné riziko úniku informací.
Vezměte v úvahu následující body:
DataContractSerializer Programovací model umožňuje vystavení privátních a interních dat mimo typ nebo sestavení během serializace. Kromě toho lze během exportu schématu vystavit tvar typu. Nezapomeňte porozumět projekci serializace vašeho typu. Pokud nechcete nic vystavit, zakažte jeho serializaci (například tím, že nepoužijete atribut DataMemberAttribute v případě datového kontraktu).
Mějte na paměti, že stejný typ může mít více projekcí serializace v závislosti na použitém serializátoru. Stejný typ může zveřejnit jednu sadu dat při použití s DataContractSerializer a jinou sadou dat při použití s XmlSerializer. Náhodné použití nesprávného serializátoru může vést ke zpřístupnění informací.
Použití XmlSerializer ve starším režimu vzdáleného volání procedur (RPC) / kódovaném režimu může neúmyslně odhalit strukturu grafu objektů ze strany odesílatele na stranu příjemce.
Zabránění útokům na dostupnost služby
Kvóty
Způsobení toho, že přijímající strana musí přidělit značné množství paměti, je potenciální útok typu denial-of-service. I když se tato část zaměřuje na problémy se spotřebou paměti vyplývající z velkých zpráv, mohou nastat jiné útoky. Zprávy mohou například používat nepřiměřenou dobu zpracování.
Útoky na dostupnost služby se obvykle zmírňují pomocí kvót. Při překročení QuotaExceededException kvóty se obvykle vyvolá výjimka. Bez kvóty může škodlivá zpráva způsobit, že se přistupuje k veškeré dostupné paměti, což vede k výjimce OutOfMemoryException, nebo k přístupu ke všem dostupným zásobníkům, což vede k StackOverflowException.
Scénář překročení kvóty je možné obnovit; pokud k tomu dojde ve spuštěné službě, zpráva, která se právě zpracovává, se zahodí a služba zůstane spuštěná a zpracovává další zprávy. Scénáře přetečení zásobníku a nedostatku paměti ale nejsou v rozhraní .NET Framework obnovitelné. služba se ukončí, pokud dojde k těmto výjimkám.
Kvóty ve WCF nezahrnují žádné předběžné přidělení. Pokud je například kvóta (nalezená MaxReceivedMessageSize v různých třídách) nastavena na 128 kB, neznamená to, že pro každou zprávu je automaticky přiděleno 128 kB. Skutečná přidělená částka závisí na skutečné velikosti příchozí zprávy.
V přenosové vrstvě je k dispozici mnoho kvót. Jedná se o kvóty vynucované konkrétním dopravním kanálem, který se používá (HTTP, TCP atd.). Ačkoliv toto téma uvádí některé z těchto kvót, jsou tyto kvóty podrobně popsány v Přepravní kvóty.
Zranitelnost hashovací tabulky
Ohrožení zabezpečení existuje, když kontrakty dat obsahují hashtable nebo kolekce. K problému dochází, pokud je do hashovatelné tabulky vložen velký počet hodnot, kde velký počet těchto hodnot generuje stejnou hodnotu hash. To se dá použít jako útok DOS. Toto ohrožení zabezpečení je možné zmírnit nastavením kvóty vazby MaxReceivedMessageSize. Při nastavování této kvóty je potřeba věnovat pozornost, aby se zabránilo takovým útokům. Tato kvóta představuje horní limit velikosti zprávy WCF. Kromě toho nepoužívejte v datových kontraktech hašovací tabulky nebo kolekce.
Omezení spotřeby paměti bez streamování
Model zabezpečení kolem velkých zpráv závisí na tom, jestli se používá streamování. V základním nestreamovém případě se zprávy ukládají do vyrovnávací paměti. V takovém případě použijte kvótu MaxReceivedMessageSizeTransportBindingElement pro vazby poskytované systémem, abyste ochránili před velkými zprávami omezením maximální velikosti zprávy na přístup. Upozorňujeme, že služba může současně zpracovávat více zpráv, v takovém případě jsou všechny v paměti. Tuto hrozbu můžete zmírnit pomocí funkce omezování.
Všimněte si také, že MaxReceivedMessageSize neumisťuje horní mez spotřeby paměti pro jednotlivé zprávy, ale omezuje ji na konstantní faktor. Pokud je například MaxReceivedMessageSize 1 MB a přijme se zpráva o velikosti 1 MB a pak se deserializuje, vyžaduje se další paměť, aby obsahovala deserializovaný objektový graf, což vede k celkové spotřebě paměti nad 1 MB. Z tohoto důvodu se vyhněte vytváření serializovatelných typů, které by mohly vést k významné spotřebě paměti bez velkého množství příchozích dat. Například datový kontrakt "MyContract" s 50 volitelnými poli datového člena a 100 dalšími privátními poli může být instancován pomocí konstrukce XML "<MyContract/>". Výsledkem tohoto XML je přístupná paměť pro 150 polí. Všimněte si, že datové členy jsou ve výchozím nastavení volitelné. Problém je složený, pokud je takový typ součástí pole.
MaxReceivedMessageSize samotná není dostatečná, aby se zabránilo všem útokům na dostupnost služby. Deserializátor může být například nucen deserializovat hluboce vnořený objektový graf (objekt, který obsahuje jiný objekt, který obsahuje další objekt atd.) příchozí zprávou. Oba metody DataContractSerializer a XmlSerializer volají vnořeným způsobem k deserializaci těchto grafů. Hluboké vnoření volání metod může vést k neopravitelnému StackOverflowException. Tato hrozba je zmírněna nastavením MaxDepth kvóty pro omezení úrovně vnoření XML, jak je popsáno v části Použití XML bezpečně v tématu.
Nastavení dalších kvót MaxReceivedMessageSize je zvlášť důležité při použití binárního kódování XML. Použití binárního kódování je poněkud ekvivalentní kompresi: malá skupina bajtů v příchozí zprávě může představovat velké množství dat. Proto i zpráva, která se hodí k limitu MaxReceivedMessageSize, může zabírat mnohem více paměti v plně rozšířené podobě. Pokud chcete takové hrozby specifické pro XML zmírnit, je nutné správně nastavit všechny kvóty čtečky XML, jak je popsáno dále v tomto tématu v části Používání XML bezpečně.
Omezení spotřeby paměti pomocí streamování
Při streamování můžete použít malé MaxReceivedMessageSize nastavení k ochraně před útoky na dostupnost služby. U streamování ale můžou být složitější scénáře. Služba pro nahrání souborů například přijímá soubory větší než všechny dostupné paměti. V tomto případě nastavte MaxReceivedMessageSize na extrémně velkou hodnotu, s očekáváním, že téměř žádná data se neukládají do vyrovnávací paměti a zprávy jsou streamována přímo na disk. Pokud škodlivá zpráva může nějak vynutit WCF ukládat data do vyrovnávací paměti místo jeho streamování v tomto případě, MaxReceivedMessageSize už nebude chránit před zprávou, která přistupuje ke všem dostupným paměti.
Pro zmírnění této hrozby existují konkrétní nastavení kvóty pro různé komponenty zpracování dat WCF, které omezují ukládání do vyrovnávací paměti. Nejdůležitější z nich je MaxBufferSize vlastnost pro různé prvky přenosové vazby a standardní vazby. Při streamování by se tato kvóta měla nastavit s ohledem na maximální velikost paměti, kterou jste ochotni přidělit na zprávu.
MaxReceivedMessageSizeStejně jako v případě , nastavení neukládá absolutní maximum pro spotřebu paměti, ale omezuje ho pouze na v rámci konstantního faktoru. Stejně jako v MaxReceivedMessageSizepřípadě , mějte na paměti, že je možné zpracovávat více zpráv současně.
Podrobnosti o MaxBufferSize
Tato vlastnost MaxBufferSize omezuje jakékoliv davové ukládání do vyrovnávací paměti ve WCF. WCF například vždy uloží hlavičky SOAP do vyrovnávací paměti a chyby SOAP, stejně jako všechny části MIME, které nejsou v přirozeném pořadí čtení ve zprávě MTOM (Message Transmission Optimization Mechanism). Toto nastavení omezuje množství ukládání do vyrovnávací paměti ve všech těchto případech.
WCF toho dosahuje předáním MaxBufferSize hodnoty různým komponentám, které mohou ukládat do vyrovnávací paměti. Například některá přetížení třídy CreateMessage přebírají Message parametr. WCF předá MaxBufferSize hodnotu tomuto parametru, aby omezila velikost vyrovnávací paměti hlavičky SOAP. Při použití Message třídy je důležité nastavit tento parametr přímo. Obecně platí, že při použití komponenty ve WCF, který přebírá parametry kvóty, je důležité pochopit důsledky zabezpečení těchto parametrů a správně je nastavit.
Kodér zpráv MTOM má také MaxBufferSize nastavení. Při použití standardních vazeb se to automaticky nastaví na hodnotu přenosu úrovně MaxBufferSize. Při použití elementu vazby kodéru zpráv MTOM k vytvoření vlastní vazby je však důležité nastavit MaxBufferSize vlastnost na bezpečnou hodnotu při použití streamování.
útoky na streamování XML-Based
Samotné MaxBufferSize není dostatečné k zajištění, že WCF není možné při očekávaném streamování vynutit ukládání do vyrovnávací paměti. Například WCF XML procesory vždy ukládají do vyrovnávací paměti celou počáteční značku elementu XML při zahájení čtení nového elementu. To se provádí tak, aby obory názvů a atributy byly správně zpracovány. Pokud MaxReceivedMessageSize je nakonfigurovaná tak, aby byla velká (například pro scénář streamování velkých souborů typu direct-to-disk), může být vytvořena škodlivá zpráva, kde celý text zprávy je velká počáteční značka elementu XML. Pokus o přečtení má za následek OutOfMemoryException. Jedná se o jednu z mnoha možných útoků založených na odepření služeb založených na JAZYCE XML, které je možné zmírnit pomocí kvót čtečky XML, popsané dále v tomto tématu v části "Bezpečné použití XML". Při streamování je obzvláště důležité nastavit všechny tyto kvóty.
Kombinování programovacích modelů streamování a ukládání do vyrovnávací paměti
Mnoho možných útoků vzniká z kombinování programovacích modelů streamování a nestreamovaných programovacích modelů ve stejné službě. Předpokládejme, že existuje smlouva o službách se dvěma operacemi: jedna přijímá Stream a druhá přijímá pole nějakého vlastního typu. Předpokládejme také, že je nastavená na velkou hodnotu, MaxReceivedMessageSize aby první operace mohla zpracovávat velké datové proudy. Bohužel to znamená, že velké zprávy se teď dají odeslat i do druhé operace a deserializátor uloží data do paměti jako pole před zavolání operace. Jedná se o potenciální útok na dostupnost služby: MaxBufferSize kvóta neomezuje velikost textu zprávy, což je to, s čím deserializátor pracuje.
Z tohoto důvodu se vyhněte kombinování operací založených na datových proudech a nestreamovaných operací ve stejném kontraktu. Pokud musíte tyto dva programovací modely naprosto kombinovat, postupujte následovně:
Vypněte funkci IExtensibleDataObject nastavením vlastnosti IgnoreExtensionDataObject z ServiceBehaviorAttribute na
true. Tím se zajistí, že se deserializují pouze členové, kteří jsou součástí smlouvy.MaxItemsInObjectGraph Nastavte vlastnost DataContractSerializer na bezpečnou hodnotu. Tato kvóta je také k dispozici pro ServiceBehaviorAttribute atribut nebo prostřednictvím konfigurace. Tato kvóta omezuje počet objektů, které jsou deserializovány v jedné deserializační epizodě. Za normálních okolností se každý parametr operace nebo část textu zprávy v kontraktu zprávy deserializuje v jedné epizodě. Při deserializaci polí se každá položka pole počítá jako samostatný objekt.
Nastavte všechny kvóty čtečky XML na bezpečné hodnoty. Věnujte pozornost MaxDepth, MaxStringContentLength a MaxArrayLength a vyhněte se řetězcům v mimoproudových operacích.
Projděte si seznam známých typů a mějte na paměti, že kterýkoli z nich je možné kdykoli instancovat (viz část "Zabránění načtení nezamýšlených typů" dále v tomto tématu).
Nepoužívejte žádné typy, které implementují IXmlSerializable rozhraní a ukládají velké množství dat do vyrovnávací paměti. Nepřidávejte takové typy do seznamu známých typů.
Nepoužívejte pole XmlElement, XmlNode, Byte nebo typy, které implementují ISerializable, ve smlouvě.
Nepoužívejte XmlElement pole, XmlNode pole, nebo typy, které implementují Byte, v seznamu známých typů.
Předchozí opatření se použijí, pokud nestreamovaná operace používá DataContractSerializer. Nikdy nekombinujte programovací modely pro streamování a nestreamování ve stejné službě, pokud používáte XmlSerializer, protože nemá ochranu kvóty MaxItemsInObjectGraph.
Pomalé útoky toku
Třída útoků typu denial-of-service zaměřených na streamování nezahrnuje spotřebu paměti. Místo toho útok zahrnuje pomalého odesílatele nebo příjemce dat. Při čekání na odeslání nebo přijetí dat se vyčerpá prostředky, jako jsou vlákna a dostupná připojení. K této situaci může dojít buď v důsledku škodlivého útoku, nebo kvůli legitimnímu odesílateli či příjemci na pomalém síťovém připojení.
Pokud chcete tyto útoky zmírnit, nastavte správný časový limit přenosu. Další informace viz Kvóty přenosu. Za druhé, nikdy nepoužívejte synchronní Read nebo Write operace při práci s datovými proudy ve WCF.
Bezpečné použití XML
Poznámka:
I když se tato část týká XML, informace platí také pro dokumenty JSON (JavaScript Object Notation). Kvóty fungují podobně pomocí mapování mezi JSON a XML.
Zabezpečené čtečky XML
Informační sada XML tvoří základ veškerého zpracování zpráv ve WCF. Při přijímání dat XML z nedůvěryhodného zdroje existuje řada možností útoku na dostupnost služby, které je potřeba zmírnit. WCF poskytuje speciální a zabezpečené čtečky XML. Tyto čtečky se vytvářejí automaticky při použití jednoho ze standardních kódování ve WCF (text, binární soubor nebo MTOM).
Některé funkce zabezpečení těchto čteček jsou vždy aktivní. Čtenáři například nikdy nezpracují definice typu dokumentu (DTD), které jsou potenciálním zdrojem útoků na dostupnost služby a nikdy by se neměly zobrazovat v legitimních zprávách SOAP. Mezi další funkce zabezpečení patří kvóty pro čtení, které je potřeba nakonfigurovat, které jsou popsány v následující části.
Při práci přímo se čtečkami XML (například při psaní vlastního kodéru nebo při přímé práci s Message třídou) vždy používejte zabezpečené čtečky WCF, pokud existuje možnost pracovat s nedůvěryhodnými daty. Vytvořte zabezpečené čtenáře voláním jednoho z přetížení statických továrních metod CreateTextReader, CreateBinaryReader nebo CreateMtomReader třídy XmlDictionaryReader. Při vytváření čtečky předejte hodnoty zabezpečené kvóty. Nevolejte přetížené verze metody Create. Ty nevytvoří čtečku WCF. Místo toho se vytvoří čtenář, který není chráněný funkcemi zabezpečení popsanými v této části.
Čtenářské kvóty
Zabezpečené čtečky XML mají pět konfigurovatelných kvót. Obvykle se konfigurují pomocí ReaderQuotas vlastnosti u elementů vazby kódování nebo standardních vazeb nebo pomocí objektu XmlDictionaryReaderQuotas předaného při vytváření čtečky.
Maximální počet bajtů na čtení
Tato kvóta omezuje počet bajtů, které se čtou v jedné Read operaci při čtení počáteční značky elementu a jeho atributů. (V jiných než streamovaných případech se samotný název elementu nezapočítá do kvóty.) MaxBytesPerRead je důležité z následujících důvodů:
Název elementu a jeho atributy se vždy při čtení uschovávají do paměti. Proto je důležité tuto kvótu správně nastavit v režimu streamování, aby se zabránilo nadměrnému ukládání do vyrovnávací paměti při očekávaném streamování. Informace o skutečném množství probíhajícího vyrovnávacího procesu naleznete v části kvót
MaxDepth.Příliš mnoho atributů XML může spotřebovat nepřiměřeně mnoho času na zpracování, protože je nutné zkontrolovat jedinečnost názvů atributů.
MaxBytesPerReadsnižuje tuto hrozbu.
MaxDepth
Tato kvóta omezuje maximální hloubku vnoření elementů XML. Například dokument "<A><B><C/><B></A>" má třetí úroveň vnoření. MaxDepth je důležité z následujících důvodů:
MaxDepthkomunikuje sMaxBytesPerRead: čtenář vždy uchovává data v paměti pro aktuální prvek a všechny jeho nadřazené prvky, takže maximální spotřeba paměti čtenáře je úměrná součinu těchto dvou nastavení.Při deserializaci hluboko vnořeného objektového grafu je deserializátor nucen přistupovat k celému zásobníku a vyvolat neopravitelný StackOverflowException. Přímá korelace existuje mezi vnořením XML a vnořením objektů jak pro DataContractSerializer, tak pro XmlSerializer. Slouží
MaxDepthke zmírnění této hrozby.
MaxNameTableCharCount
Tato kvóta omezuje velikost názvové tabulky čtenáře. Názvová tabulka obsahuje určité řetězce (například obory názvů a předpony), ke kterým dochází při zpracování dokumentu XML. Vzhledem k tomu, že jsou tyto řetězce uloženy do vyrovnávací paměti, nastavte tuto kvótu, aby se zabránilo nadměrnému ukládání do vyrovnávací paměti při očekávaném streamování.
MaxStringContentLength
Tato kvóta omezuje maximální velikost řetězce, kterou vrátí čtečka XML. Tato kvóta neomezuje spotřebu paměti v samotné čtečce XML, ale v komponentě, která používá čtečku. Pokud například DataContractSerializer používá čtečku zabezpečenou pomocí MaxStringContentLength, nedeserializuje řetězce větší než tato kvóta. Při použití XmlDictionaryReader třídy přímo, ne všechny metody respektují tuto kvótu, ale pouze metody, které jsou speciálně navrženy pro čtení řetězců, jako je například ReadContentAsString metoda. Tato kvóta Value nemá vliv na atribut čtenáře, a proto by neměl být použit, když je zapotřebí ochrana, kterou tato kvóta poskytuje.
MaxArrayLength
Tato kvóta omezuje maximální velikost pole primitiv, které vrátí čtečka XML, včetně bajtových polí. Tato kvóta neomezuje spotřebu paměti v samotné čtečce XML, ale v jakékoli komponentě, která používá čtečku. Například, když DataContractSerializer používá čtečku zabezpečenou pomocí MaxArrayLength, nedeserializuje pole bajtů větší než tato kvóta. Při pokusu o kombinování modelů streamování a modelů ve vyrovnávací paměti v rámci jednoho kontraktu je důležité nastavit tuto kvótu. Mějte na paměti, že při použití XmlDictionaryReader třídy přímo, pouze metody, které jsou speciálně navrženy pro čtení pole libovolné velikosti určitých primitivních typů, například ReadInt32Array, respektují tuto kvótu.
Hrozby specifické pro binární kódování
Binární kódování XML WCF podporuje funkce slovníkových řetězců . Velký řetězec může být kódován pouze pomocí několika bajtů. To umožňuje významné zvýšení výkonu, ale přináší nové hrozby pro odepření služeb, které je potřeba zmírnit.
Existují dva druhy slovníků: statické a dynamické. Statický slovník je integrovaný seznam dlouhých řetězců, které mohou být reprezentovány pomocí krátkého kódu v binárním kódování. Tento seznam řetězců je pevně stanoven při vytvoření čtečky a nelze ho změnit. Žádný z řetězců ve statickém slovníku, který WCF ve výchozím nastavení používá, není dostatečně velký, aby představoval závažnou hrozbu pro odepření služby, i když se můžou stále používat v útoku na rozšíření slovníku. V pokročilých scénářích, kdy poskytujete svůj vlastní statický slovník, buďte opatrní při zavádění velkých řetězců slovníku.
Funkce dynamických slovníků umožňuje zprávám definovat vlastní řetězce a přidružit je ke krátkým kódům. Tato mapování řetězců na kód jsou uložena v paměti během celé komunikační relace, takže následné zprávy nemusí znovu odeslat řetězce a mohou využívat kódy, které jsou již definovány. Tyto řetězce mohou mít libovolnou délku, a proto představují vážnější hrozbu než řetězce ve statickém slovníku.
První hrozbou, kterou je potřeba zmírnit, je možnost, že se dynamický slovník (tabulka mapování řetězců na kód) stává příliš velkým. Tento slovník se může rozšířit v průběhu několika zpráv, takže kvóta MaxReceivedMessageSize nenabízí žádnou ochranu, protože se vztahuje pouze na každou zprávu samostatně. Proto na MaxSessionSize existuje samostatná BinaryMessageEncodingBindingElement vlastnost, která omezuje velikost slovníku.
Na rozdíl od většiny ostatních kvót se tato kvóta vztahuje také při psaní zpráv. Pokud se při čtení zprávy překročí limit, je QuotaExceededException vyvolána jako obvykle. Pokud při zápisu zprávy dojde k překročení kvóty, všechny řetězce, které toto překročení způsobí, se zapíší jako as-isbez použití funkce dynamických slovníků.
Rozšiřovací hrozby slovníku
Z rozšíření slovníku vzniká významná třída útoků specifických pro binární soubory. Malá zpráva v binární podobě se může převést na velmi velkou zprávu v plně rozšířené textové podobě, pokud využívá rozsáhlou funkci řetězcových slovníků. Rozšiřující faktor pro řetězce dynamického slovníku je omezen kvótou MaxSessionSize , protože žádný řetězec dynamického slovníku nepřekračuje maximální velikost celého slovníku.
Vlastnosti MaxNameTableCharCount, MaxStringContentLength a MaxArrayLength omezují pouze spotřebu paměti. Obvykle se nevyžadují ke zmírnění jakýchkoli hrozeb v nestreamovém využití, protože využití paměti je již omezené MaxReceivedMessageSize.
MaxReceivedMessageSize Počítá však bajty před rozšířením. Při použití binárního kódování by spotřeba paměti mohla potenciálně překročit MaxReceivedMessageSize, omezen pouze faktorem MaxSessionSize. Z tohoto důvodu je důležité při použití binárního kódování vždy nastavit všechny kvóty čtenáře (zejména MaxStringContentLength).
Při použití binárního kódování ve spojení s DataContractSerializer může být rozhraní IExtensibleDataObject zneužito k provedení útoku typu rozšiřování slovníku. Toto rozhraní v podstatě poskytuje neomezené úložiště pro libovolná data, která nejsou součástí kontraktu. Pokud kvóty nelze nastavit dostatečně nízko, aby se násobení MaxSessionSize a MaxReceivedMessageSize nestalo problémem, zakažte funkci IExtensibleDataObject při používání binárního kódování. Nastavte vlastnost IgnoreExtensionDataObject na true na atributu ServiceBehaviorAttribute. Alternativně neimplementujte IExtensibleDataObject rozhraní. Další informace najdete v tématu Forward-Compatible datové smlouvy.
Souhrn kvót
Následující tabulka shrnuje pokyny k kvótám.
| Podmínka | Důležité kvóty k nastavení |
|---|---|
| Žádné streamování ani odesílání malých zpráv, textu nebo kódování MTOM. |
MaxReceivedMessageSize, MaxBytesPerRead a MaxDepth |
| Žádné streamování nebo streamování malých zpráv, binární kódování |
MaxReceivedMessageSize, MaxSessionSizea vše ReaderQuotas |
| Streamování velkých zpráv, textu nebo kódování MTOM |
MaxBufferSize a vše ReaderQuotas |
| Streamování velkých zpráv, binární kódování |
MaxBufferSize, MaxSessionSizea vše ReaderQuotas |
Vypršení časového limitu na úrovni přenosu musí být vždy nastaveno a nikdy nepoužívejte synchronní čtení/zápisy, když používáte streamování, bez ohledu na to, jestli streamujete velké nebo malé zprávy.
Pokud máte pochybnosti o kvótě, nastavte ji na bezpečnou hodnotu než ji nechat otevřenou.
Zabránění spuštění škodlivého kódu
Následující obecné třídy hrozeb mohou spouštět kód a mít nezamýšlené účinky:
Deserializátor načte škodlivý, nezabezpečený nebo citlivý na zabezpečení typ.
Příchozí zpráva způsobí, že deserializátor vytvoří instanci normálně bezpečného typu takovým způsobem, že má nezamýšlené důsledky.
V následujících částech jsou tyto třídy hrozeb podrobněji popsány.
DataContractSerializer
cs-CZ: (Informace o zabezpečení na XmlSerializer najdete v příslušné dokumentaci.) Model zabezpečení pro XmlSerializer je podobný modelu zabezpečení pro DataContractSerializer, liší se většinou v detailech. Například XmlIncludeAttribute atribut se používá pro zahrnutí typu místo atributu KnownTypeAttribute . Některé hrozby, které jsou jedinečné pro toto XmlSerializer téma, jsou však popsány dále v tomto tématu.
Zabránění načtení nezamýšlených typů
Načítání nezamýšlených typů může mít významné důsledky, ať už je typ škodlivý nebo má pouze vedlejší účinky citlivé na zabezpečení. Typ může obsahovat zneužitelné ohrožení zabezpečení, provádět akce citlivé na zabezpečení v konstruktoru nebo konstruktoru třídy, mít velké nároky na paměť, které usnadňují útoky na dostupnost služby nebo můžou vyvolat neobnovitelné výjimky. Typy můžou mít konstruktory tříd, které se spouštějí, jakmile je typ načten a před vytvořením všech instancí. Z těchto důvodů je důležité kontrolovat sadu typů, které může deserializátor načíst.
Deserializuje DataContractSerializer volně vázaným způsobem. Nikdy nečte z příchozích dat názvy typů a sestavení modulu CLR (Common Language Runtime). To je podobné chování XmlSerializer, ale liší se od chování NetDataContractSerializer, BinaryFormattera SoapFormatter. Volné spojení představuje stupeň bezpečnosti, protože vzdálený útočník nemůže načíst libovolný typ pouhým pojmenováním tohoto typu ve zprávě.
DataContractSerializer má vždy povoleno načíst typ, který se aktuálně očekává podle kontraktu. Pokud má například datový kontrakt datový člen typu Customer, DataContractSerializer je povoleno načíst Customer typ při deserializaci tohoto datového členu.
Kromě toho podporuje DataContractSerializer polymorfismus. Datový člen může být deklarován jako Object, ale příchozí data mohou obsahovat Customer instanci. Pouze pokud byl typ Customer deserializátoru zpřístupněn nebo učiněn "známým" prostřednictvím jednoho z těchto mechanismů, je to možné.
KnownTypeAttribute atribut použitý u typu.
KnownTypeAttributeatribut určující metodu, která vrací seznam typů.Atribut
ServiceKnownTypeAttribute.Sekce
KnownTypeskonfigurace.Seznam známých typů explicitně předávaných DataContractSerializer během konstrukce, pokud používáte serializátor přímo.
Každý z těchto mechanismů zvyšuje povrchovou plochu tím, že zavádí více typů, které deserializátor může načíst. Kontrolujte každý z těchto mechanismů, abyste zajistili, že do seznamu známých typů nebudou přidány žádné škodlivé nebo nezamýšlené typy.
Jakmile je známý typ v oboru, lze ho kdykoli načíst a instance typu lze vytvořit, i když kontrakt zakáže jeho skutečné použití. Předpokládejme například, že typ "MyDangerousType" je přidán do seznamu známých typů pomocí jednoho z výše uvedených mechanismů. To znamená, že:
MyDangerousTypeje načten a jeho konstruktor třídy se spouští.Dokonce i když deserializujete datový kontrakt s řetězcovým datovým členem, může škodlivá zpráva stále způsobit vytvoření instance
MyDangerousType. Kód vMyDangerousTypeobjektu , například vlastnosti setters, může běžet. Po dokončení se deserializátor pokusí přiřadit tuto instanci datovému členu řetězce a selže s výjimkou.
Při zápisu metody, která vrací seznam známých typů nebo při předávání seznamu přímo DataContractSerializer konstruktoru, ujistěte se, že kód, který seznam připraví, je zabezpečený a pracuje pouze s důvěryhodnými daty.
Pokud v konfiguraci zadáte známé typy, ujistěte se, že je konfigurační soubor zabezpečený. Vždy používejte silné názvy v konfiguraci (zadáním veřejného klíče podepsaného sestavení, kde se typ nachází), ale nezadávejte verzi typu, která se má načíst. Pokud je to možné, zavaděč typů automaticky vybere nejnovější verzi. Pokud v konfiguraci zadáte konkrétní verzi, spustíte následující riziko: Typ může mít chybu zabezpečení, která může být opravena v budoucí verzi, ale zranitelná verze se stále načte, protože je explicitně určená v konfiguraci.
Příliš mnoho známých typů má jiný následek: DataContractSerializer vytváří v doméně aplikace mezipaměť kódu pro serializaci/deserializaci s položkou pro každý typ, který musí serializovat a deserializovat. Tato mezipaměť se nikdy nevymazá, pokud je doména aplikace spuštěná. Útočník, který si je vědom toho, že aplikace používá mnoho známých typů může způsobit deserializaci všech těchto typů, což způsobí, že mezipaměť spotřebuje nepřiměřeně velké množství paměti.
Zabránění tomu, aby typy byly v nezamýšleném stavu
Typ může mít interní omezení konzistence, která se musí vynutit. Je třeba dbát na to, abyste se vyhnuli narušení těchto omezení během deserializace.
Následující příklad typu představuje stav vzduchového zámku na vesmírné lodi a vynucuje omezení, že vnitřní i vnější dveře nelze otevřít současně.
[DataContract]
public class SpaceStationAirlock
{
[DataMember]
private bool innerDoorOpenValue = false;
[DataMember]
private bool outerDoorOpenValue = false;
public bool InnerDoorOpen
{
get { return innerDoorOpenValue; }
set
{
if (value & outerDoorOpenValue)
throw new Exception("Cannot open both doors!");
else innerDoorOpenValue = value;
}
}
public bool OuterDoorOpen
{
get { return outerDoorOpenValue; }
set
{
if (value & innerDoorOpenValue)
throw new Exception("Cannot open both doors!");
else outerDoorOpenValue = value;
}
}
}
<DataContract()> _
Public Class SpaceStationAirlock
<DataMember()> Private innerDoorOpenValue As Boolean = False
<DataMember()> Private outerDoorOpenValue As Boolean = False
Public Property InnerDoorOpen() As Boolean
Get
Return innerDoorOpenValue
End Get
Set(ByVal value As Boolean)
If (value & outerDoorOpenValue) Then
Throw New Exception("Cannot open both doors!")
Else
innerDoorOpenValue = value
End If
End Set
End Property
Public Property OuterDoorOpen() As Boolean
Get
Return outerDoorOpenValue
End Get
Set(ByVal value As Boolean)
If (value & innerDoorOpenValue) Then
Throw New Exception("Cannot open both doors!")
Else
outerDoorOpenValue = value
End If
End Set
End Property
End Class
Útočník může takhle poslat škodlivou zprávu, obejít omezení a dostat objekt do neplatného stavu, což může mít nezamýšlené a nepředvídatelné důsledky.
<SpaceStationAirlock>
<innerDoorOpen>true</innerDoorOpen>
<outerDoorOpen>true</outerDoorOpen>
</SpaceStationAirlock>
Této situaci se můžete vyhnout tím, že si uvědomíte následující body:
Když DataContractSerializer deserializuje většinu tříd, nespustí se konstruktory. Proto nespoléhejte na žádnou správu stavu provedenou v konstruktoru.
Pomocí zpětných volání se ujistěte, že je objekt v platném stavu. Zpětné volání označené atributem OnDeserializedAttribute je zvlášť užitečné, protože se spustí po dokončení deserializace a má šanci prozkoumat a opravit celkový stav. Další informace naleznete v tématu Version-Tolerant serializace zpětných volání.
Nenavrhujte typy datových kontraktů tak, aby se spoléhaly na konkrétní pořadí, ve kterém musí být volány settery vlastností.
Dbejte na to, aby se používaly starší typy označené atributem SerializableAttribute . Mnohé z nich byly navrženy tak, aby fungovaly se vzdálenou komunikací rozhraní .NET Framework, a to pouze s důvěryhodnými daty. Existující typy označené tímto atributem nemusí být navrženy s ohledem na zabezpečení stavu.
Nespoléhejte na IsRequired vlastnost atributu DataMemberAttribute k zajištění přítomnosti dat, pokud jde o bezpečnost státu. Data můžou být vždy
null,zeroneboinvalid.Nikdy nedůvěřujte deserializaci objektového grafu z nedůvěryhodného zdroje dat bez jeho ověření jako první. Každý jednotlivý objekt může být v konzistentním stavu, ale graf objektů jako celek nemusí být. I když je režim zachování grafu objektu zakázán, může deserializovaný graf mít více odkazů na stejný objekt nebo mít cyklické odkazy. Další informace naleznete v tématu Serializace a deserializace.
Bezpečné použití NetDataContractSerializer
Serializační modul používá úzkou vazbu k typům NetDataContractSerializer. Toto je podobné BinaryFormatter a SoapFormatter. To znamená, že určuje, který typ má vytvořit instanci načtením sestavení rozhraní .NET Framework a názvu typu z příchozích dat. Ačkoli je součástí WCF, není poskytovaný žádný způsob, jak tento serializační modul připojit; vlastní kód musí být napsán.
NetDataContractSerializer je poskytován především k usnadnění migrace z .NET Framework pro vzdálenou komunikaci na WCF. Další informace naleznete v příslušné části serializace a deserializace.
Protože samotná zpráva může znamenat, že lze načíst libovolný typ, NetDataContractSerializer mechanismus je ze své podstaty nezabezpečený a měl by se používat pouze s důvěryhodnými daty. Další informace naleznete v příručce zabezpečení BinaryFormatter.
I když se používají s důvěryhodnými daty, příchozí data mohou nedostatečně určit typ, který se má načíst, zejména pokud AssemblyFormat je vlastnost nastavena na Simple. Kdokoliv, kdo má přístup k adresáři aplikace nebo ke globální mezipaměti sestavení, může nahradit zamýšlený typ, který se má načíst, typem škodlivým. Vždy zajistěte zabezpečení adresáře vaší aplikace a globální mezipaměti sestavení správným nastavením oprávnění.
Obecně platí, že pokud povolíte přístup částečně důvěryhodného kódu k instanci NetDataContractSerializer nebo jinak řídíte selektor náhradníka ISurrogateSelector či vazebník serializace SerializationBinder, může kód vykonávat značnou kontrolu nad procesem serializace/deserializace. Například může vložit libovolné typy, vést k vyzrazení informací, manipulovat s výsledným grafem objektů nebo serializovanými daty, nebo může dojít k přetečení výsledného serializovaného datového proudu.
Další obava o zabezpečení s NetDataContractSerializer je odepření služby, nikoli hrozba spuštění škodlivého kódu. Při použití NetDataContractSerializervždy nastavte kvótu MaxItemsInObjectGraph na bezpečnou hodnotu. Je snadné vytvořit malou škodlivou zprávu, která přiděluje pole objektů, jejichž velikost je omezena pouze touto kvótou.
XmlSerializer-Specific hrozby
Model XmlSerializer zabezpečení je podobný DataContractSerializermodelu . Několik hrozeb, nicméně, jsou jedinečné pro XmlSerializer.
Generuje XmlSerializersestavení pro serializaci při běhu programu, která obsahují kód, jenž skutečně provádí serializaci a deserializaci; tato sestavení jsou vytvořena v dočasném adresáři souborů. Pokud má nějaký jiný proces nebo uživatel přístupová práva k danému adresáři, může přepsat serializace/deserializační kód libovolným kódem. Pomocí svého kontextu zabezpečení pak XmlSerializer spustí tento kód, a ne kód pro serializaci/deserializaci. Ujistěte se, že jsou oprávnění správně nastavená v adresáři dočasných souborů, aby k tomu nedocházelo.
Má XmlSerializer také režim, ve kterém používá předgenerovaná serializační sestavení namísto jejich generování za běhu. Tento režim se aktivuje vždy, když XmlSerializer najde vhodné sestavení serializace. XmlSerializer kontroluje, zda serializační sestavení bylo podepsáno stejným klíčem, který byl použit k podepsání sestavení obsahujícího typy, které jsou serializovány. Tato možnost nabízí ochranu před škodlivými sestaveními, která se vydávají za serializační sestavení. Pokud však sestavení obsahující vaše serializovatelné typy není podepsáno elektronickým podpisem, XmlSerializer nemůže provést tuto kontrolu a použije jakékoli sestavení se správným názvem. To umožňuje spuštění škodlivého kódu. Vždy podepište sestavení, která obsahují vaše serializovatelné typy, nebo přísně kontrolujte přístup k adresáři vaší aplikace a k vaší globální mezipaměti sestavení, aby se zabránilo zavedení škodlivých sestavení.
XmlSerializer může být vystaven útoku odepřením služby.
XmlSerializer nemá kvótu MaxItemsInObjectGraph (jak je k dispozici na DataContractSerializer). Proto deserializuje libovolné množství objektů, omezené pouze velikostí zprávy.
Částečné hrozby důvěryhodnosti
Všimněte si následujících obav týkajících se hrozeb souvisejících s kódem spuštěným s částečnou důvěryhodností. Mezi tyto hrozby patří škodlivý částečně důvěryhodný kód a škodlivý částečně důvěryhodný kód v kombinaci s jinými scénáři útoku (například částečně důvěryhodný kód, který vytváří určitý řetězec a pak ho deserializuje).
Při použití jakýchkoli komponent serializace nikdy nevyžadujte žádná oprávnění před takovým použitím, a to ani v případě, že celý scénář serializace je v rozsahu vašeho příkazu assert, a nepracujete s žádným nedůvěryhodným datem nebo objekty. Takové použití může vést k ohrožením zabezpečení.
V případech, kdy částečně důvěryhodný kód má kontrolu nad serializačním procesem, a to buď prostřednictvím bodů rozšiřitelnosti (náhradních dotazů), typů serializovaných nebo jinými prostředky, může částečně důvěryhodný kód způsobit, že serializátor vypíše velké množství dat do serializovaného datového proudu, což může způsobit odepření služby (DoS) příjemci tohoto datového proudu. Pokud serializujete data určená pro cíl, který je citlivý na hrozby DoS, neserializujte částečně důvěryhodné typy ani jinak nedovolte částečně důvěryhodnému kódu řídit serializaci.
Pokud povolíte částečně důvěryhodný přístup kódu k vaší DataContractSerializer instanci nebo jinak řídíte náhradní kontrakty dat, může provádět velkou kontrolu nad serializací/deserializačním procesem. Například může vložit libovolné typy, vést k vyzrazení informací, manipulovat s výsledným grafem objektů nebo serializovanými daty, nebo může dojít k přetečení výsledného serializovaného datového proudu. NetDataContractSerializer Ekvivalentní hrozba je popsaná v části Použití NetDataContractSerializer Bezpečně.
DataContractAttribute Pokud se atribut použije na typ (nebo typ označený jakoSerializableAttribute, ale neníISerializable), deserializátor může vytvořit instanci takového typu, i když jsou všechny konstruktory neveřejné nebo chráněné požadavky.
Nikdy nedůvěřujte výsledku deserializace, pokud nejsou data, která mají být deserializována, důvěryhodná a jste si jisti, že všechny známé typy jsou typy, kterým důvěřujete. Všimněte si, že známé typy nejsou načítány z konfiguračního souboru aplikace (ale jsou načítány z konfiguračního souboru počítače), když běží v režimu omezené důvěryhodnosti.
Pokud předáte instanci DataContractSerializer, ke které byl přidán zástupce, do částečně důvěryhodného kódu, může tento kód změnit veškerá nastavitelná nastavení tohoto zástupce.
U deserializovaného objektu, pokud čtečka XML (nebo data v ní) pochází z částečně důvěryhodného kódu, zachází s výsledným deserializovaným objektem jako nedůvěryhodnými daty.
Skutečnost, že typ nemá žádné veřejné členy, neznamená, ExtensionDataObject že data v něm jsou zabezpečená. Pokud například deserializujete z privilegovaného zdroje dat do objektu, ve kterém se některá data nacházejí, pak tento objekt předáte částečně důvěryhodnému kódu, může částečně důvěryhodný kód číst data v objektu
ExtensionDataObjectserializací objektu. Zvažte nastavení IgnoreExtensionDataObject natruepři deserializaci z privilegovaného datového zdroje do objektu, který se později předá částečně důvěryhodnému kódu.DataContractSerializer a DataContractJsonSerializer podporují serializaci soukromých, chráněných, interních a veřejných členů v plném důvěryhodném režimu. Ve stavu částečné důvěry však lze serializovat pouze veřejné členy. Vyvolá se SecurityException, pokud se aplikace pokusí serializovat neveřejný člen.
Chcete-li povolit serializaci interních nebo chráněných vnitřních členů v částečné důvěryhodnosti, použijte InternalsVisibleToAttribute atribut sestavení. Tento atribut umožňuje sestavení deklarovat, že jeho vnitřní členy jsou viditelné pro některé jiné sestavení. V tomto případě sestavení, které chce mít své vnitřní členy serializované deklaruje, že jeho vnitřní členy jsou viditelné pro System.Runtime.Serialization.dll.
Výhodou tohoto přístupu je, že nevyžaduje cestu generování kódu se zvýšenými oprávněními.
Současně existují dvě hlavní nevýhody.
První nevýhodou je, že vlastnost opt-in atributu InternalsVisibleToAttribute platí pro celou sestavu. To znamená, že nelze určit, aby pouze určité třídě mohly být její interní členy serializovány. Samozřejmě můžete stále rozhodnout, že nebudete serializovat konkrétní interní člen, jednoduše nepřidáním atributu DataMemberAttribute k tomuto členu. Podobně se vývojář může rozhodnout, že člen bude vnitřní spíše než soukromý nebo chráněný, s mírnými viditelnostními obavami.
Druhou nevýhodou je, že stále nepodporuje soukromé ani chráněné členy.
Pokud chcete ilustrovat použití atributu InternalsVisibleToAttribute v částečné důvěryhodnosti, zvažte následující program:
public class Program { public static void Main(string[] args) { try { // PermissionsHelper.InternetZone corresponds to the PermissionSet for partial trust. // PermissionsHelper.InternetZone.PermitOnly(); MemoryStream memoryStream = new MemoryStream(); new DataContractSerializer(typeof(DataNode)). WriteObject(memoryStream, new DataNode()); } finally { CodeAccessPermission.RevertPermitOnly(); } } [DataContract] public class DataNode { [DataMember] internal string Value = "Default"; } }V příkladu výše
PermissionsHelper.InternetZoneodpovídá PermissionSet částečnému vztahu důvěryhodnosti. Bez atributu InternalsVisibleToAttribute se aplikace nezdaří a vyvolá SecurityException indikující, že neveřejné členy nelze serializovat v částečném vztahu důvěryhodnosti.Pokud však do zdrojového souboru přidáme následující řádek, program se úspěšně spustí.
[assembly:System.Runtime.CompilerServices.InternalsVisibleTo("System.Runtime.Serialization, PublicKey = 00000000000000000400000000000000")]
Další obavy týkající se správy stavů
Za zmínku stojí několik dalších problémů týkajících se správy stavu objektů:
Při použití programovacího modelu založeného na streamu se streamovacím přenosem dochází ke zpracování zprávy při příchodu zprávy. Odesílatel zprávy může přerušit operaci odeslání uprostřed datového proudu a nechat kód nepředvídatelným stavem, pokud by byl očekáváno více obsahu. Obecně se nespoléhejte na to, že datový proud bude dokončen, a neprovádějte žádnou práci v operaci založené na datovém proudu, kterou nelze vrátit zpět, pokud je datový proud přerušen. To platí také pro situaci, kdy může být zpráva po textu streamování poškozena (například může chybět koncová značka obálky SOAP nebo může obsahovat druhý text zprávy).
IExtensibleDataObjectPoužití této funkce může způsobit vygenerování citlivých dat. Pokud přijímáte data z nedůvěryhodného zdroje do datových smluv sIExtensibleObjectDataa později je znovu vysíláte na zabezpečeném kanálu, kde jsou zprávy podepsány, potenciálně ručíte za data, o kterých nic nevíte. Celkový stav, který odesíláte, může být navíc neplatný, pokud vezmete v úvahu známé i neznámé části dat. Vyhýbejte se této situaci tak, že buď selektivně nastavíte vlastnost dat rozšířenínullnebo selektivně deaktivujete funkciIExtensibleObjectData.
Import schématu
Za normálních okolností probíhá proces importu schématu pro generování typů pouze v době návrhu, například při použití nástroje ServiceModel Metadata Utility (Svcutil.exe) ve webové službě k vygenerování klientské třídy. V pokročilejších scénářích však můžete zpracovat schéma za běhu. Mějte na paměti, že se tímto vystavujete riziku útoku odepření služby. Import některých schématu může trvat delší dobu. Pokud schémata pravděpodobně pocházejí z nedůvěryhodného zdroje, nikdy v takových scénářích nepoužívejte XmlSerializer komponentu importu schématu.
Hrozby specifické pro integraci ASP.NET AJAX
Když uživatel implementuje WebScriptEnablingBehavior nebo WebHttpBehaviorwcf zveřejňuje koncový bod, který může přijímat zprávy XML i JSON. Existuje však pouze jedna sada kvót pro čtení, kterou používá čtečka XML i čtečka JSON. Některá nastavení kvóty můžou být vhodná pro jednoho čtenáře, ale pro druhou je příliš velká.
Při implementaci WebScriptEnablingBehaviormá uživatel možnost zveřejnit v koncovém bodu javascriptový proxy server. Je třeba zvážit následující problémy se zabezpečením:
Informace o službě (názvy operací, názvy parametrů atd.) je možné získat prozkoumáním proxy javascriptového serveru.
Při použití koncového bodu JavaScriptu mohou být citlivé a soukromé informace zachovány v mezipaměti webového prohlížeče klienta.
Poznámka ke komponentám
WCF je flexibilní a přizpůsobitelný systém. Většina obsahu tohoto tématu se zaměřuje na nejběžnější scénáře použití WCF. Technologie WCF však umožňuje vytváření komponent mnoha různými způsoby. Je důležité porozumět dopadům na zabezpečení používání jednotlivých komponent. Zejména:
Pokud musíte použít čtenáře XML, použijte čtenáře, které poskytuje třída XmlDictionaryReader, na rozdíl od jiných čtenářů. Bezpečné čtečky se vytvářejí pomocí , CreateTextReaderCreateBinaryReadernebo CreateMtomReader metod. Nepoužívejte metodu Create . Vždy konfigurujte čtenáře se bezpečnými kvótami. Serializační moduly ve WCF jsou zabezpečené pouze při použití se zabezpečenými čtečkami XML z WCF.
Při použití DataContractSerializer k deserializaci potenciálně nedůvěryhodných dat vždy nastavte MaxItemsInObjectGraph vlastnost.
Při vytváření zprávy nastavte
maxSizeOfHeadersparametr, pokudMaxReceivedMessageSizenenabízí dostatečnou ochranu.Při vytváření kodéru vždy nakonfigurujte příslušné kvóty, například
MaxSessionSizeaMaxBufferSize.Pokud používáte filtr zpráv XPath, nastavte NodeQuota omezení počtu uzlů XML, které filtr navštíví. Nepoužívejte výrazy XPath, které by mohly trvat dlouhou dobu, než se vypočítá, aniž byste museli navštívit mnoho uzlů.
Obecně platí, že pokud používáte libovolnou komponentu, která přijímá kvótu, seznamte se s důsledky zabezpečení a nastavte ji na bezpečnou hodnotu.