Jaki odgovori html. Ludi oblici. Email adrese

Napadi umetanjem skripte na više stranica

U napadu cross-site scripting (XSS), napadač ubacuje zlonamjerni kod u legitimnu web stranicu, koja zatim izvršava zlonamjernu skriptu na strani klijenta. Kada korisnik posjeti zaraženu stranicu, skripta se preuzima u korisnikov preglednik i tamo se izvršava. Ova shema ima mnogo varijanti. Zlonamjerna skripta mogla bi pristupiti kolačićima preglednika, tokenima sesije ili drugim osjetljivim informacijama pohranjenim u pregledniku. Međutim, svi napadi djeluju prema shemi prikazanoj na slici 1.

Slika 1. Slika 1. Tipični XSS napad
XSS ranjivosti

U tipičnom XSS napadu, napadač pronalazi način da ubaci niz u web stranicu poslužitelja. Recimo da je napadač u web stranicu ubacio sljedeći redak: alert("napadnuti ste") . Svaki put kada korisnik posjeti ovu stranicu, njegov preglednik preuzima ovu skriptu i pokreće je zajedno s ostatkom sadržaja stranice. U tom slučaju, kao rezultat pokretanja skripte, korisnik će vidjeti skočni prozor s tekstom "napadnuti ste".

Posljedice XSS-a

Ako je napadač uspio iskoristiti XSS ranjivost u web aplikaciji, mogao bi ubaciti skriptu na stranicu koja bi omogućila pristup podacima račun korisnik. U tom slučaju napadač može izvršiti mnoge zlonamjerne radnje, na primjer:

  • ukrasti račun;
  • širiti viruse;
  • pristup povijesti pregledavanja i sadržaju međuspremnika;
  • Dobiti priliku daljinski upravljač preglednik;
  • skenirati i koristiti hardverske i softverske resurse i aplikacije na internoj mreži.
Sprječavanje XSS napada

Kako bi se spriječili XSS napadi, aplikacija mora šifrirati izlaz stranice prije nego što je dostavi krajnjem korisniku. Prilikom šifriranja izlaznih podataka HTML označavanje zamijenjen alternativnim prikazima - objekti. Preglednik prikazuje ove objekte, ali ih ne pokreće. Na primjer, pretvoreno u .

Tablica 1 prikazuje imena objekata za neke uobičajene HTML znakove.

Tablica 1. Nazivi objekata za HTML znakove Rezultat Opis Naziv objekta Broj objekta
Prostor koji se ne prekida
< Manje od<
> Više od> >
& ampersand& &
¢ Cent¢ ¢
£ lb£ £
¥ Jena¥ ¥
Euro
§ stavak§ §
© Autorska prava ©
® ® ®
Zaštitni znak

Kada preglednik naiđe na objekte, oni se pretvaraju natrag u HTML i ispisuju, ali se ne aktiviraju. Na primjer, ako napadač umetne string alert("vi ste pod napadom") u varijabilno polje na web stranici poslužitelja, tada će pri korištenju opisane strategije poslužitelj vratiti string alert("vi ste pod napadom") .

Kada preglednik preuzme šifriranu skriptu, pretvorit će je u upozorenje ("napadnuti ste") i prikazati skriptu kao dio web stranice, ali je neće pokrenuti.

Dodavanje HTML koda Java aplikaciji na strani poslužitelja

Kako biste spriječili prikazivanje zlonamjernog koda skripte zajedno sa stranicom, vaša aplikacija mora šifrirati sve varijable niza prije nego što se prikažu na stranici. Enkripcija se sastoji od jednostavna transformacija svaki znak u odgovarajući naziv HTML objekta, kao što je prikazano u Java kod prikazano u popisu 1.

