Močni odzivi html. Nore oblike. E-poštni naslovi

Napadi z vbrizgavanjem skripta med spletnimi mesti

Pri napadu XSS (crosssite scripting) napadalec v zakonito spletno stran vbrizga zlonamerno kodo, ki nato izvede zlonamerni skript na strani odjemalca. Ko uporabnik obišče okuženo stran, se skript prenese v uporabnikov brskalnik in se tam izvede. Ta shema ima veliko različic. Zlonamerni skript bi lahko dostopal do piškotkov brskalnika, žetonov seje ali drugih občutljivih informacij, shranjenih v brskalniku. Vendar vsi napadi delujejo po shemi, prikazani na sliki 1.

Slika 1. Slika 1. Tipičen napad XSS
XSS ranljivosti

Pri tipičnem napadu XSS napadalec najde način, da vstavi niz na spletno stran strežnika. Recimo, da je napadalec v spletno stran vnesel naslednjo vrstico: opozorilo("napadeni ste") . Vsakič, ko uporabnik obišče to stran, njegov brskalnik prenese ta skript in ga zažene skupaj z ostalo vsebino strani. V tem primeru bo uporabnik kot rezultat zagona skripta videl pojavno okno z besedilom »napadeni ste«.

Posledice XSS

Če bi napadalec lahko izkoristil ranljivost XSS v spletni aplikaciji, bi lahko v stran vbrizgal skript, ki bi omogočil dostop do podatkov račun uporabnik. V tem primeru lahko napadalec izvede veliko zlonamernih dejanj, na primer:

  • ukrasti račun;
  • širjenje virusov;
  • dostop do zgodovine brskanja in vsebine odložišča;
  • Dobi priložnost daljinec brskalnik;
  • skeniranje in uporabo virov strojne in programske opreme ter aplikacij v notranjem omrežju.
Preprečevanje napadov XSS

Za preprečitev napadov XSS mora aplikacija šifrirati izpis strani, preden ga dostavi končnemu uporabniku. Pri šifriranju izhodnih podatkov HTML oznaka nadomestijo alternativne predstavitve - predmetov. Brskalnik prikaže te predmete, vendar jih ne zažene. Na primer, pretvorjeno v.

Tabela 1 prikazuje imena objektov za nekatere običajne znake HTML.

Tabela 1. Imena objektov za znake HTML Rezultat Opis Ime objekta Številka objekta
Neprekinjen prostor
< Manj kot<
> Več kot> >
& Ampersand& &
¢ cent¢ ¢
£ Lb£ £
¥ Jena¥ ¥
Evro
§ odstavek§ §
© avtorske pravice ©
® ® ®
Blagovna znamka

Ko brskalnik naleti na predmete, se pretvorijo nazaj v HTML in natisnejo, vendar se ne sprožijo. Na primer, če napadalec vstavi niz opozorila ("napadeni ste") v spremenljivo polje na spletni strani strežnika, bo strežnik pri uporabi opisane strategije vrnil niz opozorila ("napadeni ste") .

Ko brskalnik prenese šifriran skript, ga pretvori v opozorilo ("napadeni ste") in prikaže skript kot del spletne strani, vendar ga ne bo zagnal.

Dodajanje kode HTML aplikaciji Java na strani strežnika

Da preprečite upodobitev zlonamerne kode skripta skupaj s stranjo, mora vaša aplikacija šifrirati vse spremenljivke niza, preden se upodobijo na strani. Šifriranje je sestavljeno iz preprosta transformacija vsakega znaka v ustrezno ime predmeta HTML, kot je prikazano v Java koda prikazano na seznamu 1.

