Silné odozvy html. Bláznivé tvary. Emailové adresy

Útoky na vstrekovanie skriptov medzi stránkami

Pri útoku cross-site scripting (XSS) útočník vloží škodlivý kód do legitímnej webovej stránky, ktorá potom spustí škodlivý skript na strane klienta. Keď používateľ navštívi infikovanú stránku, skript sa stiahne do prehliadača používateľa a tam sa spustí. Táto schéma má veľa odrôd. Škodlivý skript by mohol získať prístup k súborom cookie prehliadača, tokenom relácie alebo iným citlivým informáciám uloženým v prehliadači. Všetky útoky však fungujú podľa schémy znázornenej na obrázku 1.

Obrázok 1. Obrázok 1. Typický XSS útok
Zraniteľnosť XSS

Pri typickom XSS útoku útočník nájde spôsob, ako vložiť reťazec na webovú stránku servera. Povedzme, že útočník vložil do webovej stránky nasledujúci riadok: alert("ste pod útokom") . Vždy, keď používateľ navštívi túto stránku, jeho prehliadač stiahne tento skript a spustí ho spolu so zvyškom obsahu stránky. V tomto prípade v dôsledku spustenia skriptu používateľ uvidí vyskakovacie okno s textom „ste pod útokom“.

Dôsledky XSS

Ak by útočník dokázal zneužiť zraniteľnosť XSS vo webovej aplikácii, mohol by do stránky vložiť skript, ktorý by poskytol prístup k údajom. účtu užívateľ. V tomto prípade môže útočník vykonať mnoho škodlivých akcií, napríklad:

  • ukradnúť účet;
  • šíriť vírusy;
  • prístup k vašej histórii prehliadania a obsahu schránky;
  • Získajte príležitosť diaľkové ovládanie prehliadač;
  • skenovať a používať hardvérové ​​a softvérové ​​prostriedky a aplikácie vo vnútornej sieti.
Zabránenie útokom XSS

Aby sa predišlo útokom XSS, aplikácia musí zašifrovať výstup stránky pred jeho doručením koncovému používateľovi. Pri šifrovaní výstupných údajov HTML značky nahradené alternatívnymi reprezentáciami - predmety. Prehliadač zobrazí tieto objekty, ale nespustí ich. Napríklad prevedené na .

Tabuľka 1 zobrazuje názvy objektov pre niektoré bežné znaky HTML.

Tabuľka 1. Názvy objektov pre znaky HTML Výsledok Popis Názov objektu Číslo objektu
Nerozbitný priestor
< Menej ako<
> Viac ako> >
& Ampersand& &
¢ Cent¢ ¢
£ Lb£ £
¥ Jena¥ ¥
eur
§ Odsek§ §
© Autorské práva ©
® ® ®
ochranná známka

Keď prehliadač narazí na objekty, skonvertujú sa späť do HTML a vytlačia sa, ale nespustia sa. Ak napríklad útočník vloží upozornenie na reťazec ("ste pod útokom") do poľa premennej na webovej stránke servera, potom pri použití opísanej stratégie server vráti upozornenie na reťazec ("ste pod útokom") .

Keď prehliadač stiahne zašifrovaný skript, skonvertuje ho na upozornenie („ste pod útokom“) a zobrazí skript ako súčasť webovej stránky, ale nespustí ho.

Pridanie kódu HTML do aplikácie Java na strane servera

Ak chcete zabrániť vykresleniu škodlivého kódu skriptu spolu so stránkou, vaša aplikácia musí zašifrovať všetky premenné reťazca predtým, ako sa vykreslia na stránke. Šifrovanie pozostáva z jednoduchá transformácia každý znak k príslušnému názvu objektu HTML, ako je znázornené v Java kód zobrazené v zozname 1.

