Snažni odgovori html. Ludi oblici. Email adrese

Napadi ubrizgavanjem skripti na više lokacija

U napadu skriptiranja na više lokacija (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 pretraživač i tamo izvršava. Ova shema ima mnogo varijanti. Zlonamjerna skripta može pristupiti kolačićima pretraživača, tokenima sesije ili drugim osjetljivim informacijama pohranjenim u pregledniku. Međutim, svi napadi funkcionišu prema šemi prikazanoj na slici 1.

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

U tipičnom XSS napadu, napadač pronalazi način da ubaci string u web stranicu servera. Recimo da je napadač ubacio sljedeći red u web stranicu: alert("napadnuti ste") . Svaki put kada korisnik posjeti ovu stranicu, njegov pretraživač preuzima ovu skriptu i pokreće je zajedno s ostatkom sadržaja stranice. U tom slučaju, kao rezultat pokretanja skripte, korisnik će vidjeti iskačući prozor s tekstom „napadnuti ste“.

Posljedice XSS

Ako je napadač bio u mogućnosti da iskoristi 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;
  • širenje virusa;
  • pristupiti historiji pregledavanja i sadržaju međuspremnika;
  • Dobij priliku daljinski upravljač Pretraživač;
  • skenirati i koristiti hardverske i softverske resurse i aplikacije na internoj mreži.
Sprečavanje XSS napada

Kako bi spriječila XSS napade, aplikacija mora šifrirati izlaz stranice prije nego što ga isporuči krajnjem korisniku. Prilikom šifriranja izlaznih podataka HTML markup zamijenjen alternativnim reprezentacijama - objekata. Pretraživač prikazuje ove objekte, ali ih ne pokreće. Na primjer, pretvoren u .

Tabela 1 prikazuje nazive objekata za neke uobičajene HTML znakove.

Tablica 1. Nazivi objekata za HTML znakove Rezultat Opis Naziv objekta Broj objekta
Nerazbijajući prostor
< Manje od<
> Više nego> >
& Ampersand& &
¢ Cent¢ ¢
£ Lb£ £
¥ Jena¥ ¥
Euro
§ Paragraf§ §
© Copyright ©
® ® ®
Trademark

Kada pretraživač naiđe na objekte, oni se ponovo konvertuju u HTML i štampaju, ali se ne aktiviraju. Na primjer, ako napadač ubaci string upozorenje ("napadnuti ste") u promjenjivo polje na web stranici servera, tada će, kada koristi opisanu strategiju, server vratiti string upozorenje ("napadnuti ste") .

Kada pretraživač preuzme šifrovanu skriptu, konvertovaće je u alert („napadni ste“) i prikazati skriptu kao deo veb stranice, ali je neće pokrenuti.

Dodavanje HTML koda u Java aplikaciju na strani servera

Da biste spriječili da se zlonamjerni kod skripte prikaže zajedno sa stranicom, vaša aplikacija mora šifrirati sve varijable niza prije nego što se renderiraju na stranici. Šifrovanje se sastoji od jednostavna transformacija svaki znak na odgovarajući naziv HTML objekta, kao što je prikazano u Java kod prikazano na listi 1.

Listing 1. Pretvaranje znakova u nazive HTML objekata javne klase EscapeUtils ( public static final HashMap m = new HashMap(); static ( m.put(34, """); //< - меньше чем m.put(60, ""); // >- veće od //Korisnik mora odgovarati svima html objekti sa odgovarajućim decimalnim vrijednostima. //Mapiranje objekata u decimalne vrijednosti prikazano je u donjoj tabeli) public static String escapeHtml() ( String str = "alert(\"abc\")"; pokušaj ( StringWriter writer = new StringWriter((int) (str .length() * 1.5)); escape(pisac, str); System.out.println("kodirani niz je " + writer.toString()); return writer.toString(); ) catch (IOException ioe) ( ioe .printStackTrace() ; vrati 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 (pisac. write(ime entiteta); ) ) ) )

Java kod u Listingu 1 kodira HTML string String String "alert(\"abc\)" . Koristite sljedeću proceduru:

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

Tabela 2 pokazuje mapiranje HTML objekata na njihove decimalne vrijednosti.

Tablica 2. Decimalne vrijednosti HTML objekta Decimalna vrijednost Opis objekta
160 Nerazbijajući prostor
60 < Manje od
62 > Više nego
38 & Ampersand
162 ¢ Cent
163 £ Lb
165 ¥ Jena
8364 Euro
167 § Paragraf
169 Copyright
174 ® Registered Trademark
8482 Trademark
Zaključak

Ubacivanje skripte na više lokacija jedna je od najčešćih metoda napada na računar korisnika. Međutim, možete značajno smanjiti mogućnost napadača da zarazi vašu web aplikaciju zlonamjernim kodom. Kada pravite svoju aplikaciju, pazite da šifrirate sve izlazne vrijednosti stranice prije nego što ih pošaljete pretraživaču krajnjeg korisnika.

Generisanje odgovora od kontrolora

Nakon što kontrolor završi obradu zahtjeva, obično treba generirati odgovor. Kada kreiramo kontroler niskog nivoa direktnom implementacijom IController interfejsa, moramo preuzeti odgovornost za svaki aspekt obrade zahteva, uključujući generisanje odgovora klijentu.

Na primjer, da biste poslali HTML odgovor, trebali biste kreirati i sastaviti HTML podatke, a zatim ih poslati klijentu koristeći metodu Response.Write(). Slično tome, da biste preusmjerili korisnikov pretraživač na drugi URL, morat ćete pozvati metodu Response.Redirect() i proslijediti joj traženi URL. Oba pristupa su demonstrirana u kodu ispod, koji pokazuje proširenja klase BasicController koju smo kreirali u ranijem članku implementacijom IController sučelja:

Korištenje System.Web.Mvc; koristeći System.Web.Routing; imenski prostor ControllersAndActions.Controllers ( javna klasa BasicController: IController ( public void Execute(RequestContext requestContext) (string kontroler = (string)requestContext.RouteData.Values["controller"]; string action = (string)requestContext.RouteData[V.V.). "]; 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 se može 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 preko svojstva Controller.Response, kao što je prikazano u primjeru ispod, koje proširuje klasu DerivedController, također kreiranu ranije od strane nasljeđujući klasu Controller:

Korišćenje sistema; koristeći System.Web; koristeći System.Web.Mvc; imenski prostor ControllersAndActions.Controllers ( javna klasa 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 moje razvojne mašine.)

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škim za čitanje i održavanje.

    Kontroler koji generiše odgovor direktno na izlaz je teško testirati na jedinici. Morat ćete kreirati lažne implementacije objekta Response, a 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 ključne riječi, što je dug i naporan proces.

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

Srećom, MVC Framework ima zgodan alat koji rješava sve ove probleme - rezultate akcija. Sljedeći odjeljci objašnjavaju koncept rezultata akcije i prikazuju razne načine njegovu upotrebu za generiranje odgovora od kontrolera.

Rezultati akcija

Rezultati akcije u MVC okviru se koriste za odvajanje izjava o namjeri od izvršenja namjere (izvinite na tautologiji). Koncept će se činiti jednostavnim kada ga shvatite, ali je potrebno neko vrijeme da se shvati zbog neke indirektnosti.

Umjesto da se direktno bave objektom Response, metode akcije vraćaju objekt klase izveden iz ActionResult-a koji opisuje kakav bi trebao biti odgovor od kontrolera—na primjer, prikazivanje pogleda ili preusmjeravanje na drugi URL ili metod radnje. Međutim (to je sama indirektnost) odgovor nije direktno generiran. Umjesto toga, kreira se objekat ActionResult, koji MVC Framework obrađuje kako bi proizveo rezultat nakon što je pozvana metoda akcije.

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

Kada MVC Framework primi objekat ActionResult iz akcione metode, on poziva Metoda ExecuteResult()., definiran u klasi ovog objekta. Implementacija rezultata akcije tada radi na objektu Response, generirajući izlaz koji odgovara vašoj namjeri. Da bismo to demonstrirali na djelu, napravimo mapu Infrastructure i dodajmo novu datoteku klase u nju pod nazivom CustomRedirectResult.cs s prilagođenom implementacijom ActionResult prikazanom u primjeru ispod:

Korištenje System.Web.Mvc; imenski prostor ControllersAndActions.Infrastructure ( javna klasa CustomRedirectResult: ActionResult ( javni string Url ( get; set; ) javni nadjačavanje void ExecuteResult(ControllerContext context) ( string fullUrl = UrlHelper.GenerateContentUrl(Url, context.HttpRedirect.Context.); (punUrl); ) ) )

Ova klasa je zasnovana na načinu na koji radi klasa System.Web.Mvc.RedirectResult. Jedna od prednosti MVC okvira otvorenog koda je mogućnost istraživanja unutrašnjeg rada bilo čega. Klasa CustomRedirectResult je mnogo 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 MVC Framework izvršiti kada se metoda akcije završi, prima Objekt odgovora da napravite zahtjev preko ControllerContext objekta koji pruža okvir i pozove ili metodu RedirectPermanent() ili metodu Redirect() (ovo tačno odražava ono što je urađeno unutar implementacije IController niskog nivoa u primjeru ranije u članku).

Upotreba klase CustomRedirectResult je ilustrirana u primjeru ispod, koji pokazuje promjene koje su napravljene na izvedenom kontroleru:

// ... koristeći ControllersAndActions.Infrastructure; imenski prostor ControllersAndActions.Controllers ( javna klasa DerivedController: Controller ( public ActionResult Index() ( // ... ) public ActionResult ProduceOutput() ( if (Server.MachineName == "MyMachineName") vraća novi CustomRedirectResult ( Url = "/Bas Index" ); else ( Response.Write("Kontroler: Izvedeno, Metoda akcije: ProduceOutput"); vrati null; ) ) ) )

Imajte na umu da smo bili prisiljeni promijeniti rezultat metode akcije da vratimo ActionResult. Vraćamo null ako ne želimo da MVC Framework radi bilo šta kada se izvrši naš metod akcije, što smo i uradili ako CustomRedirectResult instanca nije vraćena.

Kontrolori i radnje za testiranje jedinica

Mnogi dijelovi MVC okvira dizajnirani su da olakšaju testiranje jedinica, a to se posebno odnosi na akcije i kontrolere. Postoji nekoliko razloga za ovu podršku:

Možete testirati akcije i kontrolere izvan web servera. Objektima konteksta se pristupa preko njihovih osnovnih klasa (kao što je HttpRequestBase), što je lako ismijavati.

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

Emulacija zahtjeva klijenata nije potrebna. Sistem povezivanja modela MVC Framework-a omogućava vam da pišete metode akcije koje primaju ulaz u svojim parametrima. Da biste testirali metod radnje, jednostavno ga pozovite direktno i pružite odgovarajuće vrijednosti parametara.

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

Ne zaboravite da je testiranje jedinica samo dio slike. Složeno ponašanje u aplikaciji nastaje kada se metode akcije pozivaju sekvencijalno. Jedinično testiranje najbolje funkcionira kada se kombinira s drugim pristupima testiranju.

Sada kada znate kako funkcioniše poseban rezultat akcije preusmjeravanja, možete se prebaciti na njegov ekvivalent koji nudi MVC framework, koji je moćniji i temeljno ga je testirao Microsoft. Potrebna promjena izvedenog kontrolera je data u nastavku:

// ... public ActionResult ProduceOutput() (vrati novi RedirectResult("/Basic/Index"); ) // ...

Uslovni izraz je uklonjen iz metode akcije, što znači da će nakon pokretanja aplikacije i navigacije do URL-a kao što je /Derived/ProduceOutput, pretraživač biti preusmjeren na URL kao što je /Basic/Index. Da bi se pojednostavio kod metode akcije, klasa Controller uključuje praktične metode za generiranje različitih vrsta ActionResult objekata. Tako, na primjer, možemo postići isti efekat kao u gornjem primjeru vraćanjem rezultata Redirect() metode:

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

Nema ničeg posebno složenog u vezi sa sistemom rezultata akcija, ali na kraju pomaže da se proizvede jednostavniji, čistiji, konzistentniji kod koji je lak za čitanje i testiranje jedinica. Na primjer, u slučaju preusmjeravanja, možete jednostavno provjeriti da li metoda akcije vraća instancu RedirectResult čije svojstvo Url sadrži očekivani cilj.

MVC Framework definira mnoge ugrađene tipove rezultata akcije, koji su opisani u donjoj tabeli:

Ugrađeni tipovi ActionResult Tip Opis Pomoćne metode klase Controller
ViewResult

Renderira navedeni ili standardni predložak pogleda

Pogledaj()
PartialViewResult

Renderira navedeni ili standardni predložak djelomičnog prikaza

djelomični prikaz()
RedirectToRouteResult

Problemi HTTP preusmjeravanje 301 ili 302 na metodu akcije ili specificirani unos rute, generirajući URL prema konfiguraciji usmjeravanja

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

Izdaje HTTP 301 ili 302 preusmjeravanje na dati URL

Preusmjeravanje()
PreusmjeravanjePermanent()
ContentResult

Vraća neformatirane tekstualne podatke u pretraživač, dodatno postavljajući zaglavlje tipa sadržaja

sadržaj()
FileResult

Prenosi binarne podatke (kao što je fajl na disku ili niz bajtova u memoriji) direktno u pretraživač

Fajl()
JsonResult

Serializira .NET objekt u JSON format i šalje ga kao odgovor. Odgovori ovog tipa se češće generiraju kada se koriste Web API i AJAX alati

Json()
JavaScriptResult

Šalje fragment izvorni kod JavaScript koji pretraživač mora izvršiti

JavaScript()
HttpUnauthorizedResult

Postavlja statusni kod HTTP odgovora na 401 (što znači "nije ovlašten"), što uzrokuje da mehanizam provjere autentičnosti (provjera autentičnosti obrascima ili Windows autentikacija) traži od posjetitelja da se prijavi

br
HttpNotFoundResult

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

HttpNotFound()
HttpStatusCodeResult

Vraća navedeni HTTP kod

br
EmptyResult

Ne radeći ništa

br

Svi ovi tipovi potiču iz klase ActionResult, a mnogi od njih imaju zgodne pomoćne metode u klasi Controller. U narednim člancima ćemo demonstrirati upotrebu ovih vrsta rezultata.

Nakon primanja i tumačenja poruke zahtjeva, server odgovara porukom HTTP odgovora:

  • Statusna linija
  • Nula ili više polja zaglavlja (Općenito|Odgovor|Entitet) praćenih CRLF-om
  • Prazan red (tj. red bez ničega ispred CRLF-a) koji označava kraj polja zaglavlja
  • Opciono tijelo poruke
  • Svaki sljedeći odjeljak objašnjava entitete koji se koriste u poruci HTTP odgovora.

    Statusna linija poruke

    Statusna linija se sastoji od verzije protokola praćene numeričkim statusnim kodom i pripadajućom tekstualnom frazom. Elementi su odvojeni razmakom SP znakova.

Statusna linija = HTTP verzija SP Statusni kod SP Reason-Phrase CRLF HTTP verzija

Server koji podržava HTTP verziju 1.1 će vratiti sljedeće informacije o verziji:

HTTP-verzija = HTTP/1.1

Status Code

Element Status-Code je trocifreni cijeli broj gdje prva znamenka Status-Code definira klasu odgovora, a posljednje dvije cifre nemaju nikakvu ulogu kategorizacije. Postoji 5 vrijednosti za prvu cifru:

S.N. Šifra i opis
1 1xx: Informativni

To znači da je zahtjev primljen i da se proces 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 dalje radnje kako bi se zahtjev dovršio.

4 4xx: Greška klijenta

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

5 5xx: Greška servera

To znači da server nije uspio ispuniti naizgled valjan zahtjev.

HTTP statusni kodovi su proširivi i HTTP aplikacije nisu potrebne da razumiju značenje svih registrovanih statusnih kodova. Spisak svih statusnih kodova dat je u posebnom poglavlju za vaš referenca.

Polja zaglavlja odgovora

Proučavaćemo Općenito zaglavlje i Zaglavlje entiteta u posebnom poglavlju kada ćemo naučiti HTTP polja zaglavlja. Za sada, hajde da proverimo koja su polja zaglavlja odgovora.

Polja zaglavlja odgovora dozvoljavaju serveru da prosledi dodatne informacije o odgovoru koje se ne mogu staviti u statusnu liniju. Ova polja zaglavlja daju informacije o serveru io daljem pristupu resursu identifikovanom pomoću Request-URI.

  • Proxy-Authenticate

  • WWW-Autentikacija

Možete uvesti svoja prilagođena polja u slučaju da ćete napisati svoj vlastiti prilagođeni Web klijent i server.

Primjeri poruka odgovora

Sada hajde da sve to spojimo da formiramo HTTP odgovor na zahtjev za preuzimanje hello.htm stranice sa web server trčanje na licu mjesta

HTTP/1.1 200 OK Datum: Pon, 27. jul 2009. 12:28:53 GMT Server: Apache/2.2.14 (Win32) Zadnja izmjena: sre, 22. jula 2009. 19:15:56 GMT Dužina sadržaja: 88 sadržaja- Tip: text/html Veza: Zatvorena Zdravo, svijete!

Sljedeći primjer prikazuje HTTP poruku odgovora koja prikazuje stanje greške kada web server nije mogao pronaći traženu stranicu:

HTTP/1.1 404 Nije pronađen Datum: ned, 18. oktobar 2012. 10:36:20 GMT Server: Apache/2.2.14 (Win32) Dužina sadržaja: 230 Veza: zatvorena vrsta sadržaja: text/html; charset=iso-8859-1 404 Nije pronađeno Nije pronađeno

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

Slijedi primjer poruke HTTP odgovora koja pokazuje stanje greške kada je web server naišao na pogrešnu HTTP verziju u datom HTTP zahtjevu:

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

Vaš pretraživač je poslao zahtjev koji ovaj server nije mogao razumjeti.

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