Izpis 1. Pretvarjanje znakov v imena objektov HTML public class EscapeUtils ( public static final HashMap m = new HashMap(); static ( m.put(34, """); //< - меньше чем m.put(60, ""); // >- večje od //Uporabnik se mora ujemati z vsemi html predmeti z ustreznimi decimalnimi vrednostmi. //Preslikave objektov v decimalne vrednosti so prikazane v spodnji tabeli) public static String escapeHtml() ( String str = "alert(\"abc\")"; poskusi ( StringWriter writer = new StringWriter((int) (str .length() * 1.5)); escape(writer, str); System.out.println("kodirani niz je " + writer.toString()); return writer.toString(); ) catch (IOException ioe) ( ioe .printStackTrace() ; return null; ) ) public static void escape(Writer writer, String str) vrže 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. napiši (ime entitete); ) ) ) )

Koda Java v seznamu 1 kodira niz HTML String String "alert(\"abc\)" . Uporabite naslednji postopek:

Posledično se bo v izhodu pojavila naslednja vrstica: alert("abc") .

Tabela 2 prikazuje preslikavo objektov HTML v njihove decimalne vrednosti.

Tabela 2. Decimalne vrednosti predmeta HTML Decimalna vrednost Opis predmeta
160 Neprekinjen prostor
60 < Manj kot
62 > Več kot
38 & Ampersand
162 ¢ cent
163 £ Lb
165 ¥ Jena
8364 Evro
167 § odstavek
169 avtorske pravice
174 ® Registrirana blagovna znamka
8482 Blagovna znamka
Zaključek

Vstavljanje skripta med spletnimi mesti je eden najpogostejših načinov napada na uporabnikov računalnik. Vendar pa lahko znatno zmanjšate zmožnost napadalca, da z zlonamerno kodo okuži vašo spletno aplikacijo. Ko gradite svojo aplikacijo, pazite, da šifrirate vse izhodne vrednosti strani, preden jih pošljete v brskalnik končnega uporabnika.

Ustvarjanje odgovora krmilnikov

Ko krmilnik konča obdelavo zahteve, mora običajno ustvariti odgovor. Ko ustvarimo nizkonivojski krmilnik z neposredno implementacijo vmesnika IController, moramo prevzeti odgovornost za vsak vidik obdelave zahtev, vključno z generiranjem odgovora stranki.

Če želite na primer poslati odgovor HTML, bi morali ustvariti in sestaviti podatke HTML ter jih nato poslati odjemalcu z uporabo metode Response.Write(). Podobno boste morali za preusmeritev uporabnikovega brskalnika na drug URL poklicati metodo Response.Redirect() in ji posredovati zahtevani URL. Oba pristopa sta prikazana v spodnji kodi, ki prikazuje razširitve razreda BasicController, ki smo ga ustvarili v prejšnjem članku z implementacijo vmesnika IController:

Uporaba System.Web.Mvc; z uporabo System.Web.Routing; imenski prostor ControllersAndActions.Controllers ( javni razred BasicController: IController ( public void Execute(RequestContext requestContext) ( krmilnik niza = (niz)requestContext.RouteData.Values["krmilnik"]; dejanje niza = (niz)requestContext.RouteData.Values["dejanje "]; if (action.ToLower() == "redirect") ( requestContext.HttpContext.Response.Redirect("/Derived/Index"); ) else ( requestContext.HttpContext.Response.Write(string.Format("Controller) : (0), način dejanja: (1)", krmilnik, dejanje)); ) ) ) )

Enak pristop lahko uporabimo v primeru dedovanja krmilnika iz razreda Controller. Razred HttpResponseBase, ki je vrnjen, ko je lastnost requestContext.HttpContext.Response prebrana v metodi Execute(), je dostopen prek lastnosti Controller.Response, kot je prikazano v spodnjem primeru, ki razširja razred DerivedController, ki ga je prav tako prej ustvaril dedovanje iz razreda Controller:

Uporaba sistema; z uporabo System.Web; z uporabo System.Web.Mvc; imenski prostor ControllersAndActions.Controllers ( javni razred DerivedController: Controller ( javni ActionResult Index() ( // ... ) javni void ProduceOutput() ( if (Server.MachineName == "ProfessorWeb") Response.Redirect("/Basic/Index" ); else Response.Write("Krmilnik: Izpeljano, Metoda dejanja: ProduceOutput"); ) ) )

Metoda ProduceOutput() uporablja vrednost lastnosti Server.MachineName, da se odloči, kateri odgovor poslati odjemalcu. ("ProfessorWeb" je ime mojega razvojnega stroja.)

Čeprav ta pristop generiranja odziva uporabniku deluje, obstaja več težav:

    Razredi krmilnikov morajo vsebovati informacije o Struktura HTML ali URL, zaradi česar je razrede težko brati in vzdrževati.

    Krmilnik, ki generira odziv neposredno na izhod, je težko preizkusiti enoto. Ustvariti boste morali lažne izvedbe objekta Response in nato biti sposobni obdelati izhod iz krmilnika, da ugotovite, kaj je. To lahko na primer pomeni, da je treba oznako HTML razčleniti v ključne besede, kar je dolgotrajen in dolgočasen proces.

    Obdelava majhnih podrobnosti vsakega odgovora na ta način je zapletena in nagnjena k napakam. Nekateri programerji imajo radi absolutni nadzor, ki ga zagotavlja izdelava nizkonivojskega krmilnika, vendar se to običajno zelo hitro zaplete.

Na srečo ima MVC Framework priročno orodje, ki rešuje vse te težave – rezultate dejanj. Naslednji razdelki pojasnjujejo koncept rezultatov dejanj in kažejo različne načine njegovo uporabo za generiranje odgovorov krmilnikov.

Rezultati dejanj

Rezultati dejanj v ogrodju MVC se uporabljajo za ločevanje izjav o nameri od izvedbe namena (oprostite za tavtologijo). Koncept se bo zdel preprost, ko ga boste razumeli, vendar bo trajalo nekaj časa, da ga boste razumeli zaradi nekaj posrednosti.

Namesto da bi neposredno obravnavali objekt Response, metode dejanja vrnejo objekt razreda, izpeljanega iz ActionResult, ki opisuje, kakšen mora biti odgovor krmilnika – na primer upodabljanje pogleda ali preusmeritev na drug URL ali metodo dejanja. Vendar (to je sama posrednost) odgovor ni neposredno generiran. Namesto tega se ustvari objekt ActionResult, ki ga ogrodje MVC obdela, da ustvari rezultat po klicu metode dejanja.

Sistem rezultatov dejanj je primer vzorca oblikovanja ukaza. Ta vzorec predstavlja scenarije, v katerih shranjujete in posredujete objekte, ki opisujejo operacije, ki se izvajajo.

Ko ogrodje MVC prejme objekt ActionResult od metode dejanja, pokliče Metoda ExecuteResult()., definiran v razredu tega objekta. Implementacija rezultatov dejanja nato deluje na objektu Response in ustvari izhod, ki se ujema z vašim namenom. Da bi to prikazali v akciji, ustvarimo mapo Infrastructure in ji dodamo novo datoteko razreda z imenom CustomRedirectResult.cs z izvedbo ActionResult po meri, prikazano v spodnjem primeru:

Uporaba System.Web.Mvc; imenski prostor ControllersAndActions.Infrastructure ( javni razred CustomRedirectResult: ActionResult ( javni niz Url ( get; set; ) javna preglasitev void ExecuteResult(ControllerContext context) ( niz fullUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext); context.HttpContext.Response.Redirect (polniUrl); ) ) )

Ta razred temelji na načinu delovanja razreda System.Web.Mvc.RedirectResult. Ena od prednosti odprtokodnega ogrodja MVC je možnost raziskovanja notranjega delovanja česar koli. Razred CustomRedirectResult je veliko enostavnejši od njegovega ekvivalenta MVC, vendar zadostuje za namene tega članka.

Ko instanciramo razred RedirectResult, posredujemo URL, na katerega naj bo uporabnik preusmerjen. Metoda ExecuteResult(), ki jo bo izvedel ogrodje MVC, ko se zaključi metoda dejanja, prejme Objekt odziva da izvede zahtevo prek objekta ControllerContext, ki ga zagotavlja ogrodje, in pokliče metodo RedirectPermanent() ali metodo Redirect() (to natanko odraža tisto, kar je bilo storjeno znotraj nizkonivojske implementacije IControllerja v primeru v prejšnjem članku).

Uporaba razreda CustomRedirectResult je prikazana v spodnjem primeru, ki prikazuje spremembe, ki so bile narejene v izpeljanem krmilniku:

// ... using ControllersAndActions.Infrastructure; imenski prostor ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public ActionResult ProduceOutput() ( if (Server.MachineName == "MyMachineName") vrni nov CustomRedirectResult ( Url = "/Basic/ Index" ); else ( Response.Write("Controller: Derived, Action Method: ProduceOutput"); return null; ) ) ) )

Upoštevajte, da smo bili prisiljeni spremeniti rezultat metode dejanja, da vrne ActionResult. Vrnemo vrednost null, če ne želimo, da ogrodje MVC naredi karkoli, ko se izvede naša metoda dejanja, kar smo storili, če primerek CustomRedirectResult ni bil vrnjen.

Krmilniki in dejanja za testiranje enot

Številni deli ogrodja MVC so zasnovani tako, da olajšajo testiranje enot, kar še posebej velja za dejanja in krmilnike. Razlogov za to podporo je več:

Dejanja in krmilnike lahko preizkusite zunaj spletnega strežnika. Do kontekstnih objektov se dostopa prek njihovih osnovnih razredov (kot je HttpRequestBase), ki jih je enostavno zasmehovati.

Če želite preizkusiti rezultate metode dejanja, vam ni treba razčleniti oznake HTML. Če želite zagotoviti, da dobite pričakovane rezultate, lahko pregledate vrnjeni objekt ActionResult.

Emulacija zahtev strank ni potrebna. Sistem za vezavo modela ogrodja MVC vam omogoča pisanje akcijskih metod, ki prejmejo vnos v svojih parametrih. Če želite preskusiti akcijsko metodo, jo preprosto pokličete neposredno in zagotovite ustrezne vrednosti parametrov.

Prihodnji članki o ustvarjanju podatkov iz krmilnikov vam bodo pokazali, kako ustvariti teste enot za različne vrste rezultatov dejanj.

Ne pozabite, da je testiranje enot le del slike. Zapleteno vedenje v aplikaciji se pojavi, ko se metode dejanj kličejo zaporedno. Testiranje enot deluje najbolje v kombinaciji z drugimi pristopi testiranja.

Zdaj, ko veste, kako deluje poseben rezultat dejanja preusmeritve, lahko preklopite na njegov ekvivalent, ki ga ponuja ogrodje MVC, ki je močnejše in ga je Microsoft temeljito preizkusil. Zahtevana sprememba izpeljanega krmilnika je navedena spodaj:

// ... public ActionResult ProduceOutput() ( vrni nov RedirectResult("/Basic/Index"); ) // ...

Pogojni stavek je bil odstranjen iz metode dejanja, kar pomeni, da bo brskalnik po zagonu aplikacije in navigaciji do URL-ja, kot je /Derived/ProduceOutput, preusmerjen na URL, kot je /Basic/Index. Za poenostavitev kode metode dejanja razred Controller vključuje priročne metode za generiranje različnih vrst objektov ActionResult. Tako lahko na primer dosežemo enak učinek kot v zgornjem primeru, če vrnemo rezultat metode Redirect():

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

Sistem rezultatov dejanj ni nič posebej zapletenega, vendar na koncu pomaga ustvariti enostavnejšo, čistejšo in doslednejšo kodo, ki jo je enostavno brati in testirati enoto. Na primer, v primeru preusmeritve lahko preprosto preverite, ali metoda dejanja vrne primerek RedirectResult, katerega lastnost Url vsebuje pričakovan cilj.

Ogrodje MVC definira številne vgrajene tipe rezultatov dejanj, ki so opisani v spodnji tabeli:

Vgrajeni tipi ActionResult Tip Opis Pomožne metode razreda Krmilnik
ViewResult

Upodobi določeno ali standardno predlogo pogleda

ogled ()
PartialViewResult

Upodobi določeno ali standardno predlogo delnega pogleda

DelniPogled()
RedirectToRouteResult

Težave Preusmeritev HTTP 301 ali 302 do metode dejanja ali določenega vnosa poti, generiranje URL-ja glede na konfiguracijo usmerjanja

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

Izda preusmeritev HTTP 301 ali 302 na dani URL

Preusmeri()
RedirectPermanent()
ContentResult

Brskalniku vrne neformatirane besedilne podatke in dodatno nastavi glavo vrste vsebine

Vsebina()
FileResult

Prenese binarne podatke (kot je datoteka na disku ali niz bajtov v pomnilniku) neposredno v brskalnik

Mapa()
JsonResult

Serializira predmet .NET v format JSON in ga pošlje kot odgovor. Tovrstni odgovori se pogosteje ustvarijo pri uporabi orodij Web API in AJAX

Json()
JavaScriptResult

Pošlje fragment izvorna koda JavaScript, ki ga mora izvesti brskalnik

JavaScript()
HttpUnauthorizedResult

Nastavi statusno kodo odziva HTTP na 401 (kar pomeni "ni pooblaščen"), kar povzroči, da vzpostavljeni mehanizem za preverjanje pristnosti (preverjanje pristnosti obrazcev ali preverjanje pristnosti sistema Windows) pozove obiskovalca, naj se prijavi

št
HttpNotFoundResult

Vračila Napaka HTTP s kodo 404 - Ni najdeno (ni najdeno)

HttpNotFound()
HttpStatusCodeResult

Vrne določeno kodo HTTP

št
EmptyResult

Početi nič

št

Vsi ti tipi izhajajo iz razreda ActionResult in mnogi od njih imajo priročne pomožne metode v razredu Controller. V naslednjih člankih bomo prikazali uporabo teh vrst rezultatov.

Po prejemu in interpretaciji sporočila zahteve se strežnik odzove z odgovorom HTTP:

  • Statusna vrstica
  • Nič ali več polj glave (General|Response|Entity), ki jim sledi CRLF
  • Prazna vrstica (tj. vrstica brez ničesar pred CRLF), ki označuje konec polj glave
  • Po želji telo sporočila
  • Vsak od naslednjih razdelkov pojasnjuje entitete, ki se uporabljajo v odzivnem sporočilu HTTP.

    Vrstica stanja sporočila

    Statusna vrstica je sestavljena iz različice protokola, ki ji sledi številčna statusna koda in z njo povezana besedilna fraza. Elementi so ločeni s presledki SP.

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF HTTP Version

Strežnik, ki podpira različico HTTP 1.1, bo vrnil naslednje informacije o različici:

Različica HTTP = HTTP/1.1

Statusna koda

Element statusne kode je 3-mestno celo število, kjer prva cifra statusne kode določa razred odziva, zadnji dve števki pa nimata nobene kategorizacijske vloge. Za prvo števko je 5 vrednosti:

S.N. Koda in opis
1 1xx: Informativno

To pomeni, da je bila zahteva prejeta in se postopek nadaljuje.

2 2xx: Uspeh

To pomeni, da je bilo dejanje uspešno prejeto, razumljeno in sprejeto.

3 3xx: Preusmeritev

To pomeni, da je treba sprejeti nadaljnje ukrepe za dokončanje zahteve.

4 4xx: Napaka odjemalca

To pomeni, da zahteva vsebuje napačno sintakso ali da je ni mogoče izpolniti.

5 5xx: Napaka strežnika

Pomeni, da strežnik ni uspel izpolniti navidez veljavne zahteve.

Statusne kode HTTP so razširljive in aplikacijam HTTP ni treba razumeti pomena vseh registriranih statusnih kod. Seznam vseh statusnih kod je podan v posebnem poglavju Za vašo referenca.

Polja glave odgovora

General-header in Entity-header bomo preučevali v ločenem poglavju, ko bomo spoznavali polja glave HTTP. Za zdaj preverimo, kaj so polja glave odgovora.

Polja glave odgovora omogočajo strežniku posredovanje dodatnih informacij o odgovoru, ki jih ni mogoče postaviti v vrstico stanja. Ta polja glave dajejo informacije o strežniku in o nadaljnjem dostopu do vira, ki ga identificira Request-URI.

  • Proxy-Authenticate

  • WWW-preverjanje pristnosti

Svoja polja po meri lahko uvedete, če boste pisali lastnega spletnega odjemalca in strežnika po meri.

Primeri odzivnega sporočila

Zdaj pa sestavimo vse skupaj, da oblikujemo odgovor HTTP za zahtevo za pridobitev strani hello.htm iz spletni strežnik teče na mestu

HTTP/1.1 200 OK Datum: ponedeljek, 27. julij 2009 12:28:53 GMT Strežnik: Apache/2.2.14 (Win32) Zadnja sprememba: sreda, 22. julij 2009 19:15:56 GMT Content-Length: 88 Content- Tip: text/html Povezava: Zaprta Pozdravljen, svet!

Naslednji primer prikazuje odzivno sporočilo HTTP, ki prikazuje stanje napake, ko spletni strežnik ni mogel najti zahtevane strani:

HTTP/1.1 404 ni bilo mogoče najti Datum: ned, 18. oktober 2012 10:36:20 GMT Strežnik: Apache/2.2.14 (Win32) Dolžina vsebine: 230 Povezava: zaprta Vrsta vsebine: besedilo/html; charset=iso-8859-1 404 Ni najdeno Ni najdeno

Zahtevanega URL-ja /t.html ni bilo mogoče najti na tem strežniku.

Sledi primer odzivnega sporočila HTTP, ki prikazuje stanje napake, ko je spletni strežnik v dani zahtevi HTTP naletel na napačno različico HTTP:

HTTP/1.1 400 Slaba prošnja Datum: ned, 18. oktober 2012 10:36:20 GMT Strežnik: Apache/2.2.14 (Win32) Dolžina vsebine: 230 Vrsta vsebine: besedilo/html; charset=iso-8859-1 Povezava: zaprta 400 Slaba zahteva Slaba zahteva

Vaš brskalnik je poslal zahtevo, ki je ta strežnik ni razumel.

Vrstica zahteve je vsebovala neveljavne znake za nizom protokola.