Ispis 1. Pretvaranje znakova u nazive HTML objekata public class EscapeUtils ( public static final HashMap m = new HashMap(); static ( m.put(34, """); //< - меньше чем m.put(60, ""); // >- veće od //Korisnik mora odgovarati svima html objekti s pripadajućim decimalnim vrijednostima. //Preslikavanja objekata u decimalne vrijednosti prikazana su u donjoj tablici) public static String escapeHtml() ( String str = "alert(\"abc\")"; try ( 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) izbacuje 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. napisati(naziv entiteta); ) ) ) )

Java kod u Ispisu 1 kodira HTML niz String String "alert(\"abc\)" . Koristite sljedeći postupak:

Kao rezultat, u izlazu će se pojaviti sljedeći redak: alert("abc") .

Tablica 2 prikazuje mapiranje HTML objekata na njihove decimalne vrijednosti.

Tablica 2. Decimalne vrijednosti HTML objekta Decimalna vrijednost Opis objekta
160 Prostor koji se ne prekida
60 < Manje od
62 > Više od
38 & ampersand
162 ¢ Cent
163 £ lb
165 ¥ Jena
8364 Euro
167 § stavak
169 Autorska prava
174 ® Registrirani zaštitni znak
8482 Zaštitni znak
Zaključak

Ubacivanje skripte na drugu stranicu jedna je od najčešćih metoda napada na korisničko računalo. Međutim, možete značajno smanjiti sposobnost napadača da zarazi vašu web aplikaciju zlonamjernim kodom. Prilikom izrade vaše aplikacije, pazite da šifrirate sve izlazne vrijednosti stranice prije nego što ih pošaljete pregledniku krajnjeg korisnika.

Generiranje odgovora kontrolora

Nakon što kontroler završi s obradom zahtjeva, obično treba generirati odgovor. Kada kreiramo kontroler niske razine izravnom implementacijom sučelja IController, moramo preuzeti odgovornost za svaki aspekt obrade zahtjeva, uključujući generiranje odgovora klijentu.

Na primjer, da biste poslali HTML odgovor, trebali biste stvoriti i sastaviti HTML podatke i zatim ih poslati klijentu pomoću metode Response.Write(). Slično tome, da biste preusmjerili korisnikov preglednik na drugi URL, morat ćete pozvati metodu Response.Redirect() i proslijediti joj traženi URL. Oba su pristupa prikazana u donjem kodu, koji prikazuje proširenja klase BasicController koju smo stvorili u ranijem članku implementacijom sučelja IController:

Korištenje System.Web.Mvc; koristeći System.Web.Routing; namespace ControllersAndActions.Controllers ( public class BasicController: IController ( public void Execute(RequestContext requestContext) ( string controller = (string)requestContext.RouteData.Values["controller"]; string action = (string)requestContext.RouteData.Values["action "]; if (action.ToLower() == "redirect") ( requestContext.HttpContext.Response.Redirect("/Derived/Index"); ) else ( requestContext.HttpContext.Response.Write(string.Format("Controller) : (0), Metoda akcije: (1)", kontroler, akcija)); ) ) ) )

Isti pristup može se primijeniti u slučaju nasljeđivanja kontrolera iz klase Controller. Klasi HttpResponseBase, koja se vraća kada se svojstvo requestContext.HttpContext.Response pročita u metodi Execute(), dostupno je putem svojstva Controller.Response, kao što je prikazano u donjem primjeru, koje proširuje klasu DerivedController, koju je također ranije stvorio nasljeđujući od klase Controller:

Korištenje sustava; koristeći System.Web; koristeći System.Web.Mvc; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public void ProduceOutput() ( if (Server.MachineName == "ProfessorWeb") Response.Redirect("/Basic/Index" ); else Response.Write("Kontroler: Izvedeno, Metoda akcije: ProduceOutput"); ) ) )

Metoda ProduceOutput() koristi vrijednost svojstva Server.MachineName da odluči koji odgovor poslati klijentu. ("ProfessorWeb" je naziv mog razvojnog stroja.)

Iako ovaj pristup generiranja odgovora korisniku funkcionira, postoji nekoliko problema s njim:

    Klase kontrolera moraju sadržavati informacije o HTML struktura ili URL, što čini klase teškima za čitanje i održavanje.

    Kontroler koji generira odgovor izravno na izlaz teško je jedinično testirati. Morat ćete stvoriti lažne implementacije Response objekta i zatim moći obraditi izlaz iz kontrolera da odredite što je to. To može značiti, na primjer, potrebu za raščlanjivanjem HTML oznaka u ključne riječi, što je dug i naporan proces.

    Obrada malih detalja svakog odgovora na ovaj način složena je i podložna pogreškama. Neki programeri vole apsolutnu kontrolu koju pruža izgradnja kontrolera niske razine, ali to se obično vrlo brzo zakomplicira.

Srećom, MVC Framework ima zgodan alat koji rješava sve te probleme - rezultate radnji. Sljedeći odjeljci objašnjavaju koncept rezultata akcije i pokazuju razne načine njegovu upotrebu za generiranje odgovora kontrolora.

Rezultati radnji

Rezultati akcije u MVC okviru koriste se za odvajanje izjava o namjerama od izvršenja namjere (oprostite na tautologiji). Koncept će se činiti jednostavnim nakon što ga shvatite, ali potrebno je neko vrijeme da ga shvatite zbog neke neizravnosti.

Umjesto da se izravno bave objektom Response, radnje metode vraćaju objekt klase izveden iz ActionResult-a koji opisuje kakav bi trebao biti odgovor kontrolera—na primjer, renderiranje prikaza ili preusmjeravanje na drugi URL ili metodu radnje. Međutim (to je sama neizravnost) odgovor nije izravno generiran. Umjesto toga, stvara se objekt ActionResult, koji MVC Framework obrađuje da proizvede rezultat nakon što je pozvana metoda akcije.

Sustav rezultata akcije primjer je uzorka dizajna naredbe. Ovaj uzorak predstavlja scenarije u kojima pohranjujete i prosljeđujete objekte koji opisuju operacije koje se izvode.

Kada MVC Framework primi ActionResult objekt od radnje metode, on poziva ExecuteResult() metoda, definiran u klasi ovog objekta. Implementacija rezultata radnje tada djeluje na objektu Response, generirajući izlaz koji odgovara vašoj namjeri. Da bismo to demonstrirali na djelu, stvorimo mapu Infrastruktura i dodamo joj novu datoteku klase pod nazivom CustomRedirectResult.cs s prilagođenom implementacijom ActionResult prikazanom u primjeru u nastavku:

Korištenje System.Web.Mvc; namespace ControllersAndActions.Infrastructure ( public class CustomRedirectResult: ActionResult ( public string Url ( get; set; ) public override void ExecuteResult(ControllerContext context) ( string fullUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext); context.HttpContext.Response.Redirect (puniUrl); ) ) )

Ova se klasa temelji na načinu na koji funkcionira klasa System.Web.Mvc.RedirectResult. Jedna od prednosti MVC okvira otvorenog koda je mogućnost istraživanja unutarnjeg funkcioniranja bilo čega. Klasa CustomRedirectResult mnogo je jednostavnija od svog MVC ekvivalenta, ali je dovoljna za potrebe ovog članka.

Prilikom instanciranja klase RedirectResult, prosljeđujemo URL na koji korisnik treba biti preusmjeren. Metoda ExecuteResult(), koju će izvršiti MVC Framework kada završi metoda akcije, prima Objekt odgovora za podnošenje zahtjeva putem objekta ControllerContext koji pruža okvir i poziva ili metodu RedirectPermanent() ili metodu Redirect() (ovo točno odražava ono što je učinjeno unutar implementacije IControllera niske razine u primjeru ranije u članku).

Korištenje klase CustomRedirectResult ilustrirano je u primjeru u nastavku, koji prikazuje promjene koje su napravljene na Izvedenom kontroleru:

// ... using ControllersAndActions.Infrastructure; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public ActionResult ProduceOutput() ( if (Server.MachineName == "MyMachineName") return new CustomRedirectResult ( Url = "/Basic/ Indeks" ); else ( Response.Write("Kontroler: Izvedeno, Metoda akcije: ProduceOutput"); return null; ) ) ) )

Imajte na umu da smo bili prisiljeni promijeniti rezultat metode akcije da vrati ActionResult. Vraćamo null ako ne želimo da MVC Framework radi bilo što kada se izvrši naša radna metoda, što smo učinili ako instanca CustomRedirectResult nije vraćena.

Kontrolori i radnje za testiranje jedinice

Mnogi dijelovi MVC okvira dizajnirani su za lakše testiranje jedinica, a to posebno vrijedi za akcije i kontrolere. Postoji nekoliko razloga za ovu podršku:

Radnje i kontrolere možete testirati izvan web poslužitelja. Objektima konteksta pristupa se kroz njihove osnovne klase (kao što je HttpRequestBase), što je lako ismijati.

Da biste testirali rezultate radnje metode, ne morate analizirati HTML oznake. Kako biste bili sigurni da dobivate očekivane rezultate, možete pregledati vraćeni objekt ActionResult.

Nije potrebna emulacija zahtjeva klijenata. Sustav vezivanja modela okvira MVC omogućuje vam pisanje metoda radnji koje primaju unos u svojim parametrima. Da biste testirali akcijsku metodu, jednostavno je pozovite izravno i navedite odgovarajuće vrijednosti parametra.

Budući članci o generiranju podataka iz kontrolera pokazat će vam kako izraditi jedinične testove za različite vrste rezultata radnji.

Ne zaboravite da je jedinično testiranje samo dio slike. Složeno ponašanje u aplikaciji događa se kada se akcijske metode pozivaju uzastopno. Jedinično testiranje najbolje funkcionira u kombinaciji s drugim pristupima testiranju.

Sada kada znate kako funkcionira poseban rezultat akcije preusmjeravanja, možete se prebaciti na njegov ekvivalent koji nudi okvir MVC, koji je moćniji i temeljito ga je testirao Microsoft. Potrebna promjena izvedenog regulatora je navedena u nastavku:

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

Uvjetna izjava je uklonjena iz metode akcije, što znači da će nakon pokretanja aplikacije i navigacije do URL-a kao što je /Derived/ProduceOutput, preglednik biti preusmjeren na URL kao što je /Basic/Index. Kako bi se pojednostavio kod metode akcije, klasa Controller uključuje praktične metode za generiranje raznih vrsta ActionResult objekata. Tako, na primjer, možemo postići isti učinak kao u gornjem primjeru vraćanjem rezultata metode Redirect():

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

Nema ništa posebno složeno u sustavu rezultata akcije, ali u konačnici pomaže u stvaranju jednostavnijeg, čišćeg i dosljednijeg koda koji je jednostavan za čitanje i jedinično testiranje. Na primjer, u slučaju preusmjeravanja, možete jednostavno provjeriti vraća li metoda radnje instancu RedirectResult čije svojstvo Url sadrži očekivani cilj.

MVC Framework definira mnoge ugrađene tipove rezultata radnji, koji su opisani u tablici u nastavku:

Ugrađene vrste ActionResult Tip Opis Pomoćne metode klase Controller
ViewResult

Renderira navedeni ili standardni predložak prikaza

Pogled()
PartialViewResult

Iscrtava navedeni ili standardni predložak djelomičnog prikaza

Djelomični prikaz()
RedirectToRouteResult

Problemi HTTP preusmjeravanje 301 ili 302 na akcijsku metodu ili određeni unos rute, generiranje URL-a prema konfiguraciji usmjeravanja

Preusmjeri na radnju()
RedirectToActionPermanent()
RedirectToRoute()
RedirectToRoutePermanent()
RedirectResult

Izdaje HTTP 301 ili 302 preusmjeravanje na navedeni URL

Preusmjeri()
RedirectPermanent()
ContentResult

Vraća neformatirane tekstualne podatke pregledniku, dodatno postavljajući zaglavlje vrste sadržaja

Sadržaj()
FileResult

Prenosi binarne podatke (kao što je datoteka na disku ili niz bajtova u memoriji) izravno u preglednik

Datoteka()
JsonResult

Serializira .NET objekt u JSON format i šalje kao odgovor. Odgovori ove vrste češće se generiraju korištenjem Web API i AJAX alata

Json()
JavaScriptResult

Šalje fragment izvorni kod JavaScript koji mora izvršiti preglednik

JavaScript()
HttpUnauthorizedResult

Postavlja šifru statusa HTTP odgovora na 401 (što znači "nije ovlašteno"), što uzrokuje da mehanizam provjere autentičnosti (provjera autentičnosti obrasca ili Windows provjera autentičnosti) traži od posjetitelja da se prijavi

Ne
HttpNotFoundResult

Povratak HTTP greška sa šifrom 404 - Nije pronađeno (nije pronađeno)

HttpNotFound()
HttpStatusCodeResult

Vraća navedeni HTTP kod

Ne
EmptyResult

Ne radeći ništa

Ne

Sve ove vrste proizlaze iz klase ActionResult, a mnoge od njih imaju prikladne pomoćne metode u klasi Controller. Pokazat ćemo korištenje ovih vrsta rezultata u sljedećim člancima.

Nakon primanja i tumačenja poruke zahtjeva, poslužitelj odgovara porukom HTTP odgovora:

  • Statusna linija
  • Nula ili više polja zaglavlja (Općenito|Odgovor|Entitet) iza kojih slijedi CRLF
  • Prazan red (tj. red bez ičega ispred CRLF-a) koji označava kraj polja zaglavlja
  • Po izboru tijelo poruke
  • Svaki od sljedećih odjeljaka objašnjava entitete koji se koriste u poruci HTTP odgovora.

    Redak statusa poruke

    Redak statusa sastoji se od verzije protokola iza koje slijedi numerički statusni kod i njegova pridružena tekstualna fraza. Elementi su odvojeni razmakom SP.

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

Poslužitelj koji podržava HTTP verziju 1.1 vratit će sljedeće informacije o verziji:

HTTP-verzija = HTTP/1.1

Šifra statusa

Element Status-Code je 3-znamenkasti cijeli broj gdje prva znamenka Status-Code definira klasu odgovora, a zadnje dvije znamenke nemaju nikakvu ulogu kategorizacije. Postoji 5 vrijednosti za prvu znamenku:

S N. Kod i opis
1 1xx: Informativno

To znači da je zahtjev primljen i proces se nastavlja.

2 2xx: Uspjeh

To znači da je akcija uspješno primljena, shvaćena i prihvaćena.

3 3xx: Preusmjeravanje

To znači da se moraju poduzeti daljnje radnje kako bi se zahtjev dovršio.

4 4xx: Greška klijenta

To znači da zahtjev sadrži netočnu sintaksu ili da se ne može ispuniti.

5 5xx: Greška poslužitelja

To znači da poslužitelj nije uspio ispuniti naizgled važeći zahtjev.

HTTP statusni kodovi su proširivi i HTTP aplikacije ne moraju razumjeti značenje svih registriranih statusnih kodova. Popis svih statusnih kodova dan je u posebnom poglavlju za tvoj referenca.

Polja zaglavlja odgovora

Proučavat ćemo General-header i Entity-header u zasebnom poglavlju kada ćemo učiti polja HTTP zaglavlja. Za sada provjerimo što su polja zaglavlja odgovora.

Polja zaglavlja odgovora omogućuju poslužitelju prosljeđivanje dodatnih informacija o odgovoru koje se ne mogu smjestiti u redak statusa. Ova polja zaglavlja daju informacije o poslužitelju io daljnjem pristupu resursu koji identificira Request-URI.

  • Proxy-Autentifikacija

  • WWW-Autentifikacija

Možete uvesti svoja prilagođena polja u slučaju da namjeravate napisati vlastiti prilagođeni web klijent i poslužitelj.

Primjeri poruka odgovora

Sada spojimo sve zajedno kako bismo formirali HTTP odgovor za zahtjev za dohvaćanje stranice hello.htm s web poslužitelj trčanje na mjestu

HTTP/1.1 200 OK Datum: ponedjeljak, 27. srpnja 2009. 12:28:53 GMT Poslužitelj: Apache/2.2.14 (Win32) Zadnja izmjena: srijeda, 22. srpnja 2009. 19:15:56 GMT Dužina sadržaja: 88 Sadržaj- Tip: text/html Veza: Zatvorena Hello, World!

Sljedeći primjer prikazuje poruku HTTP odgovora koja prikazuje stanje pogreške kada web poslužitelj ne može pronaći traženu stranicu:

HTTP/1.1 404 Nije pronađeno Datum: ned, 18. listopada 2012. 10:36:20 GMT Poslužitelj: Apache/2.2.14 (Win32) Dužina sadržaja: 230 Veza: Zatvoreno Tip sadržaja: tekst/html; charset=iso-8859-1 404 Nije pronađeno Nije pronađeno

Traženi URL /t.html nije pronađen na ovom poslužitelju.

Slijedi primjer poruke HTTP odgovora koja prikazuje stanje pogreške kada je web poslužitelj naišao na pogrešnu HTTP verziju u danom HTTP zahtjevu:

HTTP/1.1 400 Loš zahtjev Datum: ned, 18. listopada 2012. 10:36:20 GMT Poslužitelj: Apache/2.2.14 (Win32) Dužina sadržaja: 230 Tip sadržaja: tekst/html; charset=iso-8859-1 Veza: zatvorena 400 Loš zahtjev Loš zahtjev

Vaš preglednik je poslao zahtjev koji ovaj poslužitelj nije mogao razumjeti.

Redak zahtjeva sadržavao je nevažeće znakove nakon niza protokola.