Sterke svar html. Gale former. E-post adresse

Skriptinjeksjonsangrep på tvers av nettsteder

I et cross-site scripting (XSS)-angrep injiserer en angriper ondsinnet kode på en legitim webside, som deretter kjører et ondsinnet skript på klientsiden. Når en bruker besøker en infisert side, lastes skriptet ned til brukerens nettleser og kjøres der. Denne ordningen har mange varianter. Et ondsinnet skript kan få tilgang til nettleserinformasjonskapsler, økttokens eller annen sensitiv informasjon som er lagret i nettleseren. Imidlertid opererer alle angrep i henhold til skjemaet vist i figur 1.

Figur 1. Figur 1. Typisk XSS-angrep
XSS-sårbarheter

I et typisk XSS-angrep finner angriperen en måte å injisere en streng på serverens webside. La oss si at en angriper injiserte følgende linje på en webside: alert("du er under angrep") . Hver gang en bruker besøker denne siden, laster nettleseren deres ned dette skriptet og kjører det sammen med resten av sidens innhold. I dette tilfellet, som et resultat av å kjøre skriptet, vil brukeren se et popup-vindu med teksten "du er under angrep."

Konsekvenser av XSS

Hvis en angriper var i stand til å utnytte en XSS-sårbarhet i en nettapplikasjon, kunne han injisere skript på siden som ville gi tilgang til data regnskap bruker. I dette tilfellet kan angriperen utføre mange ondsinnede handlinger, for eksempel:

  • stjele en konto;
  • spre virus;
  • få tilgang til nettleserloggen og innholdet på utklippstavlen;
  • Få en mulighet fjernkontroll nettleser;
  • skanne og bruke maskinvare- og programvareressurser og applikasjoner på det interne nettverket.
Forhindrer XSS-angrep

For å forhindre XSS-angrep, må applikasjonen kryptere sideutgangen før den leveres til sluttbrukeren. Ved kryptering av utdata HTML-oppmerking erstattet av alternative representasjoner - gjenstander. Nettleseren viser disse objektene, men starter dem ikke. For eksempel konvertert til .

Tabell 1 viser objektnavnene for noen vanlige HTML-tegn.

Tabell 1. Objektnavn for HTML-tegn Resultat Beskrivelse Objektnavn Objektnummer
Non-breaking plass
< Mindre enn<
> Mer enn> >
& Ampersand& &
¢ Cent¢ ¢
£ Lb£ £
¥ Jena¥ ¥
Euro
§ Avsnitt§ §
© opphavsrett ©
® ® ®
Varemerke

Når nettleseren møter objektene, konverteres de tilbake til HTML og skrives ut, men de blir ikke avfyrt. For eksempel, hvis en angriper setter inn strengvarsling ("du er under angrep") i et variabelfelt på serverens webside, vil serveren returnere strengvarslet ("du er under angrep") når du bruker den beskrevne strategien. .

Når nettleseren laster ned det krypterte skriptet, vil den konvertere det til alarm ("du er under angrep") og vise skriptet som en del av websiden, men vil ikke kjøre det.

Legge til HTML-kode til en Java-applikasjon på serversiden

For å forhindre at skadelig skriptkode gjengis sammen med siden, må applikasjonen kryptere alle strengvariabler før de gjengis på siden. Kryptering består av enkel transformasjon hvert tegn til det tilsvarende HTML-objektnavnet, som vist i Java-kode vist i oppføring 1.