Výpis 1. Konverzia znakov na názvy objektov HTML public class EscapeUtils ( public static final HashMap m = new HashMap(); static ( m.put(34, """); //< - меньше чем m.put(60, ""); // >- väčšie ako //Používateľ musí zodpovedať všetkým html objekty so zodpovedajúcimi desatinnými hodnotami. //Priradenia objektov na desiatkové hodnoty sú uvedené v tabuľke nižšie) public static String escapeHtml() (String str = "alert(\"abc\")"; skúste (StringWriter Writer = new StringWriter((int) (str .length() * 1,5)); escape(writer, str); System.out.println("kódovaný reťazec je " + Writer.toString()); return Writer.toString(); ) catch (IOException ioe) ( ioe .printStackTrace() ; return null; ) ) public static void escape (Writer Writer, String str) vyvolá IOException ( int len ​​​​= str.length(); for (int i = 0; i< len; i++) { char c = str.charAt(i); int ascii = (int) c; String entityName = (String) m.get(ascii); if (entityName == null) { if (c >0x7F) ( Writer.write(""); Writer.write(Integer.toString(c, 10)); Writer.write(";"); ) else (writer.write(c); ) ) else (writer. write(názov entity); ) ) ) )

Kód Java vo výpise 1 kóduje reťazec HTML String String "alert(\"abc\)" . Použite nasledujúci postup:

V dôsledku toho sa vo výstupe objaví nasledujúci riadok: alert("abc") .

Tabuľka 2 ukazuje mapovanie objektov HTML na ich desatinné hodnoty.

Tabuľka 2. Desatinné hodnoty objektu HTML Desatinná hodnota Popis objektu
160 Nerozbitný priestor
60 < Menej ako
62 > Viac ako
38 & Ampersand
162 ¢ Cent
163 £ Lb
165 ¥ Jena
8364 eur
167 § Odsek
169 Autorské práva
174 ® Registrovaná ochranná známka
8482 ochranná známka
Záver

Vloženie skriptu medzi stránkami je jednou z najbežnejších metód útoku na počítač používateľa. Môžete však výrazne znížiť schopnosť útočníka infikovať vašu webovú aplikáciu škodlivým kódom. Pri vytváraní aplikácie buďte opatrní, aby ste zašifrovali všetky výstupné hodnoty stránky pred ich odoslaním do prehliadača koncového používateľa.

Generovanie odpovede z ovládačov

Potom, čo kontrolór dokončí spracovanie požiadavky, zvyčajne potrebuje vygenerovať odpoveď. Keď vytvoríme nízkoúrovňový kontrolér priamou implementáciou rozhrania IController, musíme prevziať zodpovednosť za každý aspekt spracovania požiadaviek, vrátane generovania odpovede klientovi.

Ak chcete napríklad odoslať odpoveď HTML, budete musieť vytvoriť a zostaviť údaje HTML a potom ich odoslať klientovi pomocou metódy Response.Write(). Podobne, ak chcete presmerovať prehliadač používateľa na inú adresu URL, budete musieť zavolať metódu Response.Redirect() a odovzdať jej požadovanú adresu URL. Oba prístupy sú demonštrované v kóde nižšie, ktorý zobrazuje rozšírenia triedy BasicController, ktoré sme vytvorili v staršom článku implementáciou rozhrania IController:

pomocou System.Web.Mvc; pomocou System.Web.Routing; menný priestor ControllersAndActions.Controllers ( verejná trieda BasicController: IController ( public void Execute(RequestContext requestContext) ( string controller = (string)requestContext.RouteData.Values["controller"]; string action = (string)requestContext.RouteData.Values["action "]; if (action.ToLower() == "presmerovanie") ( requestContext.HttpContext.Response.Redirect("/Derived/Index"); ) else ( requestContext.HttpContext.Response.Write(string.Format("Controller) : (0), Metóda akcie: (1)", ovládač, akcia)); ) ) ) )

Rovnaký prístup je možné použiť aj v prípade dedenia ovládača z triedy Controller. Trieda HttpResponseBase, ktorá sa vráti pri čítaní vlastnosti requestContext.HttpContext.Response v metóde Execute(), je prístupná prostredníctvom vlastnosti Controller.Response, ako je znázornené v príklade nižšie, ktorý rozširuje triedu DerivedController, tiež vytvorenú predtým dedenie z triedy Controller:

Používanie systému; pomocou System.Web; pomocou System.Web.Mvc; menný priestor ControllersAndActions.Controllers ( verejná trieda DerivedController: Controller ( public ActionResult Index() ( // ... ) public void ProduceOutput() ( if (Server.MachineName == "ProfesorWeb") Response.Redirect("/Basic/Index" ); else Response.Write("Ovládač: odvodené, metóda akcie: ProduceOutput"); ) ) )

Metóda ProduceOutput() používa hodnotu vlastnosti Server.MachineName na rozhodnutie, akú odpoveď poslať klientovi. ("ProfessorWeb" je názov môjho vývojového stroja.)

Hoci tento prístup generovania odpovede používateľovi funguje, je s ním niekoľko problémov:

    Triedy radičov musia obsahovať informácie o HTML štruktúra alebo URL, čo sťažuje čítanie a údržbu tried.

    Kontrolér, ktorý generuje odozvu priamo na výstup, sa ťažko testuje. Budete musieť vytvoriť falošné implementácie objektu Response a potom byť schopný spracovať výstup z radiča, aby ste určili, čo to je. To môže znamenať napríklad potrebu analyzovať HTML značky Kľúčové slová, čo je dlhý a únavný proces.

    Spracovanie malých detailov každej odpovede týmto spôsobom je zložité a náchylné na chyby. Niektorí programátori majú radi absolútnu kontrolu poskytovanú vytvorením nízkoúrovňového ovládača, ale zvyčajne sa to veľmi rýchlo skomplikuje.

Našťastie má MVC Framework šikovný nástroj, ktorý rieši všetky tieto problémy – výsledky akcií. Nasledujúce časti vysvetľujú a zobrazujú koncept výsledkov akcie rôznymi spôsobmi jeho použitie na generovanie odpovedí z ovládačov.

Výsledky akcií

Výsledky akcií v rámci MVC sa používajú na oddelenie vyhlásení o zámere od vykonania zámeru (ospravedlňujeme sa za tautológiu). Koncept sa bude zdať jednoduchý, keď ho pochopíte, ale kvôli určitej nepriamosti trvá nejaký čas, kým ho pochopíte.

Namiesto toho, aby sa metódy akcie zaoberali priamo objektom Response, vracajú objekt triedy odvodený od ActionResult, ktorý popisuje, aká by mala byť odpoveď z kontroléra – napríklad vykreslenie zobrazenia alebo presmerovanie na inú adresu URL alebo metódu akcie. Avšak (toto je práve tá nepriamosť) odpoveď nie je priamo generovaná. Namiesto toho sa vytvorí objekt ActionResult, ktorý MVC Framework spracuje na vytvorenie výsledku po zavolaní metódy akcie.

Systém výsledkov akcií je príkladom návrhového vzoru Command. Tento vzor predstavuje scenáre, v ktorých ukladáte a odovzdávate objekty, ktoré popisujú vykonávané operácie.

Keď MVC Framework prijme objekt ActionResult z metódy akcie, zavolá Metóda ExecuteResult()., definovaný v triede tohto objektu. Implementácia výsledkov akcie potom funguje na objekte Response a generuje výstup, ktorý zodpovedá vášmu zámeru. Aby sme to demonštrovali v praxi, vytvorte priečinok Infrastructure a pridajte doň nový súbor triedy s názvom CustomRedirectResult.cs s vlastnou implementáciou ActionResult, ktorá je znázornená v príklade nižšie:

pomocou System.Web.Mvc; menný priestor ControllersAndActions.Infrastructure ( verejná trieda CustomRedirectResult: ActionResult ( verejný reťazec Url ( get; set; ) verejné prepísanie void ExecuteResult(ControllerContext context) ( string fullUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext.Respontse.Context); context.HttpContext (fullUrl); ) ) )

Táto trieda je založená na spôsobe fungovania triedy System.Web.Mvc.RedirectResult. Jednou z výhod open source MVC Frameworku je možnosť preskúmať vnútorné fungovanie čohokoľvek. Trieda CustomRedirectResult je oveľa jednoduchšia ako jej ekvivalent MVC, ale na účely tohto článku je dostatočná.

Pri vytváraní inštancie triedy RedirectResult odovzdávame adresu URL, na ktorú má byť používateľ presmerovaný. Metóda ExecuteResult(), ktorá bude vykonaná rámcom MVC po dokončení metódy akcie, dostane Objekt odpovede vykonať požiadavku prostredníctvom objektu ControllerContext poskytovaného rámcom a zavolá buď metódu RedirectPermanent() alebo metódu Redirect() (presne to odzrkadľuje to, čo sa urobilo v rámci implementácie IController na nízkej úrovni v príklade vyššie v článku).

Použitie triedy CustomRedirectResult je znázornené v príklade nižšie, ktorý ukazuje zmeny, ktoré boli vykonané na odvodenom ovládači:

// ... using ControllersAndActions.Infrastructure; menný priestor ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public ActionResult ProduceOutput() ( if (Server.MachineName == "MyMachineName") vráti nový CustomRedirectResult ( Url = "/Basic/ Index" ); else ( Response.Write("Ovládač: odvodené, metóda akcie: ProduceOutput"); return null; ) ) ) )

Všimnite si, že sme boli nútení zmeniť výsledok metódy akcie na návrat ActionResult. Vrátime hodnotu null, ak nechceme, aby MVC Framework urobil čokoľvek, keď sa vykoná naša metóda akcie, čo sme urobili, ak sa inštancia CustomRedirectResult nevrátila.

Testovanie jednotiek Ovládače a akcie

Mnohé časti rámca MVC sú navrhnuté tak, aby uľahčili testovanie jednotiek, a to platí najmä pre akcie a ovládače. Existuje niekoľko dôvodov pre túto podporu:

Akcie a ovládače môžete testovať mimo webového servera. Kontextové objekty sú prístupné prostredníctvom ich základných tried (ako je HttpRequestBase), čo sa dá ľahko zosmiešniť.

Ak chcete otestovať výsledky metódy akcie, nemusíte analyzovať označenie HTML. Aby ste sa uistili, že získate očakávané výsledky, môžete skontrolovať vrátený objekt ActionResult.

Emulácia požiadaviek klientov nie je potrebná. Systém viazania modelu MVC Framework vám umožňuje písať metódy akcií, ktoré dostávajú vstup vo svojich parametroch. Ak chcete otestovať metódu akcie, jednoducho ju zavoláte priamo a poskytnete príslušné hodnoty parametrov.

Budúce články o generovaní údajov z kontrolórov vám ukážu, ako vytvoriť jednotkové testy pre rôzne typy výsledkov akcií.

Nezabudnite, že testovanie jednotiek je len časť obrazu. Zložité správanie v aplikácii nastáva, keď sa metódy akcie volajú postupne. Jednotkové testovanie funguje najlepšie v kombinácii s inými testovacími prístupmi.

Teraz, keď viete, ako funguje špeciálny výsledok akcie presmerovania, môžete prejsť na jeho ekvivalent, ktorý ponúka rámec MVC, ktorý je výkonnejší a bol dôkladne testovaný spoločnosťou Microsoft. Požadovaná zmena odvodeného ovládača je uvedená nižšie:

// ... public ActionResult ProduceOutput() ( return new RedirectResult("/Basic/Index"); ) // ...

Z metódy akcie bol odstránený podmienený príkaz, čo znamená, že po spustení aplikácie a prechode na URL ako /Derived/ProduceOutput bude prehliadač presmerovaný na URL ako /Basic/Index. Na zjednodušenie kódu metódy akcie obsahuje trieda Controller pohodlné metódy na generovanie rôznych druhov objektov ActionResult. Takže napríklad môžeme dosiahnuť rovnaký efekt ako v príklade vyššie vrátením výsledku metódy Redirect():

// ... public ActionResult ProduceOutput() ( return Redirect("/Basic/Index"); ) // ...

Na systéme výsledkov akcií nie je nič mimoriadne zložité, ale v konečnom dôsledku pomáha vytvárať jednoduchší, čistejší a konzistentnejší kód, ktorý sa dá ľahko čítať a testovať. Napríklad v prípade presmerovania môžete jednoducho skontrolovať, či metóda akcie vracia inštanciu RedirectResult, ktorej vlastnosť Url obsahuje očakávaný cieľ.

Rámec MVC definuje mnoho vstavaných typov výsledkov akcií, ktoré sú popísané v tabuľke nižšie:

Vstavané typy ActionResult Typ Popis Pomocné metódy triedy Controller
ViewResult

Vykreslí zadanú alebo štandardnú šablónu zobrazenia

Vyhliadka()
PartialViewResult

Vykreslí zadanú alebo štandardnú šablónu čiastočného zobrazenia

PartialView()
RedirectToRouteResult

Problémy HTTP presmerovanie 301 alebo 302 na metódu akcie alebo zadaný záznam trasy, vygenerovanie adresy URL podľa konfigurácie smerovania

RedirectToAction()
RedirectToActionPermanent()
RedirectToRoute()
RedirectToRoutePermanent()
RedirectResult

Vydáva presmerovanie HTTP 301 alebo 302 na danú adresu URL

Redirect()
RedirectPermanent()
ContentResult

Vráti do prehliadača neformátované textové údaje a navyše nastaví hlavičku typu obsahu

obsah()
FileResult

Prenáša binárne dáta (napríklad súbor na disku alebo bajtové pole v pamäti) priamo do prehliadača

súbor()
JsonResult

Serializuje objekt .NET na formát JSON a odošle ho ako odpoveď. Odpovede tohto typu sa častejšie generujú pri použití nástrojov Web API a AJAX

Json()
JavaScriptResult

Odošle fragment zdrojový kód JavaScript, ktorý musí prehliadač spustiť

JavaScript()
HttpUnauthorizedResult

Nastaví stavový kód odpovede HTTP na 401 (čo znamená „neoprávnené“), čo spôsobí, že zavedený mechanizmus overovania (overenie pomocou formulárov alebo overenie systému Windows) vyzve návštevníka, aby sa prihlásil

Nie
HttpNotFoundResult

Návraty Chyba HTTP s kódom 404 - Nenájdené (nenájdené)

HttpNotFound()
HttpStatusCodeResult

Vráti zadaný kód HTTP

Nie
EmptyResult

Ničnerobenie

Nie

Všetky tieto typy sú odvodené od triedy ActionResult a mnohé z nich majú pohodlné pomocné metódy v triede Controller. Využitie týchto typov výsledkov si ukážeme v nasledujúcich článkoch.

Po prijatí a interpretácii správy s požiadavkou server odpovie správou HTTP odpovede:

  • Stavový riadok
  • Nula alebo viac polí hlavičky (General|Response|Entity), za ktorými nasleduje CRLF
  • Prázdny riadok (t. j. riadok, ktorý pred CRLF nemá nič) označujúci koniec polí hlavičky
  • Voliteľne telo správy
  • Každá z nasledujúcich sekcií vysvetľuje entity použité v správe odpovede HTTP.

    Stavový riadok správy

    Stavový riadok pozostáva z verzie protokolu, za ktorou nasleduje číselný stavový kód a súvisiaca textová fráza. Prvky sú oddelené medzerami SP.

Stavový riadok = HTTP verzia SP Stavový kód SP Dôvodová fráza Verzia HTTP CRLF

Server podporujúci HTTP verziu 1.1 vráti nasledujúce informácie o verzii:

Verzia HTTP = HTTP/1.1

Stavový kód

Prvok Status-Code je 3-miestne celé číslo, kde prvá číslica Status-Code definuje triedu odpovede a posledné dve číslice nemajú žiadnu kategorizačnú úlohu. Pre prvú číslicu je 5 hodnôt:

S.N. Kód a popis
1 1xx: Informatívne

Znamená to, že žiadosť bola prijatá a proces pokračuje.

2 2xx: Úspech

Znamená to, že akcia bola úspešne prijatá, pochopená a prijatá.

3 3xx: Presmerovanie

Znamená to, že na dokončenie žiadosti je potrebné vykonať ďalšie kroky.

4 4xx: Chyba klienta

Znamená to, že požiadavka obsahuje nesprávnu syntax alebo ju nemožno splniť.

5 5xx: Chyba servera

Znamená to, že server nesplnil zjavne platnú požiadavku.

Stavové kódy HTTP sú rozšíriteľné a od aplikácií HTTP sa nevyžaduje, aby rozumeli významu všetkých zaregistrovaných stavových kódov. Zoznam všetkých stavových kódov je uvedený v samostatnej kapitole pre teba odkaz.

Polia hlavičky odpovede

General-header a Entity-header budeme študovať v samostatnej kapitole, keď sa naučíme polia HTTP hlavičky. Teraz sa pozrime, čo sú polia hlavičky odpovede.

Polia hlavičky odpovede umožňujú serveru odovzdať dodatočné informácie o odpovedi, ktoré nemožno umiestniť do stavového riadka. Tieto polia hlavičky poskytujú informácie o serveri a o ďalšom prístupe k zdroju identifikovanému pomocou URI požiadavky.

  • Proxy-Authenticate

  • WWW-Autentifikácia

Môžete zaviesť svoje vlastné polia v prípade, že sa chystáte napísať vlastného webového klienta a servera.

Príklady správy s odpoveďou

Teraz to poďme všetko dokopy, aby sme vytvorili odpoveď HTTP na požiadavku na načítanie stránky hello.htm z webový server beží na mieste

HTTP/1.1 200 OK Dátum: Po, 27. júl 2009 12:28:53 GMT Server: Apache/2.2.14 (Win32) Posledná úprava: Streda, 22. júl 2009 19:15:56 GMT Obsah-Dĺžka: 88 Obsah- Typ: text/html Pripojenie: Zatvorené Ahoj, svet!

Nasledujúci príklad zobrazuje správu s odpoveďou HTTP, ktorá zobrazuje chybový stav, keď webový server nemôže nájsť požadovanú stránku:

HTTP/1.1 404 Not Found Date: Ne, 18. október 2012 10:36:20 GMT Server: Apache/2.2.14 (Win32) Content-Length: 230 Connection: Closed Content-Type: text/html; charset=iso-8859-1 404 Nenájdené Nenájdené

Požadovaná adresa URL /t.html sa na tomto serveri nenašla.

Nasleduje príklad správy s odpoveďou HTTP, ktorá zobrazuje chybový stav, keď webový server narazí na nesprávnu verziu HTTP v danej požiadavke HTTP:

HTTP/1.1 400 Zlá požiadavka Dátum: Nedeľa, 18. októbra 2012 10:36:20 GMT Server: Apache/2.2.14 (Win32) Dĺžka obsahu: 230 Typ obsahu: text/html; charset=iso-8859-1 Spojenie: Uzavreté 400 Zlá požiadavka Zlá požiadavka

Váš prehliadač odoslal požiadavku, ktorej tento server nerozumel.

Riadok požiadavky obsahoval neplatné znaky za reťazcom protokolu.