Oppføring 1. Konvertering av tegn til HTML-objektnavn public class EscapeUtils ( public static final HashMap m = new HashMap(); static ( m.put(34, """); //< - меньше чем m.put(60, ""); // >- større enn //Bruker må samsvare med alle html-objekter med tilsvarende desimalverdier. //Objekttilordninger til desimalverdier er vist i tabellen nedenfor) public static String escapeHtml() ( String str = "alert(\"abc\")"); prøv ( StringWriter writer = new StringWriter((int) (str) .length() * 1,5)); null; ) ) public static void escape(Writer writer, String str) kaster 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. skriv(enhetsnavn);

Java-koden i oppføring 1 koder for HTML-strengen String "alert(\"abc\)" . Bruk følgende prosedyre:

Som et resultat vil følgende linje vises i utdataene: alert("abc") .

Tabell 2 viser tilordningen av HTML-objekter til deres desimalverdier.

Tabell 2. HTML-objektets desimalverdier Desimalverdi Objektbeskrivelse
160 Non-breaking plass
60 < Mindre enn
62 > Mer enn
38 & Ampersand
162 ¢ Cent
163 £ Lb
165 ¥ Jena
8364 Euro
167 § Avsnitt
169 opphavsrett
174 ® Registrert varemerke
8482 Varemerke
Konklusjon

Skriptinjeksjon på tvers av nettsteder er en av de vanligste metodene for å angripe en brukers datamaskin. Du kan imidlertid redusere en angripers evne til å infisere nettapplikasjonen din med skadelig kode betydelig. Når du bygger applikasjonen din, vær forsiktig med å kryptere alle sideutdataverdier før du sender dem til sluttbrukerens nettleser.

Generer et svar fra kontrollere

Etter at kontrolleren er ferdig med å behandle forespørselen, må den vanligvis generere et svar. Når vi oppretter en kontroller på lavt nivå ved å implementere IController-grensesnittet direkte, må vi ta ansvar for alle aspekter av forespørselsbehandlingen, inkludert å generere et svar til klienten.

For å sende et HTML-svar, må du for eksempel opprette og komponere HTML-dataene og deretter sende dem til klienten ved å bruke Response.Write()-metoden. På samme måte, for å omdirigere brukerens nettleser til en annen URL, må du kalle opp Response.Redirect()-metoden og gi den den nødvendige URL-en. Begge tilnærmingene er demonstrert i koden nedenfor, som viser utvidelser av BasicController-klassen som vi opprettet i en tidligere artikkel ved å implementere IController-grensesnittet:

Bruker System.Web.Mvc; bruker System.Web.Routing; navneområde ControllersAndActions.Controllers ( offentlig klasse BasicController: IController ( public void Execute(RequestContext requestContext) ( string controller = (string)requestContext.RouteData.Values["controller"]; string action = (string)requestContext.RouteData.Values "]; if (action.ToLower() == "omdirigering") ( requestContext.HttpContext.Response.Redirect("/Derived/Index"); ) else ( requestContext.HttpContext.Response.Write(string.Format("Controller : (0), Handlingsmetode: (1)", kontroller, handling)); ) ) ) )

Den samme tilnærmingen kan brukes i tilfelle av å arve en kontroller fra Controller-klassen. HttpResponseBase-klassen, som returneres når requestContext.HttpContext.Response-egenskapen leses i Execute()-metoden, er tilgjengelig via Controller.Response-egenskapen, som vist i eksemplet nedenfor, som utvider DerivedController-klassen, også opprettet tidligere av arver fra Controller-klassen:

Bruke System; bruker System.Web; bruker System.Web.Mvc; navneområde ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public void ProduceOutput() ( if (Server.MachineName == "ProfessorWeb") Response.Redirect("/Basic/Index" ); else Response.Write("Kontroller: Avledet, Handlingsmetode: ProduceOutput");

ProduceOutput()-metoden bruker verdien til Server.MachineName-egenskapen for å bestemme hvilket svar som skal sendes til klienten. ("ProfessorWeb" er navnet på utviklingsmaskinen min.)

Selv om denne tilnærmingen for å generere et svar til brukeren fungerer, er det flere problemer med det:

    Kontrollørklasser skal inneholde informasjon om HTML-struktur eller URL, som gjør klasser vanskelige å lese og vedlikeholde.

    En kontroller som genererer en respons direkte på utgang er vanskelig å enhetsteste. Du må lage falske implementeringer av Response-objektet og deretter kunne behandle utdataene fra kontrolleren for å finne ut hva det er. Dette kan for eksempel bety behovet for å analysere HTML-oppmerking til søkeord, som er en lang og kjedelig prosess.

    Å behandle de små detaljene i hvert svar på denne måten er komplekst og utsatt for feil. Noen programmerere liker den absolutte kontrollen som tilbys ved å bygge en kontroller på lavt nivå, men dette blir vanligvis komplisert veldig raskt.

Heldigvis har MVC Framework et hendig verktøy som løser alle disse problemene – resultatene av handlinger. De følgende avsnittene forklarer konseptet med handlingsresultater og viser ulike måter dens bruk for å generere svar fra kontrollere.

Handlingsresultater

Handlingsresultater i MVC-rammeverket brukes til å skille intensjonserklæringer fra utførelse av intensjon (beklager tautologien). Konseptet vil virke enkelt når du først får taket på det, men det tar litt tid å forstå på grunn av noe indirekte.

I stedet for å handle direkte med et Response-objekt, returnerer handlingsmetoder et ActionResult-avledet klasseobjekt som beskriver hva svaret fra kontrolleren skal være – for eksempel gjengivelse av en visning eller omdirigering til en annen URL eller handlingsmetode. Imidlertid (dette er selve indirekte) svaret er ikke direkte generert. I stedet opprettes et ActionResult-objekt, som MVC Framework behandler for å produsere resultatet etter at handlingsmetoden er kalt.

Et handlingsresultatsystem er et eksempel på kommandodesignmønsteret. Dette mønsteret representerer scenarier der du lagrer og sender objekter som beskriver operasjonene som utføres.

Når MVC Framework mottar et ActionResult-objekt fra en handlingsmetode, kaller det ExecuteResult()-metoden, definert i klassen til dette objektet. Implementeringen av handlingsresultatene opererer deretter på Response-objektet, og genererer utdata som samsvarer med intensjonen din. For å demonstrere dette i aksjon, la oss lage en Infrastructure-mappe og legge til en ny klassefil til den kalt CustomRedirectResult.cs med en tilpasset ActionResult-implementering vist i eksemplet nedenfor:

Bruker System.Web.Mvc; navneområde ControllersAndActions.Infrastructure ( offentlig klasse CustomRedirectResult: ActionResult ( offentlig streng URL ( get; set; ) offentlig overstyring void ExecuteResult(ControllerContext context) ( string fullUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext.Redirect.HttpContext); context.Redirect.HttpContext (full URL);

Denne klassen er basert på måten System.Web.Mvc.RedirectResult-klassen fungerer på. En av fordelene med åpen kildekode MVC Framework er muligheten til å utforske den indre funksjonen til hva som helst. CustomRedirectResult-klassen er mye enklere enn MVC-ekvivalenten, men er tilstrekkelig for formålet med denne artikkelen.

Når vi instansierer RedirectResult-klassen, sender vi inn URL-en som brukeren skal omdirigeres til. ExecuteResult()-metoden, som vil bli utført av MVC Framework når handlingsmetoden er fullført, mottar Responsobjektå lage en forespørsel gjennom ControllerContext-objektet gitt av rammeverket og kaller enten RedirectPermanent()-metoden eller Redirect()-metoden (dette gjenspeiler nøyaktig hva som ble gjort inne i IController-implementeringen på lavt nivå i eksemplet tidligere i artikkelen).

Bruken av CustomRedirectResult-klassen er illustrert i eksemplet nedenfor, som viser endringene som ble gjort i den avledede kontrolleren:

// ... ved hjelp av ControllersAndActions.Infrastructure; navneområde ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public ActionResult ProduceOutput() ( if (Server.MachineName == "MyMachineName") returnerer nytt CustomRedirectResult ( Url = "/Basic/ Index" ); else ( Response.Write("Kontroller: Avledet, Handlingsmetode: ProduceOutput"); return null; ) ) ) )

Merk at vi ble tvunget til å endre resultatet av handlingsmetoden for å returnere ActionResult. Vi returnerer null hvis vi ikke vil at MVC Framework skal gjøre noe når handlingsmetoden vår blir utført, som er det vi gjorde hvis CustomRedirectResult-forekomsten ikke ble returnert.

Enhetstesting av kontroller og handlinger

Mange deler av MVC Framework er designet for å gjøre enhetstesting enklere, og dette gjelder spesielt for handlinger og kontrollere. Det er flere grunner til denne støtten:

Du kan teste handlinger og kontrollere utenfor webserveren. Kontekstobjekter er tilgjengelige gjennom deres basisklasser (som HttpRequestBase), som er lett å håne.

For å teste resultatene av en handlingsmetode trenger du ikke analysere HTML-koden. For å sikre at du får de forventede resultatene, kan du inspisere det returnerte ActionResult-objektet.

Emulering av klientforespørsler er ikke nødvendig. MVC Frameworks modellbindingssystem lar deg skrive handlingsmetoder som mottar input i sine parametere. For å teste en handlingsmetode kaller du den rett og slett og oppgir de riktige parameterverdiene.

Fremtidige artikler om generering av data fra kontrollere vil vise deg hvordan du lager enhetstester for ulike typer handlingsresultater.

Ikke glem at enhetstesting bare er en del av bildet. Kompleks oppførsel i en applikasjon oppstår når handlingsmetoder kalles sekvensielt. Enhetstesting fungerer best når den kombineres med andre testmetoder.

Nå som du vet hvordan det spesielle resultatet av en omdirigeringshandling fungerer, kan du bytte til det tilsvarende som tilbys av MVC-rammeverket, som er kraftigere og har blitt grundig testet av Microsoft. Den nødvendige endringen til den avledede kontrolleren er gitt nedenfor:

// ... public ActionResult ProduceOutput() ( returner nytt RedirectResult("/Basic/Index"); ) // ...

Den betingede setningen er fjernet fra handlingsmetoden, noe som betyr at etter å ha startet programmet og navigert til en URL som /Derived/ProduceOutput, vil nettleseren bli omdirigert til en URL som /Basic/Index. For å forenkle handlingsmetodekoden inkluderer Controller-klassen bekvemmelighetsmetoder for å generere ulike typer ActionResult-objekter. Så, for eksempel, kan vi oppnå samme effekt som i eksempelet ovenfor ved å returnere resultatet av Redirect()-metoden:

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

Det er ikke noe spesielt komplekst med handlingsresultatsystemet, men det hjelper til syvende og sist med å produsere enklere, renere, mer konsistent kode som er lett å lese og enhetsteste. For eksempel, i tilfelle omdirigering, kan du ganske enkelt sjekke at handlingsmetoden returnerer en RedirectResult-forekomst hvis URL-egenskap inneholder det forventede målet.

MVC-rammeverket definerer mange innebygde handlingsresultattyper, som er beskrevet i tabellen nedenfor:

Innebygde ActionResult-typer Type Beskrivelse Hjelpemetoder for Controller-klassen
Vis Resultat

Gjengir den angitte eller standardvisningsmalen

Utsikt()
Delvis visningsresultat

Gjengir den angitte eller standard delvisningsmalen

PartialView()
RedirectToRouteResult

Problemer HTTP-viderekobling 301 eller 302 til en handlingsmetode eller spesifisert ruteoppføring, genererer en URL i henhold til rutingkonfigurasjonen

RedirectToAction()
RedirectToActionPermanent()
RedirectToRoute()
RedirectToRoutePermanent()
Omdirigeringsresultat

Utsteder en HTTP 301- eller 302-viderekobling til den gitte URL-en

Redirect()
RedirectPermanent()
Innholdsresultat

Returnerer uformaterte tekstdata til nettleseren, og setter i tillegg innholdstypeoverskriften

Innhold()
Filresultat

Overfører binære data (som en fil på disk eller en byte-array i minnet) direkte til nettleseren

Fil()
JsonResult

Serialiserer et .NET-objekt til JSON-format og sender det som svar. Svar av denne typen genereres oftere når du bruker Web API og AJAX-verktøy

Json()
JavaScriptResultat

Sender et fragment kildekode JavaScript som må kjøres av nettleseren

JavaScript()
HttpUautorisert Resultat

Setter HTTP-svarstatuskoden til 401 (som betyr "ikke autorisert"), noe som gjør at autentiseringsmekanismen på plass (skjemaautentisering eller Windows-autentisering) ber den besøkende om å logge på

Nei
HttpNotFoundResult

Returnerer HTTP-feil med kode 404 - Ikke funnet (ikke funnet)

HttpNotFound()
HttpStatusCodeResult

Returnerer den angitte HTTP-koden

Nei
Tomt Resultat

Gjør ingenting

Nei

Alle disse typene stammer fra ActionResult-klassen, og mange av dem har praktiske hjelpemetoder i Controller-klassen. Vi vil demonstrere bruken av denne typen resultater i påfølgende artikler.

Etter å ha mottatt og tolket en forespørselsmelding, svarer en server med en HTTP-svarmelding:

  • En statuslinje
  • Null eller flere overskriftsfelt (Generelt|Respons|Entitet) etterfulgt av CRLF
  • En tom linje (dvs. en linje med ingenting foran CRLF) som indikerer slutten av overskriftsfeltene
  • Eventuelt en meldingstekst
  • De følgende delene forklarer hver for seg enhetene som brukes i en HTTP-svarmelding.

    Meldingsstatuslinje

    En statuslinje består av protokollversjonen etterfulgt av en numerisk statuskode og tilhørende tekstfrase. Elementene er atskilt med mellomrom SP-tegn.

Status-linje = HTTP-versjon SP Status-kode SP Årsak-frase CRLF HTTP-versjon

En server som støtter HTTP versjon 1.1 vil returnere følgende versjonsinformasjon:

HTTP-versjon = HTTP/1.1

Statuskode

Statuskodeelementet er et 3-sifret heltall der det første sifferet i statuskoden definerer responsklassen og de to siste sifrene ikke har noen kategoriseringsrolle. Det er 5 verdier for det første sifferet:

S.N. Kode og beskrivelse
1 1xx: Informasjon

Det betyr at forespørselen ble mottatt og prosessen fortsetter.

2 2xx: Suksess

Det betyr at handlingen ble mottatt, forstått og akseptert.

3 3xx: Omdirigering

Det betyr at ytterligere tiltak må iverksettes for å fullføre forespørselen.

4 4xx: Klientfeil

Det betyr at forespørselen inneholder feil syntaks eller ikke kan oppfylles.

5 5xx: Serverfeil

Det betyr at serveren ikke klarte å oppfylle en tilsynelatende gyldig forespørsel.

HTTP-statuskoder kan utvides og HTTP-applikasjoner er ikke nødvendig for å forstå betydningen av alle registrerte statuskoder. En liste over alle statuskodene er gitt i et eget kapittel for din henvisning.

Svarhodefelt

Vi vil studere General-header og Entity-header i et eget kapittel når vi skal lære HTTP-header-felt. La oss foreløpig sjekke hva svarhodefelter er.

Respons-header-feltene lar serveren sende tilleggsinformasjon om svaret som ikke kan plasseres i statuslinjen. Disse overskriftsfeltene gir informasjon om serveren og om ytterligere tilgang til ressursen identifisert av Request-URI.

  • Proxy-autentiser

  • WWW-Autentiser

Du kan introdusere dine egendefinerte felt i tilfelle du skal skrive din egen tilpassede webklient og server.

Eksempler på svarmelding

La oss nå sette det hele sammen for å danne et HTTP-svar for en forespørsel om å hente hello.htm-siden fra Internett server kjører på stedet

HTTP/1.1 200 OK Dato: Mon, 27 Jul 2009 12:28:53 GMT Server: Apache/2.2.14 (Win32) Sist endret: Wed, 22 Jul 2009 19:15:56 GMT Innhold-lengde: 88 Innhold- Type: text/html Tilkobling: Stengt Hei, verden!

Følgende eksempel viser en HTTP-svarmelding som viser feiltilstand når webserveren ikke kunne finne den forespurte siden:

HTTP/1.1 404 Ikke funnet Dato: Søn, 18. oktober 2012 10:36:20 GMT Server: Apache/2.2.14 (Win32) Innholdslengde: 230 Tilkobling: Lukket innholdstype: tekst/html; charset=iso-8859-1 404 Ikke funnet Ikke funnet

Den forespurte URLen /t.html ble ikke funnet på denne serveren.

Følgende er et eksempel på HTTP-svarmelding som viser feiltilstand når webserveren oppdaget en feil HTTP-versjon i den gitte HTTP-forespørselen:

HTTP/1.1 400 Dårlig forespørsel Dato: Sun, 18 Oct 2012 10:36:20 GMT Server: Apache/2.2.14 (Win32) Content-Length: 230 Content-Type: text/html; charset=iso-8859-1 Tilkobling: Stengt 400 Dårlig forespørsel Dårlig forespørsel

Nettleseren din sendte en forespørsel som denne serveren ikke kunne forstå.

Forespørselslinjen inneholdt ugyldige tegn etter protokollstrengen.